Friday, May 16, 2008

Clear the Screen In Java 5

Ask your friend to write a simple command line utility in java that gives a set of options like ...

1. Press 1 to add element to LinkedList
2. Press 2 to Delete an element in LinkedList
3. Press 3 to traverse the LinkedList
4. Press 4 to exit

Enter Your Choice : _


When user choses one of the above mentioned options ,
First , the screen should be cleared off
Second , the corresponding details (if any) should be asked ( like eneter value to add / delete )
Third , perform the action
Fourth , ReDisplay the above menu

To complete the above program you need to write a method like...


public void clearTheScreen( ) {
....
}


or may be


public boolean clearTheScreen( ) {
....
// return true if screen deleted else false
}


How to complete this method ??

hhhmmmm lets "BRAIN STORM"

"first" reply may be...
Runtime.getRuntime.exec("cls");

No you say ...
System-specific tasks such as these may be performed via Runtime.exec( )
it allows you to perform certain system-specific tasks BUT with very little control.

Actually, this won't work. Yes, the 'cls' command is invoked, *but* it is
invoked in a new process ['command.com' or 'cmd.exe' is exected creating a
new process], and *does not* clear the Java application's console.

If your friend is intelligent may argue ...
But if they can implement "beep", and they do, they should be able to implement "cls" too.
But you are MORE intelligent , you say
That's because BELL is a standard ASCII character (code 7) and it's
pretty much standard that any terminal/console would render it by beeping.


The "second" reply may be
System.out.print("\n\n\n\n\n\n\n\n\n\n\n\n");

and you say ... its obviously incorrect ( BTW your friend is stupid if he mentions this option ) ,
as it scrolls the menu above so that its not visible to user NOT clean the screen.


"third" reply may be
I heard about this method:
System.out.print((char)27 + "[2J");

Dont get scared probably your friend probably was good DOS progarmmr at some time as + "[2J" is the ANSI escape sequence for clearing the screen.
However, it doen't work unless "ansi.sys" is loaded and very few WinXP user's have this.

If your friend is a Windows geek he may say

Yes, we can add the following command in the c:\windows\system32\config.nt.
device=c:\windows\system32\ansi.sys
This will load the ansi.sys

But that wont work buddy ... you may try it yourself .. and besides
Thats Platform dependent !! and Java is platform independent right ?
so take a "Chill Pill dude"

"fourth" may be ( if your friends guesses this .. he is really good with java / linux )
Printing out the form-feed character will clear the screen
System.out.print("\f");
It works but only on linux , not on windows ... But java code should be platform independent

Your friend : " So WHAT SHOULD I DO ??? "
You ( with a smile ) : Write Java Native Interface [JNI] routines which tap into the relevant operating system functionality
Your Friend : " ?? WHY ?? "
You : Unfortunately these tasks are inherently operating system-specific, and cannot be implemented in any standard way across platforms. Some platforms, in fact, don't even understand the concepts of 'screen', or 'cursor', so wouldn't even have any use for classes that implemented these abstractions. Even the 'standard' C and C++ languages which, like Java, aim for platform independance, do not implement such functionality.

Most intelligent of your friend may say ...
( you know the Phd types )

Maybe a nested class could be added to 'System', containing all the
system-specific console-management routines, something like:

class System
{
...
public class Console
{
...
public static native void cls();
public static native void setCurPos(int row, int col);
public static native String inputString();
public static native double inputNumeric();
...
}
...
}

You could then do something like:

System.Console.cls();


and YOU calmly reply ...
Amego !! It would defeat the purpose of platform-independance, since not all
platforms have the concept of a "console".


Real solution ??
Write JNI ( platform dependent way ) OR
Look at jcurses on sourceforge. ( but using this is an overkill )
http://sourceforge.net/projects/javacurses/

NeXt ... ask your friend .. to write a code to Accept input [say a single keystroke] without pressing ENTER and let me know how it goes ;o)

Contradiction
Contradicting my self ... Recently discovered that with Java 6 , Its very much possible ...
In Java 6 a better way of interacting with the command prompt was introduced, the java.io.Console class.
Together with the utility class java.util.Scanner introduced in Java 5 this new API can be used to develop more advanced Java console applications.

For more detaisl checkout
http://java.dzone.com/news/console-applications-java-6
http://java.sun.com/javase/6/docs/api/java/io/Console.html

8 comments:

Lavnish said...

For really INQUISITIVE friends came accross this code

// File Test.java
import java.awt.*;
import java.awt.event.*;

public class Test extends Frame implements WindowListener {

private final TextArea TA = new TextArea
("", 25, 80, TextArea.SCROLLBARS_NONE);
private final String NEWLINE = "" + '\n';

public Test() {
TA.setEditable(false);
add(TA);
setTitle("Test Application");
setResizable(false);
addWindowListener(this);
pack();
setVisible(true);
// The last methods were inherited
// because we extend java.awt.Frame
}

public void print(String s) {
TA.append(s);
}

public void println(String s) {
TA.append(s);
TA.append(NEWLINE);
}

public void cls() {
TA.setText("");
}

public void kill() {
dispose();
}


// We must implement the following as we are
// implementing WindowListener

public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}

public void windowActivated(WindowEvent e) {}

public void windowClosed(WindowEvent e) {
System.exit(0);
}

public void windowClosing(WindowEvent e) {
dispose();
}


public static void main(String[] args) {
Test t = new Test();
t.println("Hello World!");
t.print("Same line ");
t.println("Test");
try {
Thread.sleep(5000); // Wait 5 seconds
} catch (InterruptedException e) {
// Do nothing, not critical to
// be interrupted
}
t.cls();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Do nothing, not critical to
// be interrupted
}
t.kill();
}
}

Lavnish said...

With Java 6 .. Its very much possible ...
http://java.dzone.com/news/console-applications-java-6

shib_best said...

nice collection but use some advance technoology

Advanced Java said...

use some advanced technology in java

Tamir said...

I didn't understand a thing. I only wanted to clear the screen and came with nothing usefull, although the way you presented the arguments was intersting and funny.

Lavnish said...

in summary ... If u r using jaav6 use http://java.dzone.com/news/console-applications-java-6 ... If Java 5 cannot be implemented in any standard way across platforms.

Davii said...

I think I understood everything you've said, and I read the DZone page and the io.Console page, but like Tamir, I still don't see how to clear the screen... what am I missing?

Lavnish said...

hi daavi
its been quite some time , i havent worked on java for 2 years now ... wrote this article quite some time back .. to ans ur ques
if u r using Java 5 ... there is no std way how to clear will depend on ur scenario ... if java 6 then there is a std way which i never tried myself