I have a JButton
(swing
) in the JPanel
, where if it is pressed I am performing a task on the for loop over the list in its EDT thread
. While doing so I need to update the JProgressBar
.
Problem is, when I am pressing the JButton the task is performed in Event Dispatch Thread (EDT). So I can't update the JProgressBar
which is triggered either in main or UI thread.
Right now the source code is not available at me as I completely changed it and tried to use Eclipse SWT for JProgressBar
when that Swing JButton
is triggered, it becomes messy.
Now I got invalid thread access
error, as the Display object runs in separate UI thread. At a time, only either a Swing JPanel
or Eclipse SWT Shell
gets displayed.
I am triggering JPanel
using JOptionPane
.
You need to do your long running job and updating the progress bar value in a separate Thread from EDT
. Most of the time SwingWorker
is a good way to do that. So in your ActionListener
of that button you should separate the long running thread from the EDT. You can do it with bare Thread
but Workers and specially SwingWorker
is designed for such cases:
package graphics;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class GraphicDev extends JFrame{
private static final long serialVersionUID = 679207429168581441L;
//
private static final int FRAME_WIDTH = 300;
private static final int FRAME_HEIGHT = 100;
private int percent;
private JProgressBar progress;
public GraphicDev() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
setBounds(dim.width/2-FRAME_WIDTH/2, dim.height/2-FRAME_HEIGHT/2, FRAME_WIDTH, FRAME_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//
setLayout(new FlowLayout());
//
progress = new JProgressBar(0, 100);
progress.setStringPainted(true);
//
JButton actButton = new JButton("Start!");
actButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
for (long i = 0; i < 10000000000000L; i++) {
System.out.println(i);
if(i%200000 == 0){
progress.setValue(percent++);
}
if(percent >= 100){
break;
}
}
return null;
}
@Override
protected void done() {
JOptionPane.showMessageDialog(GraphicDev.this, "Done!");
}
}.execute();
}
});
//
add(actButton);
add(progress);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GraphicDev g = new GraphicDev();
g.setVisible(true);
}
});
}
}
Hope this would be helpful.