双打印 JList

Double printing JList

我不确定为什么所有内容都打印两次。例如,如果您按 "Male",那么程序将打印 MaleMale。这是一个更大程序的一部分:我想要性别(一个字符串)来存储最后的选择。这段代码是这样做的吗?

DefaultListModel toAdd = new DefaultListModel();
toAdd.addElement("Male");
toAdd.addElement("Female");
toAdd.addElement("Others");

JList list = new JList();
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setBorder(new TitledBorder(null, "How do you identify yourself?", ` 
TitledBorder.CENTER, TitledBorder.TOP, null, null));
list.setBackground(SystemColor.info);
list.setBounds(57, 85, 244, 97);
list.setModel(toAdd);
frame.getContentPane().add(list);

list.addListSelectionListener(new ListSelectionListener() {

        public void valueChanged (ListSelectionEvent event) {
            int lastSelIx = list.getMaxSelectionIndex();
            gender = (String) list.getModel().getElementAt(lastSelIx);
            System.out.print(gender);
        }       
    );
}

每次单击列表中的项目时都会生成两个事件:第一个在您 按下 鼠标按钮时创建,第二个在您释放 按钮。

(这主要与范围选择、拖放等更复杂的模式有关,或者您在一个项目上按下按钮然后将鼠标拖动到另一个项目的情况)

解决方法是查看ListSelectionListener中是否有"selection value is still adjusting"。所以你可以做类似

的事情
if (event.getValueIsAdjusting()) return;

在您的事件侦听器方法中。

此处作为 MCVE,以及一些其他清理工作:

import java.awt.SystemColor;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JListSelectionDoubleEvent
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        DefaultListModel<String> listModel = new DefaultListModel<String>();
        listModel.addElement("Male");
        listModel.addElement("Female");
        listModel.addElement("Others");

        JList<String> list = new JList<String>(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setBorder(
            BorderFactory.createTitledBorder("How do you identify yourself?"));
        list.setBackground(SystemColor.info);

        list.addListSelectionListener(new ListSelectionListener()
        {
            @Override
            public void valueChanged(ListSelectionEvent event)
            {
                if (event.getValueIsAdjusting())
                {
                    //System.out.println("Adjusting. Ignore this");
                    return;
                }
                String gender = list.getSelectedValue();
                System.out.print(gender);
            }
        });

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(list);
        frame.setSize(400, 400);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

一般来说,ListSelectionListener会产生两个事件,一个是针对当前选中的item/range的"deselection",一个是针对新[=]的"selection" 24=].

如果您只对已选择的内容感兴趣,可以使用 ListSelectionEvent#getValueIsAdjusting,如果还有更多活动,return true false 如果没有更多的相关事件到来(或者选择已经稳定),例如...

import java.awt.EventQueue;
import java.awt.SystemColor;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JavaApplication20 {

    public static void main(String[] args) {
        new JavaApplication20();
    }

    public JavaApplication20() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                DefaultListModel toAdd = new DefaultListModel();
                toAdd.addElement("Male");
                toAdd.addElement("Female");
                toAdd.addElement("Others");

                JList list = new JList();
                list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                list.setBorder(new TitledBorder(null, "How do you identify yourself?", TitledBorder.CENTER, TitledBorder.TOP, null, null));
                list.setBackground(SystemColor.info);
                list.setModel(toAdd);
                frame.getContentPane().add(new JScrollPane(list));

                list.addListSelectionListener(new ListSelectionListener() {

                    public void valueChanged(ListSelectionEvent event) {
                        if (!event.getValueIsAdjusting()) {
                            int lastSelIx = list.getMaxSelectionIndex();
                            String gender = (String) list.getModel().getElementAt(lastSelIx);
                            System.out.println(gender);
                        } else {
                            // You can ignore this, I was just testing ;)
                            int lastSelIx = event.getFirstIndex();
                            String gender = (String) list.getModel().getElementAt(lastSelIx);
                            System.out.println(gender);
                        }
                    }
                });
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

您可以阅读 How to Write a List Selection Listener 了解更多详情