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