O'Reilly logo

Swing Hacks by Chris Adamson, Joshua Marinacci

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

94
|
Chapter 2, Lists and Combos
#19 Turn Methods into List Renderers
HACK
The previous code replaces the label.setText( ) method in the original ren-
derer. It retrieves the specified method from the current list value and stores
it in a
Method
object. This object represents the abstract method itself. If you
did
new String("text").getClass( ).getMethod("toString",null)
, then you
would get an object that represents the
toString( )
method on any string.
Once you have this method, you can call it on the actual object at hand.
meth.invoke( ) will invoke the method on the real list item, returning a value
into
retval. Both getMethod( ) and invoke( ) take an additional argument,
which is
null in the previous code. This argument is actually an array repre-
senting the arguments to the method being called. For this hack to work,
you must assume that the method has no arguments, so
null is used.
Once you have the return value of the method in hand, you can call
setText( ). I set it to ""+retval because that will automatically handle nulls
and call
toString( ) on the value itself. The reflection code can throw an
exception, so it’s all wrapped up on a
try-catch block. If the reflection fails,
then it will set the text using
toString( ) on the list item as a backup, which
is what the standard renderer would do.
Putting It All Together
To use this new renderer, you need to create a JList and set its CellRenderer
property. The following code creates a frame with one JList in it, creates a
custom renderer for the
toString( ) method, then packs and shows the
frame on screen. The list contains an array of strings, representing common
subatomic particles:
public static void main(String[] args) {
String[] data = { "Proton", "Neutron", "Electron" };
JList list = new JList(data);
GenericListCellRenderer renderer =
new GenericListCellRenderer("toString");
list.setCellRenderer(renderer);
JFrame frame = new JFrame("Cell Renderer Hack");
frame.getContentPane( ).add(list);
frame.pack( );
frame.setVisible(true);
}
The generic renderer can call any method on the list item objects as long as
the method has no arguments and doesn’t return void. It will even work
with primitives. You could call
hashCode( ), which returns an int, like this:
GenericListCellRenderer renderer =
new GenericListCellRenderer("hashCode");

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required