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

标签 java swing list listselectionlistener

我需要允许用户点击一个按钮来选择一个目录,然后我在列表中显示该目录的所有文件并允许他们选择任意数量的文件。 选择文件后,我应该阅读每个文件的第一行并将其放入新列表中。

到目前为止,我可以选择目录并显示文件列表。但是,问题是应用程序不会显示文件列表,除非我调整窗口大小。一旦我调整它的大小,列表就会刷新并显示文件。我该如何解决这个问题以及如何找出从列表中选择了哪些项目。

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

    }
}

最佳答案

How can I solve the issue

有许多可能的解决方案,在您的情况下最简单的可能是在将 JList 添加到内容 Pane 后调用 revalidate,问题是,您已选择使用 null 布局 (frame.getContentPane().setLayout(null);),这使得调用 revalidate 毫无意义,因为这用于指示布局管理器他们需要更新布局细节。

避免使用 null 布局,像素完美布局是现代 ui 设计中的一种错觉。影响组件单个尺寸的因素太多,没有一个是您可以控制的。 Swing 旨在与核心的布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

我建议您稍微改变一下您的方法。

首先使用一个或多个布局管理器,将“浏览”按钮、“分析”按钮和 JList 添加到框架的开头。当用户选择一个目录时,构建一个新的 ListModel,然后将其应用于您创建的 JList。更改 JListListModel 将强制 JList 自动更新。

参见 Laying Out Components Within a Container了解更多详情

and how can I find out which items are selected from the list.

参见 How to Use Lists了解更多详情

更新了示例

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

    }

}

关于java - 如何获得 JList 的选定项目列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28182491/

相关文章:

java - 基于5000字节分割文件

list - 在 Haskell 中 undefined 是部分列表吗?

python - 附加列表但错误 'NoneType' 对象没有属性 'append'

java - Spring MVC 父模板模型组件

java - 为什么在我的查询中添加 Where 子句时没有得到结果?

java - 错误的组件(在单独的 JPanel 类中)获得焦点

java - 使用 MySQL 数据库创建 jar 到 exe

Java/Swing - 传递应用程序对象

c++ - 从初始化列表分配给数组

java - 如何在Java中检测矩形的哪条边被击中