等待多个Swingworker 请考虑下面的代码片段: 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(); } } } 导入java.awt.FlowLayout; 导入java.awt.event.ActionEvent; 导入java.awt.event.ActionListener; 导入java.lang.reflect.InvocationTargetException; 导入javax.swing.*; 公共类TestApplet扩展了JApplet { @凌驾 公共void init() { 尝试 { SwingUtilities.invokeAndWait(新的Runnable() { @凌驾 公开募捐 { createGUI(); } }); } 捕获(InterruptedException | InvocationTargetException ex) { } } 私有void createGUI() { getContentPane().setLayout(新的FlowLayout()); JButton startButton=新JButton(“执行工作”); addActionListener(新ActionListener()) { @凌驾 已执行的公共无效行动(行动事件ae) { JLabel标签=新的JLabel(); 新工作者(标签).execute(); } }); getContentPane().add(开始按钮); } 私有类Worker扩展SwingWorker { JLabel标签; 公共工作者(JLabel标签) { this.label=标签; } @凌驾 受保护的Void doInBackground()引发异常 { //工作 返回null; } @凌驾 受保护的void done() { getContentPane()。删除(标签); getContentPane().revalidate(); } } }
下面是向小程序添加标签,该标签显示工作线程的一些中间结果(使用发布/处理方法)。最后,标签将从小程序的窗格中删除。我的问题是,如何创建多个标签,每个标签都有自己的工作线程,并在全部完成后删除它们 提前谢谢 更新: 我希望这能澄清我的问题。我希望在所有工人完成任务时,而不是在每个工人完成任务后立即删除所有标签 更新2: 下面的代码似乎正在执行我需要的操作。请评论我的做法是否正确。我感觉有点不对劲。一个问题是,尽管按钮右侧的标签已移除,但它们仍然可见。setVisible(false)似乎解决了这个问题。这样做吗等待多个Swingworker 请考虑下面的代码片段: 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(); } } } 导入java.awt.FlowLayout; 导入java.awt.event.ActionEvent; 导入java.awt.event.ActionListener; 导入java.lang.reflect.InvocationTargetException; 导入javax.swing.*; 公共类TestApplet扩展了JApplet { @凌驾 公共void init() { 尝试 { SwingUtilities.invokeAndWait(新的Runnable() { @凌驾 公开募捐 { createGUI(); } }); } 捕获(InterruptedException | InvocationTargetException ex) { } } 私有void createGUI() { getContentPane().setLayout(新的FlowLayout()); JButton startButton=新JButton(“执行工作”); addActionListener(新ActionListener()) { @凌驾 已执行的公共无效行动(行动事件ae) { JLabel标签=新的JLabel(); 新工作者(标签).execute(); } }); getContentPane().add(开始按钮); } 私有类Worker扩展SwingWorker { JLabel标签; 公共工作者(JLabel标签) { this.label=标签; } @凌驾 受保护的Void doInBackground()引发异常 { //工作 返回null; } @凌驾 受保护的void done() { getContentPane()。删除(标签); getContentPane().revalidate(); } } },java,multithreading,swing,wait,swingworker,Java,Multithreading,Swing,Wait,Swingworker,下面是向小程序添加标签,该标签显示工作线程的一些中间结果(使用发布/处理方法)。最后,标签将从小程序的窗格中删除。我的问题是,如何创建多个标签,每个标签都有自己的工作线程,并在全部完成后删除它们 提前谢谢 更新: 我希望这能澄清我的问题。我希望在所有工人完成任务时,而不是在每个工人完成任务后立即删除所有标签 更新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();
}
}
}
}
导入java.awt.FlowLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.lang.reflect.InvocationTargetException;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.Queue;
导入java.util.Random;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入javax.swing.*;
公共类TestApplet扩展了JApplet
{
专用队列标签=新建LinkedList();
私有静态最终随机兰德=新随机();
@凌驾
公共void init()
{
尝试
{
SwingUtilities.invokeAndWait(新的Runnable()
{
@凌驾
公开募捐
{
createGUI();
}
});
}
catch(InterruptedException | InvocationTargetException ex){}
}
私有void createGUI()
{
getContentPane().setLayout(新的FlowLayout());
JButton startButton=新JButton(“执行工作”);
addActionListener(新ActionListener())
{
@凌驾
已执行的公共无效行动(行动事件ae)
{
ExecutorService executor=Executors.newFixedThreadPool(10);
对于(int i=0;i<10;i++)
{
JLabel标签=新的JLabel();
getContentPane().add(标签);
执行人执行(新计数器(标签));
}
}
});
getContentPane().add(开始按钮);
}
私有类计数器扩展SwingWorker
{
私人标签;
公共计数器(JLabel标签)
{
this.label=标签;
}
@凌驾
受保护的Void doInBackground()引发异常
{
对于(int i=1;i,您的代码已经在一定程度上完成了这项工作。单击按钮时,您需要实际将标签添加到contentpane中。如下所示:
JLabel label = new JLabel();
getContentPane().add(label);
getContentPane().validate();
new Worker(label).execute();
在标签中添加一些文本可能是一个好主意,这样当它添加到屏幕上时,您就可以看到它了
JLabel label = new JLabel("Hello...I am here");
最后,在doInBackground()方法中,您可以添加一些代码,以便在某些任务运行时更新标签:
for(int i = 0;i < 100; i++){
Thread.sleep(20);
label.setText("Counting..." + i);
}
for(int i=0;i<100;i++){
睡眠(20);
label.setText(“计数…”+i);
}
通过这种方式,您实际上可以看到任务正在运行。如果您多次单击该按钮,您将看到多个标签,并且它们在任务完成后都会消失
我打算在所有工人完成任务后,一起移除所有标签
如上所述,CountDownLatch
在这种情况下工作得很好。在下面的示例中,每个工作人员在完成时调用latch.countDown()
,而Supervisor
工作人员在latch.await()上阻塞直到所有任务完成。出于演示的目的,<代码>管理器< /代码>更新标签。在注释中显示的批量删除在技术上是可能的,但通常不吸引人。相反,请考虑<代码> JList< /COD>或<代码> JTAB< <代码> >
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();
}
}
}
导入java.awt.Color;
导入java.awt.EventQueue;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.util.LinkedList;
导入java.util.List;
导入java.util.Queue;
导入java.util.Random;
导入java.util.concurrent.CountDownLatch;
导入java.util.concurre