Friday, December 27, 2013

java.util.Timer and javax.swing.Timer

Both java.util.Timer and javax.swing.Timer provide the same basic functionality, but java.util.Timer is more general and has more features. The javax.swing.Timer has two features that can make it a little easier to use with GUIs. First, its event handling metaphor is familiar to GUI programmers and can make dealing with the event-dispatching thread a bit simpler. Second, its automatic thread sharing means that you don't have to take special steps to avoid spawning too many threads. Instead, your timer uses the same thread used to make cursors blink, tool tips appear, and so on. 
~ source: http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

Last post show "JProgressBar and java.util.Timer/java.util.TimerTask run on non-ui thread". In this post, I will apply java.util.Timer (the top group), invoke code later in ui thread from non-ui thread (the middle group) and javax.swing.Timer (the bottom group).

java.util.Timer and javax.swing.Timer
java.util.Timer and javax.swing.Timer

package javatask;

import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSeparator;
import javax.swing.SwingConstants;
import static javax.swing.SwingConstants.HORIZONTAL;
import javax.swing.SwingUtilities;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaTask extends JFrame
        implements ActionListener {

    Label labelInfo1, labelInfo2, labelInfo3;
    Label labelThread1, labelThread2, labelThread3;
    JProgressBar jProgressBar1, jProgressBar2, jProgressBar3;
    JButton buttonRun;

    java.util.Timer java_util_Timer;
    javax.swing.Timer javax_swing_Timer;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGUI();
        });
    }

    private static void createAndShowGUI() {
        JavaTask myTaskFrame = new JavaTask();
        myTaskFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myTaskFrame.prepareUI();
        myTaskFrame.pack();
        myTaskFrame.setVisible(true);

    }

    private void prepareUI() {

        JPanel vPanel = new JPanel();
        vPanel.setLayout(new BoxLayout(vPanel, BoxLayout.Y_AXIS));

        Label labelThreadMain = new Label("UI Thread: " + Thread.currentThread());
        vPanel.add(labelThreadMain);
        vPanel.add(new JSeparator(SwingConstants.HORIZONTAL));

        Label labelHeader1 = new Label("java.util.Timer");
        vPanel.add(labelHeader1);
        jProgressBar1 = new JProgressBar(HORIZONTAL, 0, 10);
        vPanel.add(jProgressBar1);
        labelInfo1 = new Label();
        vPanel.add(labelInfo1);
        labelThread1 = new Label();
        vPanel.add(labelThread1);
        vPanel.add(new JSeparator(SwingConstants.HORIZONTAL));

        Label labelHeader2 = new Label("java.util.Timer -> invokeLater");
        vPanel.add(labelHeader2);
        jProgressBar2 = new JProgressBar(HORIZONTAL, 0, 10);
        vPanel.add(jProgressBar2);
        labelInfo2 = new Label();
        vPanel.add(labelInfo2);
        labelThread2 = new Label();
        vPanel.add(labelThread2);
        vPanel.add(new JSeparator(SwingConstants.HORIZONTAL));

        Label labelHeader3 = new Label("javax.swing.Timer");
        vPanel.add(labelHeader3);
        jProgressBar3 = new JProgressBar(HORIZONTAL, 0, 10);
        vPanel.add(jProgressBar3);
        labelInfo3 = new Label();
        vPanel.add(labelInfo3);
        labelThread3 = new Label();
        vPanel.add(labelThread3);
        vPanel.add(new JSeparator(SwingConstants.HORIZONTAL));

        buttonRun = new JButton("Run");
        buttonRun.addActionListener(this);

        getContentPane().add(vPanel, BorderLayout.CENTER);
        getContentPane().add(buttonRun, BorderLayout.PAGE_END);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == buttonRun) {

            if (java_util_Timer != null) {
                java_util_Timer.cancel();
            }
            if (javax_swing_Timer != null) {
                javax_swing_Timer.stop();
            }

            //use java.util.Timer() run in non-ui thread
            java_util_Timer = new java.util.Timer();
            TimerTask timeTask1 = new TimerTask() {

                private int progress = 0;
                private final int max_progress = 10;

                @Override
                public void run() {
                    if (progress == max_progress) {
                        java_util_Timer.cancel();
                        labelInfo1.setText("Finished");

                        SwingUtilities.invokeLater(() -> {
                            //run in ui thread
                            labelInfo2.setText("Finished");
                            labelThread2.setText(Thread.currentThread().toString());
                        });
                    } else {
                        progress++;
                        labelInfo1.setText("progress: " + getProgress());
                        jProgressBar1.setValue(getProgress());

                        SwingUtilities.invokeLater(() -> {
                            //run in ui thread
                            labelInfo2.setText("progress: " + getProgress());
                            jProgressBar2.setValue(getProgress());
                            labelThread2.setText(Thread.currentThread().toString());
                        });
                    }
                    labelThread1.setText(Thread.currentThread().toString());
                }

                int getProgress() {
                    return progress;
                }

            };

            java_util_Timer.schedule(timeTask1, 1000, 1000);

            //javax.swing.Timer run in ui thread
            javax_swing_Timer = new javax.swing.Timer(1000,
                    new ActionListener() {

                        private int progress = 0;
                        private final int max_progress = 10;

                        @Override
                        public void actionPerformed(ActionEvent e) {

                            if (progress == max_progress) {
                                javax_swing_Timer.stop();
                                labelInfo3.setText("Finished");
                            } else {
                                progress++;
                                labelInfo3.setText("progress: " + progress);
                                jProgressBar3.setValue(progress);
                            }
                            labelThread3.setText(Thread.currentThread().toString());
                        }
                    });
            javax_swing_Timer.setInitialDelay(1000);
            javax_swing_Timer.start();

        }
    }

}


No comments:

Post a Comment