问题
Value is updated by the end, but not during the process. I guess the reason is that the publish
method locates outside the loop.
As to invoke PropertyChangeListener
, can it be achieved by defining the class without extends SwingWorker<Void, Void>
?
To address the question in another way, I have two threads locate in two different classes. Is it possible to build communication between the two using SwingWorker
?
Class Application
import javax.swing.JFrame;
public class Application {
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
JFrame frame = new Progress();
frame.setSize(200, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
Class Progress
import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
@SuppressWarnings("serial")
public class Progress extends JFrame{
private JProgressBar progressbar;
public Progress(){
JButton button = new JButton("Run");
progressbar = new JProgressBar(0, 100);
progressbar.setValue(0);
progressbar.setStringPainted(true);
JPanel panel = new JPanel();
panel.add(button);
panel.add(progressbar);
add(panel, BorderLayout.PAGE_START);
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
start();
}
});
}
private void start(){
progressbar.setValue(0);
SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){
@Override
protected Void doInBackground() throws Exception {
Simulation sim = new Simulation();
publish(sim.getCount());
return null;
}
@Override
protected void process(List<Integer> chunks) {
Integer progress = chunks.get(chunks.size()-1);
progressbar.setValue(progress);
progressbar.repaint();
progressbar.update(progressbar.getGraphics());
}
@Override
protected void done() {
Toolkit.getDefaultToolkit().beep();
}
};
worker.execute();
}
}
Class Simulation
public class Simulation {
private int count;
public Simulation(){
for(int i=0; i<100; i++){
count++;
System.out.println(count);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int getCount(){
return count;
}
}
How can I update the value during the process?
回答1:
You need to implement PropertyChangeListener
on your SwingWorker
and listen to the Progress
property changes and then from overridden propertChange()
method update your JProgressBar.
Here is what you are looking.
Hope this helps.
来源:https://stackoverflow.com/questions/23699256/using-swingworker-to-update-the-progress-of-a-thread-from-another-class