478
|
Chapter 12, Miscellany
#95 Debug Your GUI
HACK
Notice the odd for loop—you start at the second-to-last element and decre-
ment by two each time. On each pass, you take the first object of the pair; if
it’s the right class to fire the event to, you get the second object of the pair
and call its event-handling method. Presumably, you could use this to mix
up different kinds of listeners in the same list, calling different methods for
different classes.
When run, this test produces the following output. Since the event firing
counts down through the listeners, it’s functionally the same as the simpler
backward
for
loop shown earlier:
[tonberry] cadamson% java EventListenerListEventSource
E called
D called
C called
B called
A called
H A C K
#95
Debug Your GUI Hack #95
Standard out and err aren’t just for log files anymore.
Debugging GUIs often means keeping one or two console windows open, so
you can see the debugging messages you print to standard out (via
System.
out.println( )
and the like), as well as stack traces printed to standard err
when exceptions are caught. In the field, you might want to log these to a
file with something like
java.util.logging, but at design time, or when
investigating a bug, you want to see exactly when the exceptions happen,
and running
tail -f mylog.txt in multiple terminal windows may not be
practical, especially if you’re trying to get a customer on the phone to do it.
An alternative is for your own application to have debugging windows that
collect everything printed to standard out and err, something that you or a
user can bring up with a keypress or menu item.
Hijacking Output Streams
Fortunately, taking control of the standard output and error streams is
pretty easy. The trick is to repoint it into your own
JTextAreas, as shown in
Example 12-16.
Example 12-16. Redirecting System.out and System.err to Swing windows
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
Debug Your GUI #95
Chapter 12, Miscellany
|
479
HACK
public class StdErrOutWindows extends Object {
JTextArea outArea, errArea;
public StdErrOutWindows ( ) {
// out
outArea = new JTextArea (20, 50);
JScrollPane pain =
new JScrollPane (outArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
JFrame outFrame = new JFrame ("out");
outFrame.getContentPane( ).add (pain);
outFrame.pack( );
outFrame.setVisible(true);
// err
errArea = new JTextArea (20, 50);
pain =
new JScrollPane (errArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
JFrame errFrame = new JFrame ("err");
errFrame.getContentPane( ).add (pain);
errFrame.pack( );
errFrame.setLocation (errFrame.getLocation( ).x + 20,
errFrame.getLocation( ).y + 20);
errFrame.setVisible (true);
// set up streams
System.setOut (new PrintStream (new JTextAreaOutputStream (outArea)));
System.setErr (new PrintStream (new JTextAreaOutputStream (errArea)));
}
public static void main (String[] args) {
new StdErrOutWindows( );
// test
System.out.println ("test to out");
System.out.println ("another test to out");
try {
throw new Exception ("Test exception");
} catch (Exception e) {
e.printStackTrace( );
}
}
public class JTextAreaOutputStream extends OutputStream {
JTextArea ta;
public JTextAreaOutputStream (JTextArea t) {
super( );
ta = t;
}
Example 12-16. Redirecting System.out and System.err to Swing windows (continued)

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.