From: Erik on 21 Jan 2010 06:21 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)); }
From: Mayeul on 21 Jan 2010 08:16 Erik wrote: > ====================================== > 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(). -- Mayeul
From: Erik on 21 Jan 2010 09:01 On Thu, 21 Jan 2010 14:16:02 +0100, Mayeul <mayeul.marguet(a)free.fr> wrote: >Erik wrote: >> ====================================== >> 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(). 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)
From: John B. Matthews on 21 Jan 2010 10:04 In article <51egl512ho3p9te0158rpr9tcuhqonl4j0(a)4ax.com>, Erik <et57(a)hotmail.com> wrote: > 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)> -- John B. Matthews trashgod at gmail dot com <http://sites.google.com/site/drjohnbmatthews>
From: Peter Duniho on 21 Jan 2010 12:37 Erik wrote: > On Thu, 21 Jan 2010 14:16:02 +0100, Mayeul <mayeul.marguet(a)free.fr> > wrote: > >> [...] >> 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) As John says, since the JTextArea.append() method is thread-safe, why bother with the "invoke" method at all? But on top of that, if your code is already executing on the EDT, why are you using either method? I find it interesting that the exception is thrown. The .NET equivalents (there are several, depending on what GUI framework one is using) for "invokeAndWait()" will go ahead and complete the dispatch directly if the synchronous call is being done on the target thread, rather than trying to queue the call and then wait for it to complete (which would of course deadlock in that situation). But regardless, the Java approach is also a valid design decision, and it is highlighting the fact that there's something odd about your own program's implementation. 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. Normally, this happens very quickly. Fast enough one wouldn't notice. But if your program is doing a lot of other stuff, especially on the EDT, the redrawing may not occur until some time well in the future (hundreds of milliseconds, or even thousands if you are actively blocking the EDT with long-running operations). In fact, if there is some kind of contention going on in the EDT, using "invokeLater()" will only exacerbate the problem, because it adds an extra trip through the EDT for the update to the control. So, the first step here should be for you to figure out what else is going on in the EDT that is taking so much time and preventing it from handling the redrawing of your component. No one here can explain it if you don't post a SSCCE. You'll either have to post one, or figure it out yourself. Pete
|
Next
|
Last
Pages: 1 2 Prev: Speeding up reading from files Next: Request Help - Strange Struts - JSP exception |