Swingworker队列和单一使用

时间:2014-03-14 18:02:19

标签: java swing executorservice swingworker

我有3个摇摆工作者。和4 jButton。

jButton1必须为Swingworkers的排队工作分配。当它点击swingworker必须排队并逐个执行。我知道,我们可以使用执行器。我读了很多关于它的文章,但人们通常从第一个swingworker done()方法调用执行器。我不能这样做,因为;

jButton2,jButton3,jButton4必须分配给swingworkers进行单次执行。我们如何创建这种情况?任何示例模式都很受欢迎。

问候。

--- --- EDIT

MainGui看起来像ss;

MainGui

我所有的Swingworkers都存储在其他课程中;

package trying.project;

import java.awt.Toolkit;
import javax.swing.SwingWorker;

public class WorkersClass {


    public class SW1 extends SwingWorker<Void, Void> {

        protected Void doInBackground() throws Exception {

         //Doing Some DB Jobs Here...

         return null; 
        } 
        public void done() {
         Toolkit.getDefaultToolkit().beep();
        }                      
   }   



    public class SW2 extends SwingWorker<Void, Void> {

    protected Void doInBackground() throws Exception {

     //Doing Some DB Jobs Here...

     return null; 
    } 
    public void done() {
     Toolkit.getDefaultToolkit().beep();
    }                      
  }  



    public class SW3 extends SwingWorker<Void, Void> {

    protected Void doInBackground() throws Exception {

     //Doing Some DB Jobs Here...

     return null; 
    } 
    public void done() {
     Toolkit.getDefaultToolkit().beep();
    }                      
  } 


}

所有SW按钮必须按顺序执行所有的swingworkers并逐个执行。 SW1优先于SW2而不是SW3。

SW 1按钮必须只执行SW1, SW 2按钮必须只执行SW2, SW 3按钮必须仅执行SW3。

3 个答案:

答案 0 :(得分:1)

我已经玩了一段时间用这个问题(如果我已经理解正确的话),这是我发现的最简单的方法。我创建了两个类WorkerManagerQueuableWorker,它们共同完成以下任务:

  • 不能同时执行两个QueuableWorker
  • 工人必须按照他们入队的顺序执行

以下测试应用程序有3个按钮,用于创建不同的工作者。无论你要求执行多快,工人都不会重叠并按顺序执行。控制台中的消息显示工人入队,开始和结束的时间。

