Message Console
Posted by Rob Camick on November 8, 2008
There may be times when you want to capture output from your program and display it for the user. This is generally done by creating a console. Using Swing it is not too difficult to create a simple console using a JTextArea or JTextPane. Our message console will be able to display output written to System.out and System.err.
The MessageConsole class will enable you to use a text area or text pane as a simple console. First you must decide which component to use:
- JTextArea – will be more efficient
- JTextPane – will allow you to color the text from each source
Next you must decide how you want the console to function:
- append – messages will be added to the bottom of the console
- insert – messages will be inserted as the first line of the console
Finally, you need to decide if you need to limit the number of lines contained in the console. The MessageConsole will use my LimitLinesDocumentListener described in an earlier blog entry.
So the code for a simple useage of this class might be something like:
somePanel.add( new JScrollPane( textComponent ) );
MessageConsole mc = new MessageConsole(textComponent);
mc.redirectOut();
mc.redirectErr(Color.RED, null);
mc.setMessageLines(100);
One last comment. You can optionally redirect the message to a PrintStream. So if you did something like the following:
mc.redirectOut(null, System.out);
The message would display in your message console as well as the normal output console.

Keith Corlett said
Your blog is just full of useful suprises. Thanks for the fish!
Cheers. Keith.
Rob Camick said
Glad you found the fishing good!
Sven Goetgeluck said
Hi,
thanks for sharing this wonderfull code, but i was wondering if it was possible to embed this in sort of dropdownbox ( saw this on the lotus notes console) were u see 1 line at a time and when opening you spot fe te 10 last lines, did u ever make this?
with regards
Sven
rniamo said
which licence ?
Rob Camick said
No licence. The “About” page mentions this issue.
Kylex said
How do you deal with the synchronization needed?
I didn’t test your solution but as far as I looked into your code, the Document.remove is not in synch with your JTextArea.setCaretPosition, that could cause a problem since Document.getLength() could return a value X and just after that the length of the document is modified by your LimitLineDocumentListener so the actual value would be Y = X – Z . Whereas JTextArea.setCaretPosition(X) is of course not valid anymore.
Did I overlook sth. here or is this a problem of your current solution?
Could ofcourse be easily fixed with a lock on the document which both share.
Beside of that: Looks good & useful!
Philip Gamble said
Very useful thanks for posting this. I found a few other snippits of code online but none that worked as well as yours across multiple classes and it was easy to integrate into my program :)
brunez said
Thanks for this, it works fine.
But, is it possible to print the info in the console while the application is busy?
I’ve written a program that searches files, and I’d like to print the completed percentage while it’s at it, but it only prints the information when it’s done, which is obviously not very useful.
Is there any way to have it print info during the task?
Rob Camick said
You need to execute your long running task on a separate Thread so the GUI remains responsive and can repaint itself.
Thomas said
I’m having some issues with the way I’ve implemented this code.
I added the MessageConsole class to my project and initialized it in the EDT. I have several background tasks which output messages just fine, but if I use System.out within the main thread the text will fail to update in the TextPane. I’m guessing the EDT is blocking it, but I’m not sure how to fix it. Run all messages from the main thread as tasks, even if it’s just to send a message to the TextPane?
Thanks,
Tom
Rob Camick said
I don’t understand why you would have problems using System.out.println() in the main thread. Maybe if you post an SSCCE by using the “Contact Us” page I can see what is happening.
Thomas said
I figured it out. It has to do with the fact that I am using my own spacing (sometimes I would want a \n to separate textual output). Running a method twice that has the following code:
System.out.println(“This will work!”);
System.out.println(“This doesn’t work!” + “\n”);
would print:
This will work!
This doesn’t work!
This will work!
Whereas running a method twice with the order reversed:
System.out.println(“This doesn’t work!” + “\n”);
System.out.println(“This will work!”);
would print:
This doesn’t work!
This will work!
This doesn’t work!
This will work!
So, as in the first example, it seems the \n is holding up the buffer. Nothing that can’t be fixed with a little modification to the MessageConsole code, but it was something I initially overlooked.
Greg M. said
Hi Tom,
I use MessageConsole and have some problem with a MessageConsole and a background task that write on System.out/err : the application block when write some line.
> Nothing that can’t be fixed with a little modification to the MessageConsole code
Perhaps your fix on MessageConsole could help me ?
Rob Camick said
I just fixed a problem that occurred when the message contained a “\n” at the end of the message (as noted by Thomas). In these cases the message was just stored in the buffer and never added to the text pane.
Jeremy said
This is fantastic. The code certainly provided me with the information I need to implement my processing display logic. GUI has never been my strong suite but this code is very clear, well written, and well commented. Thank you for providing this code and explanation!
Rob Camick said
Thanks for the feedback.
teo said
thank you thank you thank you very much!
Rob Camick said
Glad you found a couple of topics that you can use.
Anonymous said
Thanks a lot!!