JList得到更新,但只允许用户选择一次项目

我有一个位于JScrollPane中的JList。 该应用程序有一个按钮,供用户浏览fileSystem并选择一个类别来显示其文件和文件夹。

第一次用户点击按钮JList显示列表并允许用户从列表中进行选择,但如果用户第二次点击浏览按钮,将显示新项目,但他将无法再从列表中选择任何项目。

public class Main { private JFrame frame; final JFileChooser fc = new JFileChooser(); private JScrollPane scrollPane; File directory; JList 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(); 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()); } } } 

我建议你的问题从:

  • addFilesToList方法中创建JScrollPanescrollPane = new JScrollPane(list); 。 创建JListJScrollPane ONCE,不需要不断重新创建它们
  • 使用null布局。 这已被建议给你多次,我记得。 说真的,花时间学习布局管理器,它会解决这么多小而恼人的问题

这里的问题……

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

是,哪个JScrollPane实际上在屏幕上可见? 哪一个实际包含JList ? 你现在有不止一个……

然而,另一个简单,可运行的例子,它的作用……

文件选择

 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 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 model = (DefaultListModel) listOfFiles.getModel(); model.removeAllElements(); for (File file : filesInDir) { model.addElement(file); } } }); add(browse, BorderLayout.NORTH); listOfFiles = new JList<>(new DefaultListModel()); 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); } } }