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

66
|
Chapter 2, Lists and Combos
#15 Make JLists Checkable
HACK
The general idea of this pop up can be modified to work in similar ways for
different kinds of searches, such as popping up a list of which field the
search is to be applied to if the list items are complex. An example of this is
a mail program in which the pop up might show the options Subject, To,
From, etc., meaning that the search is limited to finding the specified term in
only the selected field.
H A C K
#15
Make JLists Checkable Hack #15
Avoid losing 50 selections to an unshifted click.
One horrible UI problem is dealing with vast collections of things that need
to be presented to the user and made selectable. If, like me, you’ve ever had
1,000 emails in your inbox, you know what I mean. Worse, what if you pick
a bunch of items to delete, but your finger slips off the key used for multi-
selection (Alt on Windows, Command on the Mac, etc.) and you lose all of
your previous selections? Overriding the native selection behavior can make
this situation somewhat more palatable.
Because a list like this behaves differently than a normal list, it should look
different, too, so I’ve opted for a checkbox metaphor. Each item is shown
with a checkbox, and as you click more items, they get checked, and if you
select an already-checked item, it gets unchecked.
This turns out to be a little harder than expected. I once did
it without
JList, creating my own scrolling layout of JPanels
and faking the list behavior. It turned up a funny Swing bug
because I was using
GridBagLayout for the fake list, and it
started totally bombing out after about 500 items were
added to the list. This was because
GridBagLayout has a bug
where it can’t have more than 512 rows. Considering the bug
(number 4254022 on the Java Bug Parade) was filed in 1999
and is still open, I’m figuring it won’t get fixed by the time
you read this.
The basis of the checkable list is a JList. The tricky part here is that there
isn’t a way (that I’ve found) to steal the mouse clicks from the
JList and
consume them before the normal calls to the
ListSelectionModel are made.
Instead, the strategy is to set up a
ListSelectionListener and just fix every-
thing after
JList has done its thing.
To implement the checkbox functionality, subclass
JList and give it a cus-
tom
ListSelectionListener and a ListCellRenderer. A complete listing is
shown in Example 2-6.
Make JLists Checkable #15
Chapter 2, Lists and Combos
|
67
HACK
There are two important sections to consider. The first is the valueChanged( )
method that implements ListSelectionListener. The following list describes
what happens in that method.
Example 2-6. A checkbox-metaphor JList
public class CheckBoxJList extends JList
implements ListSelectionListener {
static Color listForeground, listBackground;
static {
UIDefaults uid = UIManager.getLookAndFeel().getDefaults( );
listForeground = uid.getColor ("List.foreground");
listBackground = uid.getColor ("List.background");
}
HashSet selectionCache = new HashSet( );
int toggleIndex = -1;
boolean toggleWasSelected;
public CheckBoxJList( ) {
super( );
setCellRenderer (new CheckBoxListCellRenderer( ));
addListSelectionListener (this);
}
// valueChanged( ) listing below
public static void main (String[] args) {
JList list = new CheckBoxJList ( );
DefaultListModel defModel = new DefaultListModel( );
list.setModel (defModel);
String[] listItems = {
"Chris", "Joshua", "Daniel", "Michael",
"Don", "Kimi", "Kelly", "Keagan"
};
Iterator it = Arrays.asList(listItems).iterator( );
while (it.hasNext( ))
defModel.addElement (it.next( ));
// show list
JScrollPane scroller =
new JScrollPane (list,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JFrame frame = new JFrame ("Checkbox JList");
frame.getContentPane( ).add (scroller);
frame.pack( );
frame.setVisible(true);
}
}

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