redirect System.out to JTextArea

E

Erik

The following code is meant to redirect text from System.out to a
JTextArea. However, it does not make each output visible immediately:
it sort of buffers. How can I change it, so it shows eacht line
immediately after an "System.out.println(...); ?

======================================
private void updateTextArea(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text); // it will append, but not show
immediately ...
}
});
}

private void redirectSystemStreams() {
OutputStream out = new OutputStream() {
@Override
public void write(int b) throws IOException {
updateTextArea(String.valueOf((char) b));
}

@Override
public void write(byte[] b, int off, int len) throws IOException
{
updateTextArea(new String(b, off, len));
}

@Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
};

System.setOut(new PrintStream(out, true));
System.setErr(new PrintStream(out, true));
}
 
M

Mayeul

Erik said:
======================================
private void updateTextArea(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text); // it will append, but not show
immediately ...
}
});
}

You might want to replace invokeLater() with invokeAndWait().

I usually think this use case does not look immediate with
invokeLater(), but does with invokeAndWait().
 
E

Erik

You might want to replace invokeLater() with invokeAndWait().

I usually think this use case does not look immediate with
invokeLater(), but does with invokeAndWait().


I get:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call
invokeAndWait from the event dispatcher thread
at java.awt.EventQueue.invokeAndWait(EventQueue.java:980)
 
J

John B. Matthews

Erik said:
The following code is meant to redirect text from System.out to a
JTextArea. However, it does not make each output visible immediately:
it sort of buffers. How can I change it, so it shows eacht line
immediately after an "System.out.println(...); ?

private void updateTextArea(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
textArea.append(text); // it will append, but not show immediately ...
}
});
}

Why? The append() method is thread safe.

<http://java.sun.com/javase/6/docs/api/javax/swing/JTextArea.html#append(java.lang.String)>
 
K

Knute Johnson


The behavior of the caret changes depending on whether the append()
method is called on the EDT or not (as of 1.5 that is easily changed
however). Also, you might want to do it for visibility or
synchronization purposes. If you want to put the JTextArea in a
JScrollPane and scroll to the caret, that will need to be done on the
EDT as well.

I think the OPs problem lies in the code we don't see however.
 
L

Lew

Peter said:
Now, all that said, I think none of this has answered your original
question, which is why the text does not appear immediately.  Without a
SSCCE it's impossible to say for sure what might be the cause of that.
But keep in mind that repainting of Swing components (or AWT for that
matter) does not necessarily happen immediately.  The system tracks what
components need redrawing (it's "invalidated"), and then at some
indeterminate time shortly after the invalidation happens, it's actually
redrawn.

Or the problem is not a Swing or EDT issue and has to do with
PrintStream being buffered and not flushed.
 
M

Mike Schilling

Peter said:
Wouldn't be the first time someone posted code in which they made an
incorrect assertion about what the code does. :)

At leasst half the point of posting code is to show it to people
making different assumptions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top