Java 如果插入到自定义ListModel中的元素位于两个选定值之间,则会自动选择该元素

Java 如果插入到自定义ListModel中的元素位于两个选定值之间,则会自动选择该元素,java,swing,selection,jlist,defaultlistmodel,Java,Swing,Selection,Jlist,Defaultlistmodel,我注意到,当一个元素被添加到一个JList中,并且该元素恰好落在所选值的范围内时,默认情况下它会被选中。事实上,如果将某个元素添加到选定值的正上方,则该元素将添加到选定内容中 我试过查看JList代码(在开放的JDK6中)和BasicListUI代码,但是我很难弄清楚为什么会发生这种情况,或者我需要做些什么来修复它 我正在考虑提供一个定制的SelectionModel,因为这是在我的应用程序中进行其他一些工作的一个合理的地方,但我担心这可能会使问题变得更糟,或者更难解决。有人知道为什么会这样吗?

我注意到,当一个元素被添加到一个JList中,并且该元素恰好落在所选值的范围内时,默认情况下它会被选中。事实上,如果将某个元素添加到选定值的正上方,则该元素将添加到选定内容中

我试过查看JList代码(在开放的JDK6中)和BasicListUI代码,但是我很难弄清楚为什么会发生这种情况,或者我需要做些什么来修复它

我正在考虑提供一个定制的SelectionModel,因为这是在我的应用程序中进行其他一些工作的一个合理的地方,但我担心这可能会使问题变得更糟,或者更难解决。有人知道为什么会这样吗?我能做些什么来修复它

我创建了这个示例来演示这个问题:

package jlistsscce;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;

public class JListSSCCE extends JPanel
{
    private final JList list;
    private ScheduledExecutorService ses;

    public JListSSCCE()
    {
        list = new JList();
        list.setModel(new DefaultListModel());
        ses = Executors.newSingleThreadScheduledExecutor();
        ses.scheduleAtFixedRate(new NewElement(), 100, 100, TimeUnit.MILLISECONDS);
        add(list);
    }

    private static void createGui()
    {
        // create new JFrame
        JFrame jf = new JFrame("JListSSCCE");

        // this allows program to exit
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // You add things to the contentPane in a JFrame
        jf.getContentPane().add(new JListSSCCE());

        // size frame
        jf.pack();

        // make frame visible
        jf.setVisible(true);

    }

    public static void main(String[] args)
    {
        // threadsafe way to create a Swing GUI
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run()
                {
                    createGui();
                }
            }
        );
    }

    private class NewElement implements Runnable
    {
        int n = 0;
        @Override
        public void run()
        {
            ((DefaultListModel)list.getModel()).add((int)Math.floor(Math.sqrt(n)), ("hey"+n));
            n++;
        }

    }
}

这不是问题所在,但我认为应该使用Swing计时器而不是执行器,这样代码就可以在EDT上执行

是的,问题在于选择模型。上次看代码时,我发现它相当混乱,所以我不确定您是否想玩它


我能想到的唯一一件事是确保您使用的是多重选择间隔。然后在插入一个元素后,检查该元素是否被选中。如果是,则删除对该元素的选择。

虽然这确实回答了“如何修复它?”的问题,但我很想理解为什么会发生这种情况。当用户从我的列表中选择一个值时,他们选择的不仅仅是一个值,而且所选的内容会相互作用。我真的希望将其封装在SelectionModel中,而不是在默认模型和另一个类之间进行一些笨拙的交互。我想我可以只包装默认值…我认为这是许多组件的正常行为。考虑编辑具有突出显示文本的Word文档。如果在中间插入文本,则继承相同的高亮显示。高亮显示的工作方式是保持开始/结束范围,因此添加到中间会增加范围。我不认为行选择的默认行为以相同的方式工作有什么区别。我同意,将代码封装在选择模型中将是首选方法。我只是不确定这会有多容易/难。