【问题标题】:How to get COMPONENT (not data) at Index n from JList如何从 JList 获取索引 n 处的 COMPONENT(不是数据)
【发布时间】:2012-09-04 20:25:11
【问题描述】:

我通过传递一个数据数组来创建一个 JList

public class MyJList extends JList() {
...

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

我使用 ListCellRenderer 渲染这个列表,它为每个项目提供了一个组件,可以根据业务逻辑启用或禁用。

当我尝试通过键盘箭头导航时出现问题。我希望跳过禁用的项目。 (在适当的方向继续下一个)我必须使用键盘侦听器,因为 UI 会根据列表中选择的项目更改一些内容。麻烦的是,在键盘侦听器中,我无法获得具有所选索引的项目的 COMPONENT。此组件不归 JList 所有,调用 MyJList.getComponent(index) 失败并出现 ArrayIndexOutOfBoundsException。 1 是一个太大的索引,尽管我可以看到七个项目,其中四个是启用的。

如何通过索引从我的 JList 中以编程方式检索组件以确定它是否已启用?似乎返回组件的唯一接口是 getListCellRendererComponent() - 它会更改组件的显示。我只想让组件看看它是否已启用。

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 您可能会发现this 的回答很有用。它通过在ListSelectionModel 中覆盖setSelectionInterval 来满足您的需求。

标签: java swing jlist jcomponent listselectionlistener


【解决方案1】:

JList 不包含任何组件。渲染器返回的组件只是作为一个戳记,并没有真正包含在JList中。

您可以在"Renderers and Editors" section of the Table tutorial 中找到所有这些解释。虽然它是针对表格进行解释的,但它也适用于JLists。

如果你想获取某个索引的“组件”,你只需要使用渲染器并要求它提供一个组件。这方面的一个例子可以在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();
}

【讨论】:

  • true 但无助于希望跳过禁用的项目
  • @kleopatra 但它回答了“我如何以编程方式从我的 JList 中按索引检索组件以确定它是否已启用?”问题的一部分。我不知道如何处理跳过的部分...用你自己替换相关操作或调整选择模型,但似乎都像一个丑陋的黑客
  • 足够公平,可以省略困难的部分 :-) 笑,当然,这困难,selectionModel 路线是可行的,但不是很好。可能需要退后一步来检查列表是否是小部件的正确选择。
  • 答案是你拿不到组件。一旦我明白了这一点,我意识到我实际上并不需要获取组件。与其尝试设置组件的启用成员,我可以简单地维护一个与列表中的每个项目相对应的布尔数组,并使用它来实现“跳过禁用的项目”功能。
猜你喜欢
  • 2021-01-20
  • 1970-01-01
  • 2012-08-09
  • 2015-01-11
  • 1970-01-01
  • 1970-01-01
  • 2017-02-07
  • 2022-06-19
  • 1970-01-01
相关资源
最近更新 更多