There are some example for similar question (Progress Bar Java) and (Java uploading percentage progressbar thread) but didn't understand how to make it work for my code.
My main has 2 panels one over the other (one of which is a tabbedPane with 2 tabs)
public class MainIRH {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
MainWindow window = new MainWindow();
JPanel mainPanel = new JPanel(new BorderLayout(0, 20));
mainPanel.setBorder(new EmptyBorder(20, 20, 20, 20));
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
ControlPanel controlPanel = new ControlPanel();
tabbedPane.setBorder(new EmptyBorder(10, 10, 10, 10));
controlPanel.setBorder(new EmptyBorder(0, 20, 20, 20));
ECPanel ecPanel = new ECPanel();
SMRPanel smrPanel = new SMRPanel();
tabbedPane.addTab("Environnement Canada", null, ecPanel, "Convertir des données des stations d\'Environnement Canada");
tabbedPane.addTab("Station Météo Routière", null, smrPanel, "Convertir des données des stations météos routières");
mainPanel.add(tabbedPane, BorderLayout.NORTH);
mainPanel.add(controlPanel, BorderLayout.CENTER);
window.add(mainPanel);
new ControllerIRH(ecPanel, smrPanel, controlPanel);
window.setVisible(true);
}
});
}
}
The important bit is this object : SMRPanel smrPanel = new SMRPanel();
Inside this object I have a JButton convertArchiveButton
that I add a ActionListener from a Controller
class
public void addConvertArchiveButton(ActionListener ConvertArchiveButton) {
convertArchiveButton.addActionListener(ConvertArchiveButton);
}
Here's the the implementation of the Listener in the Controller
private class ConvertArchiveButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
converter.convert();
}
}
converter
is the class that does the lengthy operation
File[] listOfFiles = folder.listFiles();
for (int file = 0; file < listOfFiles.length; file++) {
int progress = Math.round(file * 100 / listOfFiles.length);
//tried a lot of things here...
//...computing
}
I example tried to add some new Runnable
with both EventQueue
and SwingUtilities
but didn't work. A SwingWorker
class would be useful? Don't quite understand the use.
Basically, int progress
would be passed to the JProgressBar
in the SMRPanel
.
EDIT WITH ControlAltDel answer :
Still doesn't work, converter.readFile(file);
doesn't get called.
private class ConvertArchiveButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
File[] listOfFiles = folder.listFiles();
System.out.println(listOfFiles.length);
for (int i = 0; i < listOfFiles.length; i++) {
final File file = listOfFiles[i];
final int idx = (i * 100) / listOfFiles.length;
Thread t = new Thread(new Runnable() {
public void run() {
converter.readFile(file);
System.out.println(idx);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
smrPanel.setProgressBarValue(idx);
}
});
}
});
try {
t.start();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
converter.convert(year);
}
}
Your problem is that you are running your loop in the EDT thread. Fix by running this in another thread, and then setting the updated progress value in the EDT when you finish processing a file