请考虑以下代码片段:
- 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();
- }
- }
- }
- }
解决方法
I intend to remove all of the labels together when all of the workers have completed their tasks.
如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();
- }
- }
- }