Friday, August 24, 2007

Watching Swing Do Its Thing

My father has an old, dense textbook on electricity and magnetism. He once told me with a sense of wonder, "if a person knew everything in this book....." -- with an implicit "s/he would be off the charts".

I feel the same way about this Swing book. It's chock-full of ideas.

Here's one tip to slow down Swing's painting operations so that rendering of a component can be observed. It's a great debugging tool and also somewhat hypnotic.

I'll use a previous Groovy example, but the code translates directly to Java. The key lines are:

// from Swing by Robinson and Vorobiev
// It is vital to disable double buffering
// There are also options involving logging and buffering

RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
table.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);
DebugGraphics.setFlashTime(100);
DebugGraphics.setFlashCount(5);
DebugGraphics.setFlashColor(new Color(0,0,0,0));

In my experience, it is useful to wrap this in a utility class, where one can simply pass a component and let the class use some default values for the flash time and colour. Then, for debugging, this is always at hand. Naturally, don't call this in production code.

Here's the example. This one uses straight-ahead Swing and not the SwingBuilder from Groovy. Also, it doesn't display bogus entries in red (see previous post).

import java.awt.*
import javax.swing.*
import javax.swing.table.*

String envVar = System.getenv(args[0])
final String DELIMITER = ';' // use File path separator

// build data

String[] columns = [ args[0] ]

String[] values = envVar.split( DELIMITER )
Object[][] data = new String[values.length]

for( i in 0..values.length-1 ) {
String[] row = new String[1]
row[0] = values[i]
data[i] = row
}

// build GUI

frame = new JFrame()
frame.setTitle('Env Viewer (by Code to Joy)')
frame.setSize(520,500)
frame.setLayout( new BorderLayout() )

jPanel = new JPanel();
jPanel.setLayout( new BorderLayout() );

JTable table = new JTable(data, columns);
JScrollPane scrollPane = new JScrollPane(table);

jPanel.add(scrollPane, BorderLayout.NORTH);

frame.add( jPanel , BorderLayout.SOUTH );

// from Swing by Robinson and Vorobiev
// It is vital to disable double buffering
// There are also options involving logging and buffering

RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
table.setDebugGraphicsOptions(DebugGraphics.FLASH_OPTION);
DebugGraphics.setFlashTime(100);
DebugGraphics.setFlashCount(5);
DebugGraphics.setFlashColor(new Color(0,0,0,0));

frame.pack()
frame.setVisible(true)


No comments: