5

I create a JList by passing it an array of data

public class MyJList extends JList() {
...

   public MyJList(final Object[] listData) {
       super[listData];
   }

I render this list using the ListCellRenderer, which provides me a Component for each item, which can be enabled or disabled according to buisness logic.

The problem comes when I try to navigate by keyboard arrows. I want the disabled items skipped. (go on to the next one in the appropriate direction) I have to use a KeyboardListener, because the UI changes some things depending on which item is selected on the list. Trouble is, in the keyboard listener, I cannot get the COMPONENT of the item with the selected index. This Component is not owned by the JList, and calling MyJList.getComponent(index) fails with an ArrayIndexOutOfBoundsException. 1 is too large an index, even though I can see seven items, four of which are enabled.

How can I programatically retreive a component by index from my JList to determine if it's enabled? The only interface that seems to return a Component is getListCellRendererComponent() - which changes the display of the component. I just want to get the component to see if it's enabled.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Steve Cohen
  • 4,679
  • 9
  • 51
  • 89
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Sep 11 '12 at 22:44
  • 2
    You may find [this](http://stackoverflow.com/a/8344497/1048330) answer useful. It does precisely what you need by overriding `setSelectionInterval` in `ListSelectionModel`. – tenorsax Sep 11 '12 at 23:24

1 Answers1

6

The JList does not contain any components. The component returned by the renderer is only used as a stamp, but not actually contained in the JList.

You can find all this explained in the "Renderers and Editors" section of the Table tutorial. Although it is explained for tables, it applies to JLists as well.

If you want to obtain the "component" for a certain index, you just have to use the renderer and ask it for a component. An example of this can be seen in the source code of the JList#getTooltipText:

public String getToolTipText(MouseEvent event) {
    if(event != null) {
        Point p = event.getPoint();
        int index = locationToIndex(p);
        ListCellRenderer<? super E> r = getCellRenderer();
        Rectangle cellBounds;

        if (index != -1 && r != null && (cellBounds =
                           getCellBounds(index, index)) != null &&
                           cellBounds.contains(p.x, p.y)) {
            ListSelectionModel lsm = getSelectionModel();
            Component rComponent = r.getListCellRendererComponent(
                       this, getModel().getElementAt(index), index,
                       lsm.isSelectedIndex(index),
                       (hasFocus() && (lsm.getLeadSelectionIndex() ==
                                       index)));

            if(rComponent instanceof JComponent) {
                MouseEvent      newEvent;

                p.translate(-cellBounds.x, -cellBounds.y);
                newEvent = new MouseEvent(rComponent, event.getID(),
                                          event.getWhen(),
                                          event.getModifiers(),
                                          p.x, p.y,
                                          event.getXOnScreen(),
                                          event.getYOnScreen(),
                                          event.getClickCount(),
                                          event.isPopupTrigger(),
                                          MouseEvent.NOBUTTON);

                String tip = ((JComponent)rComponent).getToolTipText(
                                          newEvent);

                if (tip != null) {
                    return tip;
                }
            }
        }
    }
    return super.getToolTipText();
}
Robin
  • 36,233
  • 5
  • 47
  • 99
  • true but doesn't help in _want disabled items skipped_ – kleopatra Sep 11 '12 at 21:13
  • 1
    @kleopatra but it answers the "How can I programatically retreive a component by index from my JList to determine if it's enabled?" part of the question. I do not know how to deal with the skipped part ... replace the relevant actions by your own or adjust the selection model come to mind but seems both like an ugly hack – Robin Sep 11 '12 at 21:31
  • fair enough to leave out the hard part :-) Grinning, of course, it _is_ hard, the selectionModel route is workable but not so nice. Probably need a step-back to review if a list is the right choice of widget. – kleopatra Sep 12 '12 at 06:59
  • The answer is that you CAN'T get the component. Once I understood that, I realized that I didn't actually need to get the component. Instead of trying to set the Component's enabled member, I could simply maintain an array of booleans corresponding to each item in the list and use that to implement "disabled items skipped" feature. – Steve Cohen Sep 20 '12 at 19:50