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