javaswingjlistlistselectionlistener

JList Item Selection


I was wondering if there is a way, by selecting an item with a JList, to let the program perform some code. This code should run every time a new item is selected.

Previously, I had added a listener. Here is a minimal example I made.

public class Driver {

    public static void main(String[] args) {
        JFrame frame = new ListFrame();
        frame.setVisible(true);
        frame.setSize(200,100);
    }

}

public class ListFrame extends JFrame {

    private JList<String> list; 
    private JScrollPane scrollPane;
    private String[] data = {"A","B","C"};
    private JButton addButton = new JButton("Add");

    public ListFrame() {
        setLayout(new BorderLayout());

        list = new JList<String>(data);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        scrollPane = new JScrollPane(list);

        add(scrollPane, BorderLayout.CENTER);
        add(addButton, BorderLayout.SOUTH);

        addButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                String newEntry = JOptionPane.showInputDialog("Add new entry.");
                String[] tempData = new String[data.length + 1];
                for(int i = 0; i < data.length; i++)
                    tempData[i] = data[i];
                tempData[data.length] = newEntry;
                data = tempData;
                list = new JList<String>(data);
                scrollPane.setViewportView(list);
            }

        });

        list.addListSelectionListener(
                new ListSelectionListener() {

                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        System.out.println("Hi");
                    }

        });
    }
}

However, when I click an item on the Jlist, nothing is printed.


Solution

  • Your example uses getSelectionModel() to get the the list's ListSelectionModel, and it adds your listener directly to the selection model. This bypasses the ListSelectionHandler, used internally by JList, which never gets a chance to fireSelectionValueChanged(). Instead, let JList add your listener:

    list.addListSelectionListener(new ListSelectionListener() {...}
    

    when I click an item on the JList, nothing is printed.

    Your new example prints "Hi" when I click an item, but I see some problems:

    See How to Write a List Selection Listener for more; here's the example I tested.

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.DefaultListModel;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.JOptionPane;
    import javax.swing.JScrollPane;
    import javax.swing.ListSelectionModel;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    
    public class Driver {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(() -> {
                JFrame frame = new ListFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            });
        }
    
        private static class ListFrame extends JFrame {
    
            private final String[] data = {"A", "B", "C"};
            private final DefaultListModel model = new DefaultListModel();
            private final JList<String> list = new JList<>(model);
            private final JButton addButton = new JButton("Add");
    
            public ListFrame() {
                for (String s : data) {
                    model.addElement(s);
                }
                list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                add(new JScrollPane(list), BorderLayout.CENTER);
                add(addButton, BorderLayout.SOUTH);
                addButton.addActionListener(new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        String newEntry = JOptionPane.showInputDialog("Add new entry.");
                        model.addElement(newEntry);
                    }
                });
                list.addListSelectionListener(new ListSelectionListener() {
    
                    @Override
                    public void valueChanged(ListSelectionEvent e) {
                        if (!e.getValueIsAdjusting()) {
                            System.out.println(e.getFirstIndex() + " " + e.getLastIndex());
                        }
                    }
                });
            }
        }
    }