java console apps made easy - codeproject
TRANSCRIPT
-
7/24/2019 Java Console Apps Made Easy - CodeProject
1/8
Articles Languages Java Beginners
David MacDermot, 10 Feb 2012 CPOL
Java Console apps made easy
This article describes the creation of a Java console type application.
Download demo - 192 KB
Download source - 22.4 KB
Contents
IntroductionHow to use this Java Console
How to wire up a console
Making a custom block caret
Extra! Extra! The menu system.
4.88 (16 votes)
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
2/8
Final comments
History
Introduction
The humble console app: I write them all the time creating one off tests to explore new coding ideas. I'll even string up quick,
menu based, test applications for testing remote device communications and command sets, where the number of commands
can grow during the product development cycle. The advantage of course, is that to grow the application I only have to add a
menu item and an event handler in the code. That is far preferable to squeezing more fields onto an already crowded Windows
Forms application. Sometimes you don't know what you have till it's gone.
I decided to tackle Java this year and get a feel for the language and tools. I usually take on a new (for me) language by
translating an application I have written into the new language and stumbling through the thorny issues as I encounter them. I
was surprised at how many of the things I took for granted in C# turned out to be rather hard to do in Java; case in point, the
console app.
The application I chose to port to Java happened to be a console based menu driven application. Porting the menu code was
fairly straightforward once I figured out how to substitute an interface and nested Java class for a C# delegate in order to obtain
callback behavior. The real headache lay in the performance of the application's menu code in an actual Windows console
instance.
Java applications utilize STDIN, STDOUT, and STDERRstreams but do not own the console instance displaying the streams.Since Java aims at a broad range of Operating Systems, it doesn't include support for clearing the screen. I tried a number of
work-a-rounds to get my application to function as intended without acceptable results.
I was about to give up when I took a different track and considered duplicating console functionality in a Java GUI widget. This
turned out to be more promising. There were quite a few examples of redirecting STDOUTand STDERRto a JtextAreabutI was unable to find one that also successfully copied keyboard input to STDIN. What I did find was quite a bit of chatter fromother developers indicating a desire for such a component.
I began to test the various code solutions and snippets that I had found and settled on one particularly robust example[^]. I
then added some code to pipe keyboard characters to STDIN, added a public clear()method, and some properties tocustomize the look and feel of the console. Finally I figured out how to create a custom blinking block cursor for
JavaConsoleto round things off.
How to use this Java Console
Minimally all that is necessary to use this Java Console in your project is to declare an instance of the JavaConsoleclass.
public static voidmain(String[] args) {
newJavaConsole();
scanner = newScanner(System.in);
System.out.println("Hello World!"); scanner.nextLine();
System.exit(0);}
Here is an example of how to customize the look of the Java Console.
public static voidmain(String[] args){
Scanner scanner = newScanner(System.in);
JavaConsole console = newJavaConsole();
//Customize the console text field
console.setBackground(Color.WHITE); console.setForeground(Color.BLACK);
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
3/8
console.setFont(newFont ("Ariel", Font.BOLD, 12));
//Customize the console frame
console.setTitle("Hello World Program");
Image im = Toolkit.getDefaultToolkit().getImage("../images/MyIcon.png"); console.setIconImage(im);
System.out.println("Hello World!"); scanner.nextLine();
System.exit(0);
}
Here is an example using the JavaConsole.clear()method to clear the screen between chunks of text.
public static voidmain(String[] args){
Scanner scanner = newScanner(System.in); JavaConsole console = newJavaConsole();
System.out.println("It was a dark and stormy night; the rain fell in torrents, except at "+"occasional intervals, when it was checked by a violent gust of wind "+"which swept up the streets (for it is in London that our scene lies), "+"rattling along the house-tops, and fiercely agitating the scanty flame "+"of the lamps that struggled against the darkness. Through one of the "+"obscurest quarters of London, and among haunts little loved by the "+"gentlemen of the police, a man, evidently of the lowest orders, was "+"wending his solitary way.");
scanner.nextLine();
console.clear(); System.out.println(
"He stopped twice or thrice at different shops and houses of a description " +"correspondent with the appearance of the quartier in which they were situated, "+
"and tended inquiry for some article or another which did not seem easily "+"to be met with. All the answers he received were couched in the negative; "+"and as he turned from each door he muttered to himself, in no very elegant "+"phraseology, his disappointment and discontent. At length, at one house, "+"the landlord, a sturdy butcher, after rendering the same reply the inquirer "+"had hitherto received, added, \"But if this vill do as vell, Dummie, it is "+"quite at your sarvice!\"");
scanner.nextLine();
System.exit(0);
}
Finally, here's a comprehensive list of Java Console custom features.
console.getBackground();console.getForeground();console.getFont();
console.setBackground(Color);console.setForeground(Color);console.setFont(Font);
console.setTitle(title);console.setIconImage(Image);
console.clear();
How to wire up a console
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
4/8
The first thing we need to do is to redirect STDOUTand STDERRto our JtextArea. The code class I started with achievedthis in the following manner.
Establish some Piped Input Streams.1.
private finalPipedInputStream pin=new PipedInputStream();private finalPipedInputStream pin2=new PipedInputStream();
Hook the input streams up to the associated output streams.2.
PipedOutputStream pout=new PipedOutputStream(this.pin);PipedOutputStream pout2=new PipedOutputStream(this.pin2);
Redirect System STDOUTand STDERRto these output streams.3.
System.setOut(newPrintStream(pout,true));System.setErr(newPrintStream(pout2,true));
Spin up some threads to read from the Piped Input Streams.4.
//Declarations
privateThread reader;privateThread reader2;
//In the class constructor
reader=new Thread(this);reader.setDaemon(true);reader.start();
reader2=new Thread(this);reader2.setDaemon(true);reader2.start();
Monitor STDOUTand STDERRappending the text to the JtextArea.5.
public synchronized voidrun(){
try {
while(Thread.currentThread()==reader) {
try{ this.wait(100);}catch(InterruptedException ie) {}if(pin.available()!=0)
{Stringinput=this.readLine(pin);
textArea.append(input); textArea.setCaretPosition(textArea.getDocument().getLength());//DWM
02-07-2012 }
if(quit) return; }
while(Thread.currentThread()==reader2) {
try{ this.wait(100);}catch(InterruptedException ie) {}if(pin2.available()!=0)
{Stringinput=this.readLine(pin2);
textArea.append(input); textArea.setCaretPosition(textArea.getDocument().getLength());//DWM
02-07-2012 }if(quit) return;
}} catch(Exception e)
{
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
5/8
textArea.append("\nConsole reports an Internal error."); textArea.append("The error is: "+e); textArea.setCaretPosition(textArea.getDocument().getLength());//DWM 02-07-2012 }}
Now that we have STDOUTand STDERRpiped to the JtextArea, we need to monitor keyboard input to the JtextAreaand copy the characters to STDIN. I modified the original code to do so as follows:
Establish a Piped Output Stream for reading keyboard input.1.
private finalPipedOutputStream pout3=new PipedOutputStream();
Hook the output stream to an associated input stream and redirectSTDINto this input stream.2.
System.setIn(newPipedInputStream(this.pout3));
Add a KeyListenerand copy out keyboard input as it arrives.3.
textArea.addKeyListener(newKeyListener() {
public voidkeyPressed(KeyEvent e) {}
public voidkeyReleased(KeyEvent e) {}
public voidkeyTyped(KeyEvent e) {try{ pout3.write(e.getKeyChar()); } catch(IOException ex) {}
}});
Making a custom block caret
The default caret of the JtextAreais a vertical bar but I wanted a prompt that was a bit more prominent. It turns out that thisfeature is customizable and I found some examples on how to do this. Refer to A custom caret class[^] and Fancier custom
caret class[^] to get an idea of how it's done. Here is the code for my flashing block caret:
public classBlockCaret extendsDefaultCaret {
private static final longserialVersionUID = 1L;
/**
* @brief Class Constructor
*/
publicBlockCaret() {
setBlinkRate(500);// half a second }
/* (non-Javadoc)
* @see javax.swing.text.DefaultCaret#damage(java.awt.Rectangle)
*/
protected synchronized voiddamage(Rectangle r) {if(r == null)
return;
// give values to x,y,width,height (inherited from java.awt.Rectangle)
x = r.x; y = r.y; height = r.height;
// A value for width was probably set by paint(), which we leave alone.
// But the first call to damage() precedes the first call to paint(), so
// in this case we must be prepared to set a valid width, or else
// paint()
// will receive a bogus clip area and caret will not get drawn properly.
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
6/8
if(width
-
7/24/2019 Java Console Apps Made Easy - CodeProject
7/8
private static voidHandleItem2{ Console.WriteLine("You chose item 2.\n"); Console.Read();}
Then I add them to the Menulike so:3.
menu = newMenu();
menu.Add("Item 1", newMenuCallback(HandleItem1));menu.Add("Item 2", newMenuCallback(HandleItem2));menu.Show();
Java does not allow for the passing of function pointers and thus delegates. Instead this behavior is restricted to typed object
pointers and thus the class interface becomes the Java equivalent of the delegate. Here's how it's done in Java.
I declare an interface (a typed object pointer):1.
public interfaceMenuCallback extendsEventListener {public voidInvoke();
}
Next I create some event handlers for menu picks:2.
private static voidHandleItem1 { System.out.println("You chose item 1.\n."); scanner.nextLine();}
private static voidHandleItem2 { System.out.println("You chose item 2.\n."); scanner.nextLine();}
Then I add them to the Menulike so:3.
Menu menu = newMenu(console);menu.add("Item 1", newMenuCallback() { public voidInvoke() { HandleItem1(); } });menu.add("Item 2", newMenuCallback() { public voidInvoke() { HandleItem2(); } });menu.show();
It's a bit more verbose since we are in effect, having to wrap our function pointer in a class.
Final commentsThe menu system does not work well in the standard console when used in a Java application. The version of Menuclassincluded here should only be used in this Java Console. This Java Console may be used anytime you want to have a console
window that is owned by your application. While it features a clear()method for clearing the screen it does not, howeverhandle DOS commands or provide a command prompt.
History
Feb 09, 2012: Version 1.0.0.0.
License
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...
8 25/02/2016 14:24
-
7/24/2019 Java Console Apps Made Easy - CodeProject
8/8
Permalink| Advertise | Privacy| Terms of Use| Mobile
Web04 | 2.8.160217.1 | Last Updated 10 Feb 2012Selecione o idioma
Article Copyright 2012 by David MacDermot
Everything else Copyright CodeProject, 1999-2016
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
Share
About the Author
You may also be interested in...
Lucene.Net ultra fast search for
MVC or WebForms site =>
made easy!
SharePoint Governance: A
definitive Guide
NHibernate Made Simple SAPrefs - Netscape-like
Preferences Dialog
Processes and threads made
easy
Window Tabs (WndTabs) Add-In
for DevStudio
Comments and Discussions
12 messageshave been posted for this article Visit http://www.codeproject.com/Articles/328417/Java-Console-
apps-made-easyto post and view comments on this article, or click hereto get a print view with messages.
No Biography provided
David MacDermotUnited States
Console apps made easy - CodeProject http://www.codeproject.com/Articles/328417/Java-Console-apps-made...