如果在两个选定值之间,则会自动选择插入自定义 ListModel 的元素
我注意到,当将一个元素添加到 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这不是问题,但我相信您应该使用 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.