Wednesday, December 25, 2013

JProgressBar and java.util.Timer/java.util.TimerTask

JProgressBar and Timer
JProgressBar with Timer

package javatask;

import java.awt.BorderLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Timer;
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 static javax.swing.SwingConstants.HORIZONTAL;
import javax.swing.SwingUtilities;

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

    Label labelInfo;
    JButton buttonRun;
    JProgressBar jProgressBar1;
    
    Timer 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));

        jProgressBar1 = new JProgressBar(HORIZONTAL, 0, 10);
        vPanel.add(jProgressBar1);
        
        labelInfo = new Label();
        vPanel.add(labelInfo);

        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) {
            labelInfo.setText("Run button click");

            if(timer != null){
                timer.cancel();
            }
            
            timer = new Timer(); 
            TimerTask timeTask = new TimerTask() {
                
                private int progress = 0;
                private final int max_progress = 10;

                @Override
                public void run() {
                    if(progress == max_progress){
                        timer.cancel();
                        labelInfo.setText("Finished");
                    }else{
                        progress++;
                        labelInfo.setText("progress: " + getProgress());
                        jProgressBar1.setValue(getProgress());
                    }
                }
                
                int getProgress(){
                    return progress;
                }

            };
                       
            timer.schedule(timeTask, 1000, 1000);
        }
    }
}



Remark: In this example, the ui elements are updated in TimerTask run on non-ui thread. If you want to update ui inside, you shoulad using javax.swing.Timer. Read next post: java.util.Timer and javax.swing.Timer.
~ thanks comment by Tomtom.

2 comments:

  1. You should stay with the event-dispatching thread if you want to update Swing components. So you should use a javax.swing.Timer

    ReplyDelete