70
|
Chapter 2, Lists and Combos
#16 Make Different List Items Look Different
HACK
When you click on items in the list, their selection state is shown with
checkboxes, as seen in Figure 2-6.
Notice how the checkboxes are all you need to see what’s selected. In an
early version of this hack, I went out of my way to maintain the usual selec-
tion colors and it looked lousy, probably because there were two competing
metaphors to show the selection: the highlight and the checkbox. Since this
hack totally changes how the JList works, it’s appropriate to radically
change its appearance, too.
H A C K
#16
Make Different List Items Look Different Hack #16
An in-progress download shouldn’t look like a completed one.
What made me love lists again were the OmniWeb browser and (later)
Safari—particularly, their download managers. By way of negative example,
take the download manager for Internet Explorer 5 for Mac...please. This
GUI was a table of filenames, URLs, sizes, etc., with columns not even intel-
ligently resized for their widths. OmniWeb, on the other hand, showed a
running download with a progress bar, and a finished download with the
defaultComp.getListCellRendererComponent (list, value, index,
isSelected, cellHasFocus);
checkbox.setSelected (isSelected);
Component[] comps = getComponents( );
for (int i=0; i<comps.length; i++) {
comps[i].setForeground (listForeground);
comps[i].setBackground (listBackground);
}
return this;
}
}
Figure 2-6. Using the checkbox-metaphor JList
Example 2-8. ListCellRenderer for checkbox-based JList (continued)
Make Different List Items Look Different #16
Chapter 2, Lists and Combos
|
71
HACK
file location and file size. Safari goes a step further with context-appropriate
buttons: an X to cancel an in-progress download, a magnifying glass to
locate an already-downloaded file, etc. But it’s the same idea: different things
shouldn’t look the same.
To do this in Swing, you need a hack that goes against everything in all the
other Swing books: you need to stop subclassing
JComponent
when you write
a
ListCellRenderer. Instead, delegate the getListCellRendererComponent( )
call to one of several components, choosing whichever best represents the
item to be rendered.
In fact, the whole tradition of subclassing
JComponent for ListCellRenderers
is a pretty hateful practice because they’re not really used as
Components any-
way! They’re certainly not added to the
JList. Instead, a list cell is rendered
off screen and those pixels are blitted to the
JList. So, provided that what
you return in
getListCellRendererComponent is what you want the cell to
look like, it really doesn’t matter how you get there.
By way of demonstration, this hack shows the items in a given directory
with different layouts, depending on the file type. All of the cells use an icon
on the left, with a name in bold at the top of a two-line layout. However, if
the item is a folder, the bottom line contains a count of the children in that
folder. If the item is a text file—it ends with one of the various extensions
associated with text files (e.g., .txt, .html, .java)—then there’s a different lay-
out that uses two cells on the second line to show file size and word count.
And if the item is determined to be an image file, then a layout with room
for a little two-row image icon on the right is used.
So, there are four different prototypes, and
getListCellRendererComponent( )
needs to choose one, set its fields and highlight colors, and return it.
Example 2-9 is quite long, in part because of the icky
GridBagLayout work
required to make the four prototypes look interesting. This is one time when
I really wish I had a visual Swing GUI builder.
Example 2-9. A JList with multiple cell-rendering layouts
public class PolymorphicJList extends JList {
static Color listForeground, listBackground,
listSelectionForeground, listSelectionBackground;
static {
UIDefaults uid = UIManager.getLookAndFeel().getDefaults( );
listForeground = uid.getColor ("List.foreground");
listBackground = uid.getColor ("List.background");
listSelectionForeground = uid.getColor ("List.selectionForeground");
listSelectionBackground = uid.getColor ("List.selectionBackground");
}

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.