【问题标题】:Removing element from JList is not working从 JList 中删除元素不起作用
【发布时间】:2012-05-10 14:01:48
【问题描述】:

我有一个列出 arrayList 的 JList。当我按下名为 delete 的按钮时,我想从列表中删除选定的元素(最好是数组列表)。目前我有以下代码,但是它不起作用。我的意思是,如果选择了一个元素,它似乎什么都不做,当什么都没有选择时,它会给我一个 ArrayIndexOutOfBoundsException。

private JList listOrders = new JList(arrayList.toArray());

public void myList() {
    listOrders.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION );
    panelForLists.add(listOrders);
}

public void updateList() {
    listOrders.setListData(arrayList.toArray());
    listOrders.revalidate();
    listOrders.repaint();
}

public void actionPerformed(ActionEvent event) {
    if (event.getSource() == deleteItem) {
         int index = listOrders.getSelectedIndex();
            listOrders.remove(index);
           updateList();
    }
}

我认为这可能是因为我必须在某个地方添加 ListSelectionListener,但我不知道如何才能做到这一点。我在互联网上搜索了很长时间的答案,这就是我从 JList oracle 演示中得出的。

非常感谢!

【问题讨论】:

  • 您必须在删除 JList 元素的其余代码之前测试 if(listOrders.getSelectedIndex() > -1)
  • 这可能(几乎肯定)是非常糟糕的做法,但我设法解决了我的问题:我没有使用listOrders.remove(index);,而是使用arrayList.remove(index); 使用更新方法然后刷新列表它在一种方法中有效地从列表和数组列表中删除了项目。

标签: java swing arraylist jlist


【解决方案1】:

您需要使用ListModel 来删除选定的元素。

int index = listOrders.getSelectedIndex();
ListModel model = listOrders.getModel();

JList 在调用setListData 时使用 javax.swing.AbstractListModel 构建模型。

您需要实现自己的 ListModel 扩展 javax.swing.AbstractListModel 用于 put CRUD 方法。

【讨论】:

    【解决方案2】:

    这基本上是 Hovercraft Full Of Eels 已经回答的问题,但有更多代码指针。

    1. 您确实删除并重新添加了元素,这当然没有效果。最简单的方法是您的ArrayList 可以直接用作ListModel,但这是不可能的(因为ArrayList 不会触发任何事件)。您可能想改用JList( Vector ) 构造函数,但该构造函数不允许之后修改向量。因此,您只能创建自己的ListModelDefaultListModel 类可能正是您正在寻找的。​​li>
    2. actionPerformed 方法中的代码始终假定选择了一个元素。请注意,当未选择任何内容时,getSelectedIndex 方法返回 -1。您可以(对用户)做的最好的事情是在未选择任何内容或选择多个元素时禁用删除按钮。这可以通过让按钮后面的操作监听列表的选择模型来实现,并根据选择更新其启用状态(如果需要,不要忘记触发PropertyChangeEvent)。如果您不使用 Action 备份按钮,只需根据选择直接切换按钮的启用状态即可。

    【讨论】:

    • 感谢您的回答,它帮助我了解了 ArrayLists 如何与 JLists 一起工作!
    【解决方案3】:

    您可以创建一个正确更新它的模型

    class ArrayListModel<T> extends AbstractListModel{
    
        private final List<T> arr = new ArrayList<T>();
        public int getSize(){
            return arr.size();
        }
    
        public T getElementAt(int ind){
            return arr.get(ind);
        }
    
        public void remove(int ind){
            arr.remove();
            fireIntevalRemoved(this,ind,ind);
        }
    
    
        public void add(T obj){
            arr.add(obj);
            fireIntevalAdded(this,arr.size(),arr.size());
        }
    
        public void setData(List<T> list){
            int size=arr.size();
            arr.clear();
            arr.addAll(list);
            fireIntevalChanged(this,0,arr.size()>size?arr.size():size);
        }
    
    }
    

    并用 setModel 设置列表的模型

    【讨论】:

    • 这个ArrayListModel类的附加值是什么?您仍然不能直接使用ArrayList,需要对ListModel 进行所有修改。那么为什么不坚持DefaultListModel。一个附加值是切换到Collection,它实际上会在添加/删除元素时触发事件/...并使用该Collection 实例直接支持ListModel,允许对@ 进行更改987654329@ 或ListModel
    • @Robin 是的,这是一个你可以选择的选项,但这样做更容易,如果你通常不需要 List 接口来处理类似的东西
    【解决方案4】:

    当您调用 updateList() 并且此方法在 JList 上调用 setListData(...) 时,您似乎正在从列表中删除该项目,然后将其重新添加回来。我认为你应该摆脱这种方法。 ListModel 应该保存数据,更改数据后无需在 JList 上调用 revalidate()repaint()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多