Jack
Jack

Reputation: 6600

JList gets updated but just allow users to select items once

I have a JList that is located in a JScrollPane. The application has a button for users to browse fileSystem and select a category to show its files and folders.

First time user clicks on the button JList shows the list and enables user to select from the list but if user clicks on the browse button for the second time new items will be shown but he wont be able to select any item from the list anymore.

public class Main {

    private JFrame frame;
    final JFileChooser fc = new JFileChooser();
    private JScrollPane scrollPane;
    File directory;
    JList<File> list;
    private final Action action_1 = new SwingAction_1();
    private final Action action_2 = new SwingAction_2();
    JTextArea message;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main window = new Main();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public Main() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.getContentPane().setBackground(Color.WHITE);
        frame.setBounds(100, 100, 800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        list = new JList<File>();

        JButton btnBut1 = new JButton("Convert1");
        btnBut1.setBounds(401, 6, 114, 29);
        btnBut1.setAction(action_1);

        JButton btnBut2 = new JButton("Convert2");
        btnBut2.setBounds(523, 6, 117, 29);
        btnBut2.setAction(action_2);

        JButton btnChooseDirectory = new JButton("Choose Directory");
        btnChooseDirectory.setBounds(59, 6, 153, 29);
        btnChooseDirectory.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int returnVal = fc.showOpenDialog(fc);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    directory = fc.getSelectedFile();
                    File[] filesInDir = directory.getAbsoluteFile().listFiles();
                    addFilesToList(filesInDir);
                }
            }
        });
        frame.getContentPane().setLayout(null);
        frame.getContentPane().add(btnChooseDirectory);

        JLabel lblFilesMsg = new JLabel("List of files in the directory:");
        lblFilesMsg.setBounds(6, 64, 175, 16);
        frame.getContentPane().add(lblFilesMsg);
        frame.getContentPane().add(btnBut1);
        frame.getContentPane().add(btnBut2);

        message = new JTextArea();
        message.setBounds(6, 426, 788, 146);
        message.setEditable(false);
        message.setLineWrap(true);
        frame.getContentPane().add(message);

        frame.setTitle(APP_NAME);

    }

    private void addFilesToList(File[] filesInDir) {

        list.setListData(filesInDir);

        list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        list.setLayoutOrientation(JList.VERTICAL);

        scrollPane = new JScrollPane(list);

        scrollPane.setBounds(6, 81, 788, 330);
        scrollPane.setBackground(Color.WHITE);
        frame.getContentPane().add(scrollPane);
        scrollPane.revalidate();

    }

    private class SwingAction_1 extends AbstractAction {
        public SwingAction_1() {
            putValue(NAME, "Converter1");
        }

        public void actionPerformed(ActionEvent e) {

            MyAction1 act = new MyAction1();
            act.method1(list.getSelectedValuesList());

        }

    }

    private class SwingAction_2 extends AbstractAction {
        public SwingAction_2() {
            putValue(NAME, "Converter2");
        }

        public void actionPerformed(ActionEvent e) {

             MyAction2 act = new MyAction2();
             act.method2(list.getSelectedValuesList());
        }

    }

}

Upvotes: 0

Views: 290

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347184

I would suggest your problem(s) start with:

  • Creating a JScrollPane within the addFilesToList method: scrollPane = new JScrollPane(list);. Create the JList AND JScrollPane ONCE, there should be no need to continuously recreate these
  • Use of null layouts. This has been suggested to you more times then I care to remember. Seriously, make the time to learn the layout managers, it will solve so many small and annoying problems

The problem here...

scrollPane.setBounds(6, 81, 788, 330);
scrollPane.setBackground(Color.WHITE);
frame.getContentPane().add(scrollPane);

Is, which JScrollPane is actually visible on the screen? Which one actually contains the JList? You have more than one now...

And yet, another, simple, runnable example, which works...

FileChooser

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class Test {

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

    public Test() {
        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);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JFileChooser fc;
        private JList<File> listOfFiles;
        private JLabel selectedFile;

        public TestPane() {
            setLayout(new BorderLayout());
            JButton browse = new JButton("Browse");
            browse.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (fc == null) {
                        fc = new JFileChooser();
                        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                    }
                    int returnVal = fc.showOpenDialog(fc);
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        File directory = fc.getSelectedFile();
                        File[] filesInDir = directory.getAbsoluteFile().listFiles();
                        addFilesToList(filesInDir);
                    }
                }

                protected void addFilesToList(File[] filesInDir) {
                    DefaultListModel<File> model = (DefaultListModel<File>) listOfFiles.getModel();
                    model.removeAllElements();
                    for (File file : filesInDir) {
                        model.addElement(file);
                    }
                }
            });
            add(browse, BorderLayout.NORTH);

            listOfFiles = new JList<>(new DefaultListModel<File>());
            listOfFiles.addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    if (!e.getValueIsAdjusting()) {
                        File file = listOfFiles.getSelectedValue();
                        selectedFile.setText("You selected: " + (file == null ? "Nothing" : file.getPath()));
                    }
                }
            });
            add(new JScrollPane(listOfFiles));

            selectedFile = new JLabel("You selected: Nothing");
            add(selectedFile, BorderLayout.SOUTH);

        }

    }

}

Upvotes: 1

Related Questions