java – 等待多个SwingWorkers
|
请考虑以下代码片段: import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class TestApplet extends JApplet
{
@Override
public void init()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex)
{
}
}
private void createGUI()
{
getContentPane().setLayout(new FlowLayout());
JButton startButton = new JButton("Do work");
startButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
JLabel label = new JLabel();
new Worker(label).execute();
}
});
getContentPane().add(startButton);
}
private class Worker extends SwingWorker<Void,Void>
{
JLabel label;
public Worker(JLabel label)
{
this.label = label;
}
@Override
protected Void doInBackground() throws Exception
{
// do work
return null;
}
@Override
protected void done()
{
getContentPane().remove(label);
getContentPane().revalidate();
}
}
}
这是向applet添加一个标签,显示Worker线程的一些中间结果(使用publish / process方法).最后,标签从小应用程序的窗格中删除.我的问题是,我如何创建几个标签,每个标签都有自己的工作线程,并在完成后删除它们? 提前致谢. 更新: 我希望这将澄清我的问题.当所有的工作人员都完成了任务,而不是在每个工作人员完成后立即将标签全部删除. 更新2: 以下代码似乎正在做我需要的.请评论我是否做了正确的方法.我有一种感觉有什么问题.一个问题是,除去删除按钮之后,按钮右侧的标签仍然可见. setVisible(false)似乎解决了这个问题.是这样做吗? import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.*;
public class TestApplet extends JApplet
{
private Queue<JLabel> labels = new LinkedList<>();
private static final Random rand = new Random();
@Override
public void init()
{
try
{
SwingUtilities.invokeAndWait(new Runnable()
{
@Override
public void run()
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex){}
}
private void createGUI()
{
getContentPane().setLayout(new FlowLayout());
JButton startButton = new JButton("Do work");
startButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
ExecutorService executor = Executors.newFixedThreadPool(10);
for(int i = 0; i < 10; i++)
{
JLabel label = new JLabel();
getContentPane().add(label);
executor.execute(new Counter(label));
}
}
});
getContentPane().add(startButton);
}
private class Counter extends SwingWorker<Void,Integer>
{
private JLabel label;
public Counter(JLabel label)
{
this.label = label;
}
@Override
protected Void doInBackground() throws Exception
{
for(int i = 1; i <= 100; i++)
{
publish(i);
Thread.sleep(rand.nextInt(80));
}
return null;
}
@Override
protected void process(List<Integer> values)
{
label.setText(values.get(values.size() - 1).toString());
}
@Override
protected void done()
{
labels.add(label);
if(labels.size() == 10)
{
while(!labels.isEmpty())
getContentPane().remove(labels.poll());
getContentPane().revalidate();
}
}
}
}
解决方法
如here所述,CountDownLatch在此上下文中工作良好.在下面的示例中,每个工作人员在完成时调用latch.countDown(),并且Supervisor工作程序阻塞latch.await(),直到所有任务完成.为了演示目的,主管更新标签.批评删除,在评论中显示,在技术上是可能的,但通常没有吸引力.相反,请考虑一个JList或JTable. import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.*;
/**
* @see https://stackoverflow.com/a/11372932/230513
* @see https://stackoverflow.com/a/3588523/230513
*/
public class WorkerLatchTest extends JApplet {
private static final int N = 8;
private static final Random rand = new Random();
private Queue<JLabel> labels = new LinkedList<JLabel>();
private JPanel panel = new JPanel(new GridLayout(0,1));
private JButton startButton = new JButton(new StartAction("Do work"));
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setTitle("Test");
frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new WorkerLatchTest().createGUI());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
@Override
public void init() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
add(new WorkerLatchTest().createGUI());
}
});
}
private JPanel createGUI() {
for (int i = 0; i < N; i++) {
JLabel label = new JLabel("0",JLabel.CENTER);
label.setOpaque(true);
panel.add(label);
labels.add(label);
}
panel.add(startButton);
return panel;
}
private class StartAction extends AbstractAction {
private StartAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
startButton.setEnabled(false);
CountDownLatch latch = new CountDownLatch(N);
ExecutorService executor = Executors.newFixedThreadPool(N);
for (JLabel label : labels) {
label.setBackground(Color.white);
executor.execute(new Counter(label,latch));
}
new Supervisor(latch).execute();
}
}
private class Supervisor extends SwingWorker<Void,Void> {
CountDownLatch latch;
public Supervisor(CountDownLatch latch) {
this.latch = latch;
}
@Override
protected Void doInBackground() throws Exception {
latch.await();
return null;
}
@Override
protected void done() {
for (JLabel label : labels) {
label.setText("Fin!");
label.setBackground(Color.lightGray);
}
startButton.setEnabled(true);
//panel.removeAll(); panel.revalidate(); panel.repaint();
}
}
private static class Counter extends SwingWorker<Void,Integer> {
private JLabel label;
CountDownLatch latch;
public Counter(JLabel label,CountDownLatch latch) {
this.label = label;
this.latch = latch;
}
@Override
protected Void doInBackground() throws Exception {
int latency = rand.nextInt(42) + 10;
for (int i = 1; i <= 100; i++) {
publish(i);
Thread.sleep(latency);
}
return null;
}
@Override
protected void process(List<Integer> values) {
label.setText(values.get(values.size() - 1).toString());
}
@Override
protected void done() {
label.setBackground(Color.green);
latch.countDown();
}
}
} (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
