JList 复制选择

Posted

技术标签:

【中文标题】JList 复制选择【英文标题】:JList duplicating selection 【发布时间】:2012-04-23 06:22:53 【问题描述】:

我正在尝试使用 Swing,并决定专注于将 JList 与对象数组列表结合使用。

我想创建一个显示空白 JList 的程序,当按下按钮时,它将显示 arraylist 的内容,并允许单个选择打印出曾经选择的内容。

我当前的代码执行上述所有操作,但是当我单击 JList 上的单个条目时,它会打印两次。我觉得这是一个很容易纠正的简单错误,但我一直在阅读它,我的大脑已经停止合作。

任何帮助将不胜感激。在此先感谢:)

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.event.*;


public class textarea 

    ArrayList <Pet> petList = new ArrayList <Pet> ();
    DefaultListModel model = new DefaultListModel();
    JList list = new JList();

    public static void main (String [] args)

        textarea gui = new textarea();
        gui.go();
    

    public void go()

        petList.add(new Pet("Lucy","Dog",5));
        petList.add(new Pet("Geoff","Cat",2));
        petList.add(new Pet("Hammond","Hamster",1));

        model = new DefaultListModel();
        for(Pet p:petList)
            model.addElement(p.toString());
        

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JButton button = new JButton("view pets");
        button.addActionListener(new ButtonListener());


        JScrollPane scroller = new JScrollPane(list);
        scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        panel.add(scroller);

        list.setVisibleRowCount(4);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(new ListSelectionListener()
            public void valueChanged(ListSelectionEvent event)
                String selection = (String) list.getSelectedValue();
                System.out.println(selection);
            
        );

        frame.getContentPane().add(BorderLayout.CENTER,panel);
        frame.getContentPane().add(BorderLayout.SOUTH,button);

        frame.setSize(350,300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //end go()

        class ButtonListener implements ActionListener
        public void actionPerformed(ActionEvent event)
                list.setModel(model);
            
        //end ButtonListener


【问题讨论】:

一般评论:您应该使用SwingUtilities.invokeLater() 在EDT 中运行GUI 代码。 谢谢,我会记住并相应地更改代码。 【参考方案1】:

简答:像这样在你的印刷品周围添加if (!event.getValueIsAdjusting())

list.addListSelectionListener(new ListSelectionListener()

  public void valueChanged(ListSelectionEvent event)
  
    if (!event.getValueIsAdjusting())
    
      String selection = (String) list.getSelectedValue();
      System.out.println(selection);
    
  
);

长答案:正在触发两个事件。单击鼠标时触发一个,释放鼠标时触发另一个。我们通常将单击视为单个动作,但实际上它是由鼠标按下、任何移动和鼠标释放组成的。在这些阶段,选择的内容可以改变。运行您的代码并尝试单击一行,拖动到其他行,然后释放。您会看到每次行更改时都会触发事件。通过仅在值不再调整时采取行动,您可以在“最终”状态下触发。

来源:ListSelectionEvent Javadocs 和 ListSelectionModel Javadocs

【讨论】:

谢谢埃里克。在做了你提到的事情之后,事件处理现在更有意义了。 我很高兴听到它很有帮助。欢迎使用 Stack Overflow!【参考方案2】:

刚刚测试了您的代码。在项目选择上发送 2 个事件。我能看到的唯一区别是 isAdjusting 布尔值。第一次设置为true,第二次设置为false

无论如何,这似乎是标准行为

【讨论】:

以上是关于JList 复制选择的主要内容,如果未能解决你的问题,请参考以下文章

JList - 单击已选择的项目时取消选择

如何防止 JList 在单元格边界之外进行选择?

如何在java中的某些事件上取消选择Jlist项目

从 JLIST 中选择一个项目并使用来自该选定 id 的所有 db 信息更新一个表单

禁用 JList 中的项目

Java swing弹出菜单和jlist