SwingWorker在另一个SwingWorker的done方法中

时间:2014-04-17 05:58:01

标签: java swing jframe swingworker

首先,我需要通知您,我正努力学习如何用Java编写代码。它有点困难,但是,我相信我拥有它。我过去曾就SwingWorkers等提交了一些问题。其中每一个我都认为我拥有它,但后来发现我还在学习。希望这次,不是其中一次。

话虽如此,请告诉我您认为不符合标准的任何内容,或者可能导致将来出现问题。


现在提出问题!

我构建了一个JFrame,在允许用户进入另一个页面,按下按钮或其他任何内容之前,它会加载一些东西。加载数据后,它将解锁JFrame以允许用户与数据交互。

问题是,(这不是一个真正的问题,只是一个澄清)我需要执行另一个任务,而用户可以这样的方式与JFrame交互它不会打扰他们,但是,将更新JFrame基于它找到的结果。一个例子可能是版本检查。根据版本是否过期,通知用户。


示例Sudo代码

protected void startJFrame() {
    JFrame myFrame = new JFrame();//Starts with disable/invisible components. Preventing the user from doing to much before allowed.
    SwingWorker<Void, Progress> loadingWorker = new SwingWorker<Void, Progress>() {
        @Override
        protected Void doInBackground() throws Exception {
            publish(new Progress(0,"Loading This"));      // Set Percent
            loadingTasks.loadThis();                         // Do Work!!
            publish(new Progress(25,"Loading That"));     // Set Percent
            loadingTasks.loadThat();                         // Do Work!!
            publish(new Progress(50,"Loading More"));     // Set Percent
            loadingTasks.loadMore();                         // Do Work!!
            publish(new Progress(75,"Loading Last"));     // Set Percent
            loadingTasks.loadLast();                         // Do Work!!
            publish(new Progress(100,"Loading Complete"));// Set Percent
            return null;
        }
        @Override
        protected void process(List<Progress> ProgressList) {
            for (Progress p : ProgressList) {
                System.out.println(p.getInt() + "% " + p.getString()); //Show user percent and what its doing.
            }
        }
        @Override
        protected void done() {
            try {
                get();
                loadingTasks.WrapUp();//Set Variables or other small stuff.
                myFrame.userAllowed();//Lets the user interact with the whole JFrame.
                SwingWorker<Void, Void> secondWorker = new SwingWorker<Void, Void>() {
                    @Override
                    protected Void doInBackground() throws Exception {
                        versionCheck.makeItSo();// Do Work!!
                        return null;
                    }
                    @Override
                    protected void done() {
                        try {
                            get();
                            versionCheck.wrapUp();//Set Variables or other small stuff.
                            myFrame.showLabel();//Show a label with specific info.
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                    }
                };
                secondWorker.execute();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    };
    loadingWorker.execute();
}

涉及此代码的主题问题。

我担心创建许多对象而不是处理它们,只是为了传递多个变量。特别是在第一个doInBackground方法中创建的 Progress 对象。

这样做是否可以?它会自动自动处理Progress Objects吗?如果没有,在我完成它们之后我将如何处理它们?

1 个答案:

答案 0 :(得分:3)

SwingWorker支持PropertyChange个事件,也就是说,您可以在SwingWorker更改状态或更新其进度时监听...是的,SwingWorker甚至支持进度通知,例如

这意味着您可以设置PropertyChangeListener来监控progressstate属性的更改并采取相应的措施......

简单设置进度更新的工作人员......

public class LoadMaster extends SwingWorker<Void, Progress> {

    @Override
    protected Void doInBackground() throws Exception {
        System.out.println("Working hard here, nothing to see...");
        for (int index = 0; index < 100; index++) {
            Thread.sleep(10);
            setProgress(index);
        }
        return null;
    }

    @Override
    protected void done() {
        try {
            get();
        } catch (Exception e) {
        }
    }

}

示例PropertyChangeListener ...

public class LoadMasterPropertyChanegHandler implements PropertyChangeListener {

    private SwingWorkerExample example;

    public LoadMasterPropertyChanegHandler(SwingWorkerExample example) {
        this.example = example;
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        System.out.println(evt.getPropertyName());
        if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
            int value = (int) evt.getNewValue();
            example.showProgress(value);
        } else if ("state".equalsIgnoreCase(evt.getPropertyName())) {
            SwingWorker worker = (SwingWorker) evt.getSource();
            if (worker.isDone()) {
                try {
                    worker.get();
                    example.loadCompleted();
                } catch (InterruptedException | ExecutionException exp) {
                    example.loadFailed();
                }
            }
        }
    }

}

现在,所有这一切都是将信息发送回SwingWorkerExample(它即将到来),这样就可以确定它应该做什么......

在此示例中,loadCompleted方法更新UI,然后启动第二个工作程序...

protected void loadCompleted() {
    //...
    LoadStuffWorker stuffWorker = new LoadStuffWorker(this);
    stuffWorker.execute();
}

事实上,我可能会使用界面,所以我不会公开地暴露课程,但那是另一天的话题......

完整的例子......

Worker

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class SwingWorkerExample {

    private JProgressBar pb;
    private JPanel content;

    public static void main(String[] args) {

        new SwingWorkerExample();

    }

    public SwingWorkerExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                pb = new JProgressBar();
                content = new JPanel();
                content.setBorder(new EmptyBorder(10, 10, 10, 10));

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(content);
                frame.setLayout(new GridBagLayout());
                frame.add(pb);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                LoadMaster master = new LoadMaster();
                master.addPropertyChangeListener(new LoadMasterPropertyChanegHandler(SwingWorkerExample.this));
                master.execute();
            }
        });
    }

    protected void showProgress(int value) {
        pb.setValue(value);
    }

    protected void loadCompleted() {
        content.removeAll();
        content.setLayout(new GridLayout(0, 1));
        content.add(new JLabel("All your base are belong to us"));
        content.revalidate();

        LoadStuffWorker stuffWorker = new LoadStuffWorker(this);
        stuffWorker.execute();
    }

    protected void loadFailed() {
        content.removeAll();
        content.setLayout(new GridLayout(0, 1));
        content.add(new JLabel("Fail"));
        content.revalidate();
    }

    protected void setVersion(String value) {
        content.add(new JLabel("Version: " + value));
        content.revalidate();
    }

    protected void failed(String fail) {
        content.add(new JLabel(fail));
        content.revalidate();
    }

    public class LoadMaster extends SwingWorker<Void, Progress> {

        @Override
        protected Void doInBackground() throws Exception {
            System.out.println("Working hard here, nothing to see...");
            for (int index = 0; index < 100; index++) {
                Thread.sleep(10);
                setProgress(index);
            }
            return null;
        }

        @Override
        protected void done() {
            try {
                get();
            } catch (Exception e) {
            }
        }

    }

    public class LoadStuffWorker extends SwingWorker<String, Void> {

        private SwingWorkerExample example;

        public LoadStuffWorker(SwingWorkerExample example) {
            this.example = example;
        }

        @Override
        protected String doInBackground() throws Exception {
            System.out.println("Hanging about in the background");
            Thread.sleep(3000);
            return "Hello from the dark side";
        }

        @Override
        protected void done() {
            try {
                String value = get();
                example.setVersion(value);
            } catch (InterruptedException | ExecutionException ex) {
                example.failed("Fail while doing version check");
            }
        }

    }

    public class Progress {
    }

    public class LoadMasterPropertyChanegHandler implements PropertyChangeListener {

        private SwingWorkerExample example;

        public LoadMasterPropertyChanegHandler(SwingWorkerExample example) {
            this.example = example;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            System.out.println(evt.getPropertyName());
            if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                int value = (int) evt.getNewValue();
                example.showProgress(value);
            } else if ("state".equalsIgnoreCase(evt.getPropertyName())) {
                SwingWorker worker = (SwingWorker) evt.getSource();
                if (worker.isDone()) {
                    try {
                        worker.get();
                        example.loadCompleted();
                    } catch (InterruptedException | ExecutionException exp) {
                        example.loadFailed();
                    }
                }
            }
        }

    }

}