How to get COMPONENT (not data) at Index n from JList

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.

Answer

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();
}

Leave a Reply

Your email address will not be published. Required fields are marked *