Groovy SwingBuilder and Secret Methods
Last night, I mocked up a little Groovy example that split an environment variable (e.g. PATH) and displayed each entry. This is a modest experiment to mitigate Microsoft's dreaded, 1970-vintage line editor for modifying environment variables. (I had done something similar in Python years ago, and the topic has come up recently. More on this to come).
I used straight-ahead, quick-n-dirty Swing, and then decided to reduce the code by using a SwingBuilder.
As usual, most of it went fine, except when it came to simply performing something like this:
jPanel.add( scrollPane );
On a couple of projects now, I have spent considerable energy trying to figure out how to do this.
The answer may be in the GINA book but on the web, the only morsel of help that I could find is an article from 2004. (thank you!)
The answer is the secret
widget
method! See the code listing below for an example on how to use it.As an aside, I find it useful to display non-existent PATH entries in red (see screenshot).
import java.awt.*
import javax.swing.*
import javax.swing.table.*
import groovy.swing.SwingBuilder
class MyTableCellRenderer extends JLabel
implements TableCellRenderer {
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int rowIndex, int vColIndex) {
setText(value.toString())
File file = new File(value)
if( !file.exists() ) { setForeground(Color.red) }
return this
}
}
///////////////////////////////////////////////////////////////
// static public void main(String[] args)
//
// args[0] = env var to view
final String DELIMITER = ';' // change this for Unix
String envVar = System.getenv(args[0])
// 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. Note that this is quick-n-dirty stuff,
// that illustrates a SwingBuilder more than proper
// Swing techniques.
builder = new SwingBuilder()
JTable table = new JTable(data, columns)
def renderer = new MyTableCellRenderer()
table.columnModel.getColumn(0).setCellRenderer(renderer)
JScrollPane scrollPane = new JScrollPane(table)
gui = builder.frame( title:'Code to Joy',
size:[520,500] ) {
panel( layout: new BorderLayout(),
constraints: BorderLayout.NORTH ) {
widget(scrollPane) // THIS is a revelation
}
}
gui.show()
5 comments:
Sweet. But maybe you could use the File.pathSeparator instead of ";". Then no change for a different OS.
why wouldn't the follwing work for you?
gui = builder.frame( ... ) {
scrollPane {
widget( table )
}
}
you could also use SwingBuilder's jtable support for models and columns, check GINA page 263 ;-)
re: rhyolight.
Thanks: you are absolutely right. Excellent point.
re: Andres.
Indeed, it works for me. I was just so happy to discover "widget" that I posted as soon as it worked.
I don't own GINA but it is on my list. Duly-noted. Thanks
M.
It's also listed on the Groovy Wiki...
http://groovy.codehaus.org/Alphabetical+Widgets+List
It gets monotonous reading the obvious entries, so I can see why it is missed.
Also entertatining are
- map(...) which returns a java.util.Map of the attributes
- container(...) {...} which will be a container variant of widget(...), right now it's exactly the same.
- actions() {...} which returns a list of the declared items, intended to be used to declare actions in context of a given swing builder and attaching it's id: attribute, used in GroovyConsole.
Great! you'll find more info on programming UIs with Groovy at http://groovy.codehaus.org/GUI+Programming+with+Groovy
like the brand new SwingXBuilder (swingx from http://swinglabs.com) and JideBuilder for the JIDE JCL.
Keep on Groovying!
Post a Comment