Java – wait for multiple swingworkers

Consider the following code snippet:

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();
        }
    }
}

This is to add a tag to the applet to display some intermediate results of the worker thread (using the publish / process method) Finally, the tag is removed from the pane of the applet My question is, how do I create several tags, each with its own worker thread, and delete them when I finish?

Thank you in advance

to update:

I hope this will clarify my question When all the staff have finished the task, instead of deleting all the tags immediately after each staff has finished

Update 2:

The following code seems to be doing what I need Please comment on whether I have done the right way I have a feeling that there is something wrong One problem is that after removing the delete button, the label on the right side of the button is still visible Setvisible (false) seems to solve this problem Is that it?

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();
            }
        }
    }
}

Solution

As described here, countdownlatch works well in this context In the following example, each worker calls latch. When finished Countdown(), and the supervisor worker blocks latch Await() until all tasks are completed For demonstration purposes, the supervisor updates the label Critical deletion, as shown in the comments, is technically possible but usually unattractive Instead, consider a JList or 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();
        }
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>