This week's book giveaway is in the OCPJP forum.
We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line!
See this thread for details.
The moose likes I/O and Streams and the fly likes getting console output into a JTextArea Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of OCA/OCP Java SE 7 Programmer I & II Study Guide this week in the OCPJP forum!
JavaRanch » Java Forums » Java » I/O and Streams
Bookmark "getting console output into a JTextArea" Watch "getting console output into a JTextArea" New topic
Author

getting console output into a JTextArea

Ellen Zhao
Ranch Hand

Joined: Sep 17, 2002
Posts: 581
I'm trying to get the console output (logging info) into a JTextArea. Here's my code:


it works with console output, say if I have any statement like "System.out.println("blah blah");", the "blah blah" does appear in the desired place, i.e the JTextArea. But the logging info simply doesn't show up. Then according to logging doc, the ConsoleHandler publishes log records to System.err. then I changed the line

to


the System.out info disappeared from my JTextArea but the log still doesn't show up. I am so frustrated....

Any help will be highly appreciated!


Regards,
Ellen
[ March 06, 2005: Message edited by: Ellen Zhao ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, it looks like you've just fixed several things I was going to note. You say it's working now it you use System.out.println(), but it's not picking up stuff that is logged. I assume your logging is configured to print to the console, right? You've been seeing log messages appear on the console? Then I think the problem may be that

System.setOut(ps);

is executing after the loggers have been configured. That is, the loggers have already saved a reference to the standard System.out stream, from before you set it to this new stream - and they're still writing to that standard System.out, which is not connected to your piped streams. My guess is that you need to create a StreamHandler which writes to the PipedOutputStream (and thus to a TextPane), and configure the logging to write to this new StreamHandler rather than (or in addition to) the ConsoleHandler.

If you have any further troubles getting messages to appear in the text area, you may want to insert some debugging code into the loop that reads the piped input stream:
This can make it easier to tell if your problems are in to code that gets messages into the piped streams, or the code that displays them. It sounds like right now your problems are in the first area, but if you experience any new problems, this println() may be useful. Note that for this, it's helpful if System.out has not been redirected to the piped streams - else you'll get an endless loop. (I suppose you could write to System.err instead to circumvent that.)

Hope that helps...
[ March 06, 2005: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I see your message above has changed yet again since I had last updated my view of the thread. Could you put any future updates in separate messages in this thread? That would make it a lot easier to follow. Thanks.
Ellen Zhao
Ranch Hand

Joined: Sep 17, 2002
Posts: 581
Sorry for having confused you Jim. :embarrassed: Updating my message in one place was just a personal manner for not to scatter my name around, I was nervous about that....Okay if updating message in different posts can make you read more clearly, I'll do it.
Ellen Zhao
Ranch Hand

Joined: Sep 17, 2002
Posts: 581
Thank you very much for your reply, I am reading it closely now....
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Yeah, updating in place like that makes perfect sense if no one's read it yet. Unfortunately you had no way of knowing I was reading it, and getting confused each time it changed.

Of course I myself just edited one of my posts above - but that was just to fix a typo. No significant content changes, I promise.
Ellen Zhao
Ranch Hand

Joined: Sep 17, 2002
Posts: 581
Okay, I tried with both System.setOut(ps) and System.setErr(ps), they both worked well. If I insert debug message somewhere else, they all appeared in the JTextArea like expected. But the log info still hides itself...so this is my last hope:


My guess is that you need to create a StreamHandler which writes to the PipedOutputStream (and thus to a TextPane), and configure the logging to write to this new StreamHandler rather than (or in addition to) the ConsoleHandler.


How? I've never done any IO tweaking like this before...

And, if this doesn't work ( or isn't possible for one to configure the logger to write to any new StreamHandler), I want the JTextArea to read the infomation from the log file and flush the text area reasonably fast (since this log file is always being updated during the execution of this program). How? Thank you very^n ( n ---> infinitely big integer) much!


Best Regards,
Ellen
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
How?

Well, there are a lot of different ways, but the more I think about it the more I like the idea of simply reading the info from the log file. That's probably easiest to understand, as you know the logging to the file is working, right? Try creating a thread which wakes up every n milliseconds (or use a java.util.Timer) and checks the size in bytes of the file. If the size has increased since the last check, read the new bytes in, convert them to a String, and append them to the JTextArea. For efficiency you should only read the new bytes each time, based on the difference between current file size and previous file size. RandomAccessFile or FileChannel will make it easy to skip to the appropriate part of the file. I think you can probably use the same RandomAccessFile for the entire life of the loop. However you may find it's necessary to open a new one on each loop iteration, and close it when the iteration finishes. There may also be some complications if the encoding used in the files requires more than one byte per character, especially if it's UTF-8. Let me know if that's the case.

Good luck...
David Harkness
Ranch Hand

Joined: Aug 07, 2003
Posts: 1646
I haven't used java.util.logging, so I'm going from the JavaDocs. It seems fairly similar to Log4j, so I'm extrapolating from what I know of the latter.

There is a root logger ("") to which your FileHandler is probably attached. You want to add a StreamHandler to it using the same Formatter.That should work with your piped streams, but it seems a waste to have a thread en/decoding Strings and copying bytes around. I'd subclass Handler to append the formatted messages to your JTextArea directly.

You could start with StreamHandler and gut almost all of it as a starting point. Keep publish() and maybe isLoggable() in case you want to be able to detach it from the JTextArea; the rest can go. Then replace StreamHandler in the code above with your TextAreaHandler and swap logArea for ps in the constructor call.

This would allow you to ditch the piped streams and the piping thread.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: getting console output into a JTextArea