要执行queuableWorker,请调用WorkerManager的方法queueExecution(worker),并覆盖QueuableWorker的customDone方法,以便在执行后将自己的代码放入EDT中。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Queue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class QueueSWTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run()
            {
                new QueueSWTest();
            }
        });
    }

    static WorkerManager _workerManager;

    public QueueSWTest()
    {
        _workerManager = new WorkerManager();

        JFrame frame = new JFrame("Frame");

        JButton button1 = new JButton("Queue TestWorker 1");
        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                String workerName = "Worker 1";
                appendMessage("Queued " + workerName);
                TestWorker worker = new TestWorker(workerName);
                _workerManager.queueExecution(worker);
            }
        });

        JButton button2 = new JButton("Queue TestWorker 2");
        button2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                String workerName = "Worker 2";
                appendMessage("Queued " + workerName);
                TestWorker worker = new TestWorker(workerName);
                _workerManager.queueExecution(worker);
            }
        });

        JButton button3 = new JButton("Queue TestWorker 3");
        button3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                String workerName = "Worker 3";
                appendMessage("Queued " + workerName);
                TestWorker worker = new TestWorker(workerName);
                _workerManager.queueExecution(worker);
            }
        });

        JPanel buttonsPanel = new JPanel();
        buttonsPanel.add(button1);
        buttonsPanel.add(button2);
        buttonsPanel.add(button3);
        frame.add(buttonsPanel, BorderLayout.PAGE_END);

        _textArea = new JTextArea("Queue some workers:\n");
        _textArea.setEditable(false);
        frame.add(new JScrollPane(_textArea));

        frame.setSize(600, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static WorkerManager getWorkerManager()
    {
        return _workerManager;
    }

    private abstract class QueuableWorker extends SwingWorker
    {
        @Override
        protected abstract Object doInBackground();

        @Override
        final protected void done()
        {
            customDone();
            QueueSWTest.getWorkerManager().setExecuting(false);
            QueueSWTest.getWorkerManager().executeNext();
        }

        protected abstract void customDone();
    }

    private class TestWorker extends QueuableWorker
    {
        public TestWorker(String name)
        {
            _name = name;
        }

        @Override
        protected Object doInBackground()
        {
            doHardWork();
            return null;
        }

        @Override
        protected void customDone()
        {
            String message = _name + " has finished!";
            appendMessage(message);
        }

        public String getName()
        {
            return _name;
        }

        private void doHardWork()
        {
            try
            {
                Thread.sleep(2000);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }

        String _name;

    }

    private static void appendMessage(String message)
    {
        _textArea.append(message + "\n");
        System.out.println(message);
    }

    class WorkerManager
    {
        volatile Queue<QueuableWorker> _workers;
        volatile boolean _executing;

        public WorkerManager()
        {
            _workers = new LinkedList<QueuableWorker>();
        }

        public synchronized void queueExecution(QueuableWorker worker)
        {
            _workers.add(worker);
            if (!_executing) executeNext();
        }

        public synchronized void executeNext()
        {
            SwingWorker worker = _workers.poll();
            if (worker != null) 
            {
                setExecuting(true);
                appendMessage("WorkerManager: Starting the next worker... (" + _workers.size() +" more queued)");
                worker.execute();
            }
        }

        public void setExecuting(boolean b)
        {
            _executing = b;
        }
    }

    private static JTextArea _textArea;
}

看起来像这样: QueueSwingwokersTest

答案 1 :(得分:0)

完成此任务有数千种方法。哪一个最合适可能取决于上下文。你没有告诉我们很多关于背景的信息。

但是,一种简单的方法是创建一个包含所有必须执行的SwingWorker实例的列表。按下按钮时,将处理列表(此处的列表可能包含SW1,SW2,SW3或[SW1,SW2,SW3] - 或任何其他SwingWorker实例集。)

处理列表意味着:第一个SwingWorker将从列表中删除。它将被执行,当它“完成”时,将处理剩余的列表。这可以通过将一个PropertyChangeListener附加到SwingWorker来轻松实现,该SwingWorker在SwingWorker完成其工作时得到通知。

import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class SwingWorkersExecution
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new GridLayout(1, 0));

        frame.getContentPane().add(createButton("SW1"));
        frame.getContentPane().add(createButton("SW2"));
        frame.getContentPane().add(createButton("SW3"));
        frame.getContentPane().add(createButton("SW1", "SW2", "SW3"));

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static JButton createButton(final String ... names)
    {
        String s = Arrays.toString(names);
        JButton button = new JButton(s);
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                List<SwingWorker<?,?>> swingWorkers = 
                    new ArrayList<SwingWorker<?,?>>();
                for (String name : names)
                {
                    swingWorkers.add(new SW(name));
                }
                execute(swingWorkers);
            }
        });
        return button;
    }

    private static void execute(final List<SwingWorker<?, ?>> swingWorkers)
    {
        if (swingWorkers.size() == 0)
        {
            return;
        }
        System.out.println("Executing first of "+swingWorkers);
        final SwingWorker<?,?> swingWorker = swingWorkers.remove(0);
        PropertyChangeListener propertyChangeListener = new PropertyChangeListener()
        {
            @Override
            public void propertyChange(PropertyChangeEvent event)
            {
                if ("state".equals(event.getPropertyName()))
                {
                    if (SwingWorker.StateValue.DONE == event.getNewValue()) 
                    {
                        swingWorker.removePropertyChangeListener(this);
                        execute(swingWorkers);
                    }
                }
            }
        };
        swingWorker.addPropertyChangeListener(propertyChangeListener);
        swingWorker.execute();
    }


    public static class SW extends SwingWorker<Void, Void>
    {
        private final String name;

        public SW(String name)
        {
            this.name = name;
        }
        @Override
        protected Void doInBackground() throws Exception
        {
            System.out.println(name+" working");
            Thread.sleep(500);
            System.out.println(name+" working DONE");
            return null;
        }
        @Override
        public void done()
        {
            System.out.println(name+" done");
            Toolkit.getDefaultToolkit().beep();
        }

        @Override
        public String toString()
        {
            return name;
        }
    }
}

答案 2 :(得分:0)

此代码应该按您的要求执行:

package trying.project;

import java.awt.Toolkit;
import javax.swing.SwingWorker;

public class WorkersClass {

    public static doSW1Stuff(){
        //Doing Some DB Jobs Here...
    }

    public static doSW2Stuff(){
        //Doing Some DB Jobs Here...
    }

    public static doSW3Stuff(){
        //Doing Some DB Jobs Here...
    }

    public class SW1 extends SwingWorker<Void, Void> {

        protected Void doInBackground() throws Exception {
            doSW1Stuff();
        }
        public void done() {
            Toolkit.getDefaultToolkit().beep();
        }
    }

    public class SW2 extends SwingWorker<Void, Void> {

        protected Void doInBackground() throws Exception {
            doSW2Stuff();
        }
        public void done() {
            Toolkit.getDefaultToolkit().beep();
        }
    }

    public class SW3 extends SwingWorker<Void, Void> {

        protected Void doInBackground() throws Exception {
            doSW3Stuff();
        }
        public void done() {
            Toolkit.getDefaultToolkit().beep();
        }
    }

    public class SWAll extends SwingWorker<Void, Void> {

        protected Void doInBackground() throws Exception {
            doSW1Stuff();
            doSW2Stuff();
            doSW3Stuff();
        }
        public void done() {
            Toolkit.getDefaultToolkit().beep();
        }
    }
}

您也可以删除SwingWorker定义并改为使用Anonymous Classes