如何流畅地重新排列JList?“最佳”方法是什么?

4

我正在制作一个基于swing的应用程序,在其中有一个JList,它会定期更新相同数据的不同排序方式,并且偶尔更新新项目,以及较少的项目。我正在尝试找出使其看起来最好的方法。目前,我只是调用:

JList.setListData(String [] data);

这样做看起来不太好,而且会清除选定的项目。

我希望有一种更新的方法,只有在从列表中删除选定项目时才清除它们,否则保持相同的选定项目,即使它们的索引发生了变化。我考虑过跟踪哪些索引被选中,然后在更改数据后设置选定项目,但那听起来很糟糕。我还看了看ListModels并跟踪我的自己,但似乎选定哪些项目是在JList本身中保留的,所以这也无法完美解决问题。

非常感谢任何建议。


setListData() 的实现是否相关?sscce(例如这个)可能会有所帮助。 - trashgod
使用JXList(Swingx的一部分)来支持UI级别的排序/过滤。请注意,在批量修改通知期间,所有模型装饰解决方案都无效(通常我们可以通过更常见的单项更改粒度来摆脱这种情况 :-))。 - kleopatra
2个回答

4

我为您制作了一个可工作的示例。

如您所请求,我使用了JList,并添加了重新排序、添加和删除列表中项目的按钮。

希望这有所帮助!

谢谢。

public class Test {

    private static String selectedValue = null;
    private static JList jList = new JList();

    public static void main(String args[]) {
        JFrame jFrame = new JFrame();
        jFrame.setSize(500, 500);
        jFrame.setLocationRelativeTo(null);
        jFrame.setLayout(new GridLayout(4, 1));

        jList = new JList(new String[]{"1", "2", "3", "4", "5"});
        jFrame.add(jList);

        JButton rearrangeButton = new JButton("rearrange");
        rearrangeButton.addActionListener(new Test().new SelectedListener());
        jFrame.add(rearrangeButton);

        JButton addButton = new JButton("add");
        addButton.addActionListener(new Test().new SelectedListener());
        jFrame.add(addButton);

        JButton deleteButton = new JButton("delete");
        deleteButton.addActionListener(new Test().new SelectedListener());
        jFrame.add(deleteButton);

        jFrame.setVisible(true);
    }

    private class SelectedListener implements ActionListener {

        public void actionPerformed(ActionEvent actionEvent) {
            storeSelected();

            if (actionEvent.getActionCommand().equalsIgnoreCase("rearrange")) {
                jList.setListData(new String[]{"5", "4", "3", "2", "1"});
            } else if (actionEvent.getActionCommand().equalsIgnoreCase("add")) {
                List< String> items = new ArrayList< String>();

                for (int item = 0; item < jList.getModel().getSize(); item++) {
                    items.add(jList.getModel().getElementAt(item).toString());
                }

                items.add("new");

                jList.setListData(items.toArray());
            } else if (actionEvent.getActionCommand().equalsIgnoreCase("delete")) {
                List< String> items = new ArrayList< String>();

                for (int item = 0; item < jList.getModel().getSize(); item++) {
                    items.add(jList.getModel().getElementAt(item).toString());
                }

                items.remove(0);

                jList.setListData(items.toArray());
            }

            reSelect();
        }
    }

    private static void storeSelected() {
        if (jList.getSelectedIndex() > -1) {
            selectedValue = jList.getSelectedValue().toString();
        } else {
            selectedValue = null;
        }
    }

    private static void reSelect() {
        if (selectedValue != null) {
            jList.setSelectedValue(selectedValue, true);
        }
    }
}

+1 for sscce。你会如何处理多个选择?编辑:对于括号我很抱歉。 :-) - trashgod
这看起来非常棒,我会研究一下并试试看。 - Nico
我通过编辑storeSelected()来保存值数组(JList.getSelectedValues())来处理多个选择,然后在reselect中计算每个值的索引,然后使用setSelectedIndices(int [] indices)将它们全部设置。这不是最干净的方法,但它有效。感谢您的帮助! - Nico

4

看起来标准的JList没有调整排序的方法(他们为什么只在JTable中添加了这个...),但是有一个排序列表教程。


这是一篇很好的文章,看起来这就是正确的做法。 - Nico
一如既往的问题,使用模型装饰方法时,在批量更改通知期间,排序模型状态是未定义的... - kleopatra
@kleopatra,有什么好的解决方案吗?我看到SwingX项目的JXList提供了视图排序,但我不熟悉其源代码。 - Robin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接