简体   繁体   中英

Double printing JList

I am not sure why everything is printing twice. For example, if you press "Male", then the program will print MaleMale. This is a part of a bigger program: I want gender (a String) to store the last selection. Is this code doing that?

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

Generally speaking, the ListSelectionListener will generate two events, one for the "deselection" of the currently selected item/range and one for the "selection" of the new item/range.

If you're only interested in what has become selected, you can use ListSelectionEvent#getValueIsAdjusting , which will return true if there are more events to come and false if no more related events are coming (or the selection has become stable), for example...

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

}

You can have a read of How to Write a List Selection Listener for more details

There are two events generated each time when you click on an item in the list: The first one is created when you press the mouse button, and the second one when you release the button.

(This is mainly relevant for more sophisticated patterns of range-selection, drag and drop, or the case where you press the button on one item and then drag the mouse to another item)

The solution is to check whether the "selection value is still adjusting" in the ListSelectionListener . So you can just do something like

if (event.getValueIsAdjusting()) return;

in your event listener method.

Here as a MCVE, together with a few other cleanups:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM