简体   繁体   English

如何获得JList的选定项列表?

[英]How to have a list of selected items of JList?

I need to allow users to click on a button to select a directory, then I show all files of the directory in a list and allow them to select any number of files. 我需要允许用户单击按钮来选择目录,然后在列表中显示该目录的所有文件,并允许他们选择任意数量的文件。 After selecting the files, I should read the first line of each file and put that in a new list for them. 选择文件后,我应该阅读每个文件的第一行并将其放在新列表中。

So far I can select the directory and show a list of files. 到目前为止,我可以选择目录并显示文件列表。 However, the problem is that the application wont show the list of files unless I resize the window. 但是,问题在于,除非我调整窗口大小,否则应用程序将不会显示文件列表。 As soon as I resize it the list get refreshed and show the files. 调整大小后,列表就会刷新并显示文件。 How can I solve the issue and how can I find out which items are selected from the list. 我该如何解决该问题,以及如何找出从列表中选择的项目。

    private JFrame frame;
    final JFileChooser fc = new JFileChooser();
    private JScrollPane scrollPane;
    File directory;
    JList<File>  list;


    /**
     * 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.setBounds(100, 100, 785, 486);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JButton btnChooseDirectory = new JButton("Choose Directory");
        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);
                }
            }
        });
        btnChooseDirectory.setBounds(59, 27, 161, 29);
        frame.getContentPane().add(btnChooseDirectory);



        JLabel lblFilesMsg = new JLabel("List of files in the directory.");
        lblFilesMsg.setBounds(20, 59, 337, 16);
        frame.getContentPane().add(lblFilesMsg);

        JButton btnParseXmls = new JButton("Analyze");
        btnParseXmls.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                for (File name : list.getSelectedValuesList()) {
                    System.err.println(name.getAbsolutePath());
                }
            }
        });
        btnParseXmls.setBounds(333, 215, 117, 29);
        frame.getContentPane().add(btnParseXmls);


    }

    private void addFilesToList(File[] filesInDir){

        list = new JList<File>(filesInDir);

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

        scrollPane = new JScrollPane(list);
        scrollPane.setBounds(20, 81, 318, 360);
        frame.getContentPane().add(scrollPane);

    }
}

Don't use null layouts and absolute positioning with Swing GUI's. 不要在Swing GUI中使用空布局和绝对定位。 It's a newbie fallacy to believe that this is the easiest way to make decent complex GUI's, and it will bite you in the end, leaving you with difficult to enhance GUI's that are rigid, that look OK on one platform and screen resolution but that look terrible on all others. 相信这是制作像样的复杂GUI的最简单方法,这是一个新手谬论,它最终会咬住您,使您难以增强那些僵化的GUI,在一个平台和屏幕分辨率上看起来不错,但看起来对其他所有人都非常糟糕。 Use the layout managers. 使用布局管理器。

If you add a new component to a container, don't forget to call revalidate() and repaint() on the container to allow Swing to display the newly added components. 如果将新组件添加到容器,请不要忘记在容器上调用revalidate()repaint()以允许Swing显示新添加的组件。

How can I solve the issue 我该如何解决这个问题

There are a number of possible solutions, the simplest in your case might be to call revalidate after you have added the JList to the content pane, the problem is, you've elected to use a null layout ( frame.getContentPane().setLayout(null); ) which makes calling revalidate pointless, as this is used to instruct the layout managers that they need to update their layout details. 有很多可能的解决方案,在您的情况下,最简单的方法可能是在将JList添加到内容窗格后调用revalidate ,问题是,您选择使用null布局( frame.getContentPane().setLayout(null); ),这使调用revalidate变得毫无意义,因为这用于指示布局管理器他们需要更新其布局详细信息。

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. 避免使用null布局,像素完美布局是现代ui设计中的一种幻觉。 There are too many factors which affect the individual size of components, none of which you can control. 有太多因素会影响组件的单个大小,您无法控制。 Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify Swing旨在与布局经理为核心一起工作,舍弃这些问题不会导致问题和问题的终结,您将花费越来越多的时间来纠正问题

What I would suggest doing is changing your approach slightly. 我建议您做的是稍微改变您的方法。

Start by using one or more layout managers, add the "browse" button, "analyze" button and JList to the frame at the start. 首先使用一个或多个布局管理器,将“浏览”按钮,“分析”按钮和JList到框架的开头。 When the user selects a directory, build a new ListModel and then apply this to the JList you created to start with. 当用户选择目录时,构建一个新的ListModel ,然后将其应用于您创建的JList Changing the ListModel of the JList will force the JList to update automatically. 更改JListListModel将强制JList自动更新。

See Laying Out Components Within a Container for more details 有关更多详细信息,请参见在容器中布置组件

and how can I find out which items are selected from the list. 以及如何找到从列表中选择的项目。

See How to Use Lists for more details 有关更多详细信息,请参见如何使用列表

Updated with example 更新了示例

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
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;

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 JList listOfFiles;

        public TestPane() {
            setLayout(new BorderLayout());
            listOfFiles = new JList();
            add(new JScrollPane(listOfFiles));

            JPanel top = new JPanel();
            top.add(new JLabel("Pick a directory"));
            JButton pick = new JButton("Pick");
            pick.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JFileChooser 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 = new DefaultListModel<>();
                    for (File file : filesInDir) {
                        model.addElement(file);
                    }
                    listOfFiles.setModel(model);
                }
            });
            top.add(pick);

            add(top, BorderLayout.NORTH);

            JPanel bottom = new JPanel();
            JButton analyze = new JButton("Analyze");
            bottom.add(analyze);

            add(bottom, BorderLayout.SOUTH);
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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