如何与两个(2)Java中的SwingWorker类共享数据 [英] How to share data with two(2) SwingWorker class in Java

查看:203
本文介绍了如何与两个(2)Java中的SwingWorker类共享数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个SwingWorker类:​​ FileLineCounterThread FileDivisionThread

I have two SwingWorker class: FileLineCounterThread and FileDivisionThread

我将执行这两个线程。当线计数线程完成时,它会将结果传递给文件分割线程。

I will execute the two threads. When the lines counting thread finishes, it will pass the result to File Division thread.

我不知道如何将结果传递给开始的线程。 p>

I do not have an idea on how to pass the result to started thread.

推荐答案

SwingWorker.execute() buggy ,并且只会顺序执行任务。对于并发使用 ExecutorService.execute()

SwingWorker.execute() is buggy and will only execute tasks serially. Use ExecutorService.execute() for concurrency:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RunnableFuture;

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

public class MyFrame extends JFrame implements ActionListener {

    /**
     * Test Driver
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MyFrame frame = new MyFrame("Swing Concurrency Test");
                frame.setVisible(true);
            }
        });
    }

    /**
     * Thread Executor
     * (must be explicitly shutdown, see WindowAdapter below)
     */
    private final ExecutorService exec = Executors.newFixedThreadPool(2);

    /**
     * Button action
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        button.setEnabled(false);
        textArea.append("\nStarting both tasks...\n");

        // start both tasks, pass a reference to outer task
        FileLineCounterThread counterTask = new FileLineCounterThread();
        exec.execute(counterTask);
        FileDivisionThread divisionTask = new FileDivisionThread(counterTask);
        exec.execute(divisionTask);
    }

    /**
     * Counter task
     */
    private class FileLineCounterThread extends SwingWorker<Long, String> {
        private String template = "[FileLineCounterThread] %s\n";

        @Override
        protected Long doInBackground() throws Exception {
            // do some work
            publish("started...");
            Thread.sleep(10000);

            // return the result
            return 42L;
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(
                        template, "complete.  Counted: " + get()));
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /**
     * File Division task 
     */
    private class FileDivisionThread extends SwingWorker<String, String> {
        private RunnableFuture<Long> counterTask;
        private String template = "    [FileDivisionThread] %s\n";

        public FileDivisionThread(RunnableFuture<Long> counterTask) {
            this.counterTask = counterTask;
        }

        @Override
        protected String doInBackground() throws Exception {
            // do some initial work
            publish("started...");
            Thread.sleep(2000);

            // wait for other task to complete and get result
            publish("Waiting for line counter to finish...");
            long numLines = counterTask.get(); 
            publish("Line count received: " + numLines);

            // do the rest of the work and return result
            Thread.sleep(5000);
            return "complete.";
        }

        @Override
        protected void process(List<String> chunks) {
            for (String chunk : chunks) {
                textArea.append(String.format(template, chunk));
            }
        }

        @Override
        protected void done() {
            try {
                textArea.append(String.format(template, get()));
                button.setEnabled(true);
            }
            catch (Exception e) {
                // catch any exceptions thrown during execution
                e.printStackTrace();
            }
        }
    }

    /////////////////////////
    //// GUI Boilerplate ////
    /////////////////////////

    private JScrollPane scroller = new JScrollPane();
    private JTextArea textArea = new JTextArea();
    private JButton button = new JButton("Start");

    public MyFrame(String windowTitle) {
        super(windowTitle);
        initComponents();
    }

    private void initComponents() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                exec.shutdownNow();
                System.exit(0);
            }
        });
        button = new JButton("Start");
        button.addActionListener(this);
        textArea = new JTextArea();
        textArea.setColumns(35);
        textArea.setRows(15);
        scroller.setViewportView(textArea);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new GridBagLayout());

        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new Insets(10, 0, 0, 0);
        getContentPane().add(button, gridBagConstraints);

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new Insets(10, 10, 10, 10);
        getContentPane().add(scroller, gridBagConstraints);

        pack();
    }
}

这篇关于如何与两个(2)Java中的SwingWorker类共享数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