我有多个扩展SwingWorker的类。我希望实现的是逐个执行每个类(不执行上一个类'done方法中的下一个类)。例如,假设我有:
ClassSwingW1 csw1 = new ClassSwingW1();
csw1.execute;
ClassSwingW2 csw2 = new ClassSwingW2();
csw2.execute;
ClassSwingW3 csw3 = new ClassSwingW3();
csw3.execute;
等等。
public class ClassSwingW1 extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
//do something
return null;
}
}
public class ClassSwingW2 extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
//do something
return null;
}
}
public class ClassSwingW3 extends SwingWorker<Void, Void> {
@Override
protected Void doInBackground() throws Exception {
//do something
return null;
}
}
我希望csw2在csw1完成后执行,csw3在csw2完成后执行。我不想要他们 同时执行。我怎么做到这一点?谢谢
答案 0 :(得分:3)
您可以使用get()
method代替execute()
- 它会阻止,直到SwingWorker完成其工作。只要确保你没有从美国东部时间调用它。
Javadoc提取物:
如果需要等待计算完成,然后检索其结果。 注意:调用事件调度线程上的get会阻止处理所有事件,包括重绘,直到此SwingWorker完成。
答案 1 :(得分:3)
我建议您通过收听PropertyChangeListener来了解Executor
调用SwingWorker
个实例
请read carrefully this thread,尤其是@trashgod
的答案
Executor
&amp; SwingWorker
&amp; PropertyChangeListener
&amp; Swing GUI
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class ExecutorAndSwingWorker2 {
private JFrame frame = new JFrame();
private JButton button1;
private JButton button2;
private JButton button3;
private JButton button4;
private JPanel buttonPanel = new JPanel();
private Executor executor = Executors.newCachedThreadPool();
private javax.swing.Timer timer1;
private javax.swing.Timer timer2;
private javax.swing.Timer timer3;
private javax.swing.Timer timer4;
private Random random = new Random();
public ExecutorAndSwingWorker2() {
button1 = new JButton(" Executor + SwingWorker Thread No.1 ");
button1.setFocusable(false);
button2 = new JButton(" Executor + SwingWorker Thread No.2 ");
button3 = new JButton(" Executor + SwingWorker Thread No.3 ");
button4 = new JButton(" Executor + SwingWorker Thread No.4 ");
buttonPanel = new JPanel();
buttonPanel.setBorder(new EmptyBorder(15, 15, 15, 15));
buttonPanel.setLayout(new GridLayout(2, 2, 20, 20));
buttonPanel.add(button1);
buttonPanel.add(button2);
buttonPanel.add(button3);
buttonPanel.add(button4);
frame.setTitle("Shaking Button Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(buttonPanel);
frame.setPreferredSize(new Dimension(700, 170));
frame.setLocation(150, 100);
frame.pack();
frame.setVisible(true);
executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
}
private void startButton1() {
System.out.println("Starting long Thread == startButton1()");
try {
Thread.sleep(15000);
} catch (InterruptedException ex) {
}
}
private void startButton2() {
System.out.println("Starting long Thread == startButton2()");
try {
Thread.sleep(17500);
} catch (InterruptedException ex) {
}
}
private void startButton3() {
System.out.println("Starting long Thread == startButton3()");
try {
Thread.sleep(12500);
} catch (InterruptedException ex) {
}
}
private void startButton4() {
System.out.println("Starting long Thread == startButton4()");
try {
Thread.sleep(20000);
} catch (InterruptedException ex) {
}
}
private void colorAction1() {
timer1 = new Timer(1000, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
random = new Random();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button1.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
button1.validate();
button1.repaint();
}
});
}
});
timer1.setDelay(500);
timer1.setRepeats(true);
timer1.start();
}
private void colorAction2() {
timer2 = new Timer(1200, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
random = new Random();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button2.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
button2.validate();
button2.repaint();
}
});
}
});
timer2.setDelay(500);
timer2.setRepeats(true);
timer2.start();
}
private void colorAction3() {
timer3 = new Timer(1400, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
random = new Random();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button3.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
button3.validate();
button3.repaint();
}
});
}
});
timer3.setDelay(500);
timer3.setRepeats(true);
timer3.start();
}
private void colorAction4() {
timer4 = new Timer(1600, new AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
random = new Random();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
button4.setBackground(new Color(127 + random.nextInt(128), 127 + random.nextInt(128), 127 + random.nextInt(128)));
button4.validate();
button4.repaint();
}
});
}
});
timer4.setDelay(500);
timer4.setRepeats(true);
timer4.start();
}
private void endButton1() {
timer1.stop();
button1.setBackground(null);
System.out.println("Long Thread Ends == startButton1()");
executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton3")); // non on EDT
}
private void endButton2() {
timer2.stop();
button2.setBackground(null);
System.out.println("Long Thread Ends == startButton2()");
}
private void endButton3() {
timer3.stop();
button3.setBackground(null);
System.out.println("Long Thread Ends == startButton3()");
executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton2")); // non on EDT
executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton4")); // non on EDT
}
private void endButton4() {
timer4.stop();
button4.setBackground(null);
System.out.println("Long Thread Ends == startButton4()");
executor.execute(new ExecutorAndSwingWorker2.MyTask("startButton1")); // non on EDT
}
private class MyTask extends SwingWorker<Void, Integer> {
private String str;
private String namePr;
private JDialog dialog = new JDialog();
MyTask(String str) {
this.str = str;
addPropertyChangeListener(new SwingWorkerCompletionWaiter(dialog, str, namePr));
}
@Override
protected Void doInBackground() throws Exception {
if (str.equals("startButton1")) {
colorAction1();
startButton1();
} else if (str.equals("startButton2")) {
colorAction2();
startButton2();
} else if (str.equals("startButton3")) {
colorAction3();
startButton3();
} else if (str.equals("startButton4")) {
colorAction4();
startButton4();
}
return null;
}
@Override
protected void process(List<Integer> progress) {
System.out.println(str + " " + progress.get(progress.size() - 1));
}
@Override
protected void done() {
if (str.equals("startButton1")) {
endButton1();
} else if (str.equals("startButton2")) {
endButton2();
} else if (str.equals("startButton3")) {
endButton3();
} else if (str.equals("startButton4")) {
endButton4();
}
}
}
private class SwingWorkerCompletionWaiter implements PropertyChangeListener {
private JDialog dialog;
private String str;
private String namePr;
SwingWorkerCompletionWaiter(JDialog dialog, String str, String namePr) {
this.dialog = dialog;
this.str = str;
this.namePr = namePr;
}
@Override
public void propertyChange(PropertyChangeEvent event) {
if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) {
System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue());
} else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.PENDING == event.getNewValue()) {
System.out.println("Thread Status with Mame :" + str + ", SwingWorker Status is " + event.getNewValue());
} else if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.STARTED == event.getNewValue()) {
System.out.println("Thread Status with Name :" + str + ", SwingWorker Status is " + event.getNewValue());
} else {
System.out.println("Thread Status with Name :" + str + ", Something wrong happends ");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ExecutorAndSwingWorker2 executorAndSwingWorker = new ExecutorAndSwingWorker2();
}
});
}
}
使用PropertyChangeListener的输出
Starting long Thread == startButton1()
Thread Status with Name :startButton1, SwingWorker Status is STARTED
Long Thread Ends == startButton1()
Thread Status with Name :startButton1, SwingWorker Status is DONE
Starting long Thread == startButton3()
Thread Status with Name :startButton3, SwingWorker Status is STARTED
Long Thread Ends == startButton3()
Thread Status with Name :startButton3, SwingWorker Status is DONE
Starting long Thread == startButton2()
Starting long Thread == startButton4()
Thread Status with Name :startButton2, SwingWorker Status is STARTED
Thread Status with Name :startButton4, SwingWorker Status is STARTED
Long Thread Ends == startButton2()
Thread Status with Name :startButton2, SwingWorker Status is DONE
Long Thread Ends == startButton4()
Thread Status with Name :startButton4, SwingWorker Status is DONE
Starting long Thread == startButton1()
Thread Status with Name :startButton1, SwingWorker Status is STARTED
Long Thread Ends == startButton1()
Thread Status with Name :startButton1, SwingWorker Status is DONE
Starting long Thread == startButton3()
Thread Status with Name :startButton3, SwingWorker Status is STARTED
Long Thread Ends == startButton3()
Starting long Thread == startButton2()
Thread Status with Name :startButton3, SwingWorker Status is DONE
Starting long Thread == startButton4()
Thread Status with Name :startButton2, SwingWorker Status is STARTED
Thread Status with Name :startButton4, SwingWorker Status is STARTED
Long Thread Ends == startButton2()
Thread Status with Name :startButton2, SwingWorker Status is DONE
BUILD SUCCESSFUL (total time: 1 minute 34 seconds)
答案 2 :(得分:2)
Memory Consistency Properties总结了JLS:&#34;线程中的每个动作都发生在该线程中的每个动作之前,该动作在程序的后续命令中出现。&# 34;只需将每个工作人员doInBackground()
重新分配到一个单独的方法中,然后按顺序调用每个方法:
@Override
protected Void doInBackground() throws Exception {
doCsw1();
doCsw2();
doCsw3();
return null;
}
答案 3 :(得分:2)
如何使用Executors.newSingleThreadExecutor()
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import java.util.concurrent.*;
import javax.swing.*;
public class SingleThreadExecutorTest {
private Executor executor;
private final Box box = Box.createVerticalBox();
public JComponent makeUI() {
executor = Executors.newSingleThreadExecutor(); //.newCachedThreadPool();
box.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
JPanel p = new JPanel(new BorderLayout());
p.add(new JButton(new AbstractAction("add") {
@Override public void actionPerformed(ActionEvent evt) {
doSomethingUseful();
}
}), BorderLayout.SOUTH);
p.add(new JScrollPane(box));
return p;
}
private void doSomethingUseful() {
JProgressBar bar = new JProgressBar(0, 100);
box.add(bar); box.add(Box.createVerticalStrut(8));
box.revalidate();
SwingWorker<Integer, Void> worker = new SwingWorker<Integer, Void>() {
private int sleepDummy = new Random().nextInt(50) + 1;
private int lengthOfTask = 120;
@Override protected Integer doInBackground() {
int current = 0;
while(current<lengthOfTask && !isCancelled()) {
current++;
try {
Thread.sleep(sleepDummy);
} catch(InterruptedException ie) {
break;
}
setProgress(100 * current / lengthOfTask);
}
return sleepDummy*lengthOfTask;
}
@Override protected void done() {
try {
System.out.println(get()+"ms");
} catch(Exception ignore) {
ignore.printStackTrace();
}
}
};
worker.addPropertyChangeListener(new ProgressListener(bar));
executor.execute(worker);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new SingleThreadExecutorTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class ProgressListener implements PropertyChangeListener {
private final JProgressBar progressBar;
ProgressListener(JProgressBar progressBar) {
this.progressBar = progressBar;
this.progressBar.setValue(0);
}
@Override public void propertyChange(PropertyChangeEvent evt) {
String strPropertyName = evt.getPropertyName();
if("progress".equals(strPropertyName)) {
progressBar.setIndeterminate(false);
int progress = (Integer)evt.getNewValue();
progressBar.setValue(progress);
}
}
}