SwingWorker

SwingWorker

App.java:
import javax.swing.SwingUtilities;


public class App {

    /**
     * @param args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            
            @Override
            public void run() {
                new MainFrame("SwingWorker Demo");
            }
        });
    }

}
MainFrame.java:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.concurrent.ExecutionException;

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

public class MainFrame extends JFrame {

    private JLabel countLabel1 = new JLabel("0");
    private JLabel statusLabel = new JLabel("Task not completed.");
    private JButton startButton = new JButton("Start");

    public MainFrame(String title) {
        super(title);

        setLayout(new GridBagLayout());

        GridBagConstraints gc = new GridBagConstraints();

        gc.fill = GridBagConstraints.NONE;

        gc.gridx = 0;
        gc.gridy = 0;
        gc.weightx = 1;
        gc.weighty = 1;
        add(countLabel1, gc);

        gc.gridx = 0;
        gc.gridy = 1;
        gc.weightx = 1;
        gc.weighty = 1;
        add(statusLabel, gc);

        gc.gridx = 0;
        gc.gridy = 2;
        gc.weightx = 1;
        gc.weighty = 1;
        add(startButton, gc);

        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                start();
            }
        });

        setSize(200, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);
    }

    private void start() {
        
        // Use SwingWorker and return null from doInBackground if
        // you don't want any final result and you don't want to update the GUI
        // as the thread goes along.
        // First argument is the thread result, returned when processing finished.
        // Second argument is the value to update the GUI with via publish() and process()
        SwingWorker worker = new SwingWorker() {

            @Override
            /*
             * Note: do not update the GUI from within doInBackground.
             */
            protected Boolean doInBackground() throws Exception {
                
                // Simulate useful work
                for(int i=0; i<30; i++) {
                    Thread.sleep(100);
                    System.out.println("Hello: " + i);
                    
                    // optional: use publish to send values to process(), which
                    // you can then use to update the GUI.
                    publish(i);
                }
                
                return false;
            }

            @Override
            // This will be called if you call publish() from doInBackground()
            // Can safely update the GUI here.
            protected void process(List chunks) {
                Integer value = chunks.get(chunks.size() - 1);
                
                countLabel1.setText("Current value: " + value);
            }

            @Override
            // This is called when the thread finishes.
            // Can safely update GUI here.
            protected void done() {
                
                try {
                    Boolean status = get();
                    statusLabel.setText("Completed with status: " + status);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
            }
            
        };
        
        worker.execute();
    }
}

SwingWorker的第一个template argument:doInBackground方法的返回类型,get方法的返回值类型

template argument中只能用Void(void对应的类)。如果用Void,doInBackground方法必须返回null。

template argument中只能用class,不能用primitive type。

SwingWorker的第二个template argument:publish方法的参数类型,process方法参数List的泛型类型。如果要再doInBackground方法执行的同时,update GUI,在doInBackground方法中调用publish方法,然后override process方法。

process方法的参数是一个List<第二个template argument>,因为并不是每一次在doInBackground方法中调用publish的时候process方法都会被调用。这个List保存了每次publish的内容。在process方法中,可以update GUI safely。process方法在EDT中被调度。

每一个SwingWorker对象只能execute一次,如果需要再执行一遍,只能再创建一个对象。

doInBackground方法中update GUI不安全。doInBackground方法可以throw exception。在done方法中可以catch。

done方法在这个thread结束的时候会被执行,done方法中可以update GUI safely。

get方法得到doInBackground方法的返回值,如果doInBackground还没有执行完,get方法wait。



你可能感兴趣的:(Java)