如果在两个选定值之间,则会自动选择插入自定义 ListModel 的元素

发布于 2024-11-27 08:23:44 字数 2005 浏览 2 评论 0原文

我注意到,当将一个元素添加到 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++;
        }

    }
}

I've noticed is that when an element is added to a JList and the element happens to fall within a range of values that are selected, it ends up being selected by default. In fact, if an element is added just above a selected value it is added to the selection.

I've tried looking at the JList code (in the open JDK6) and the BasicListUI code, but I'm having trouble teasing out the details of why this happens or what I need to do to fix it.

I'm considering supplying a custom SelectionModel, as that would be a sensible place to do some of the other work in my application, but I'm afraid that might make the problem worse, or harder to fix. Does anyone know why this happens? What I can do to fix it?

I've created this example that demonstrates the issue:

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++;
        }

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

巡山小妖精 2024-12-04 08:23:44

这不是问题,但我相信您应该使用 Swing Timer 而不是 Executor,以便代码在 EDT 上执行。

是的,问题在于选择模型。上次我查看代码时发现它相当令人困惑,所以我不确定您是否想使用它。

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

This isn't the problem but I believe you should be using a Swing Timer instead of an Executor so the code get executed on the EDT.

Yes the problem is the selection model. The last time I looked at the code I found it rather confusing, so I'm not sure you want to play with it.

The only thing I can think of is to make sure you are using the multiple selection interval. Then after inserting an elemnt you check to see if the element is selected. If it is then you remove the selection for that element.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文