如何获得JList的选定项目列表?(How to have a list of selected items of JList?)

编程入门 行业动态 更新时间:2024-10-27 03:38:30
如何获得JList的选定项目列表?(How to have a list of selected items of JList?)

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

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

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

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

最满意答案

我该如何解决这个问题

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

避免使用null布局,像素完美的布局是现代UI设计中的幻想。 影响组件的个体大小的因素太多,其中没有一个可以控制。 Swing旨在与布局经理一起工作,放弃这些将导致无法结束的问题和问题,您将花费越来越多的时间来尝试纠正

我会建议做的是稍微改变你的方法。

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

有关更多详细信息,请参阅放置容器内的组件

以及如何找出从列表中选择哪些项目。

JList#getSelectedIndices JList#getSelectedValuesList

有关更多详细信息,请参阅如何使用列表

以示例更新

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

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.

Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. 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

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. When the user selects a directory, build a new ListModel and then apply this to the JList you created to start with. Changing the ListModel of the JList will force the JList to update automatically.

See Laying Out Components Within a Container for more details

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

JList#getSelectedIndices JList#getSelectedValuesList

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

更多推荐

本文发布于:2023-07-14 23:38:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1108331.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何获得   项目   列表   JList   items

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!