Java: How to continuously update JLabel which uses atomicInteger to countdown after ActionListener

Go To StackoverFlow.com

2

I was reading different threads on the subject which suggested the Swing Timer class or SwingUtilities.InvokeLater

...but I am having a lot of trouble wrapping my head around them.

I used atomicInteger to create my countdown timer and it works fine in the console. However, When I try to incorporate it in Swing, it only updates the starting and ending value (e.g. set a 5 sec countdown will display in the frame: "5" -> after 5 seconds -> "0".

Is there any simple way for me to keep and "refresh" my atomicInteger countdown label, or the only way is using the Swing Timer class?

Thank you for your patience!

ps. not homework, just trying to make myself a custom timer to study. (ie. procrastinating)

I hope this class is enough, please let me know if you need the frame/panel code as well.

private class ClickListener implements ActionListener{

     public void actionPerformed(ActionEvent e){            
         int t_study = 5;
         atomicDown.set(t_study);

         if (e.getSource() == b_study){
             while(atomicDown.get() > 0){       
                t_study = atomicDown.decrementAndGet(); 
        l_studyTime.setText(Integer.toString(t_study));
             try {
                Thread.sleep(1000);
             }
             catch (InterruptedException e1) {
                 System.out.println("ERROR: Thread.sleep()");   
                 e1.printStackTrace();
             }
          }
     }
     else if(e.getSource() == b_exit){
         System.exit(0); 
     }
     else
         System.out.println("ERROR: button troll");
     }
}
2012-04-05 02:38
by OverAir
"I hope this class is enough, please let me know if you need the frame/panel code as well." For better help sooner, post an SSCCE - Andrew Thompson 2012-04-05 02:40
Thread.sleep(1000); Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks or a SwingWorker for long running tasks. See Concurrency in Swing for more details - Andrew Thompson 2012-04-05 02:41
@AndrewThompson Thank you! After I finish reading the SSCCE, I will look into Swing Timer/Swing Worker again(somehow I have trouble understanding how to implement it). Thanks again - OverAir 2012-04-05 02:55


3

After turning the code snippet into an SSCCE, this is what I get (which seems to work - as best as I understand the original code).

I have not changed the variable names. Please learn common Java naming conventions1 for class, method & attribute names & use it consistently.

  1. Specifically names like b_study should be more along the lines of studyButton or similar. Some will note that 'button' should not be part of the name, but when you have a GUI with both a 'Study' button & label, I don't see any other logical way to separate them.

import java.awt.event.*;
import javax.swing.*;
import java.util.concurrent.atomic.AtomicInteger;

class TimerTicker {

    public static final int STUDY_TIME = 15;
    AtomicInteger atomicDown = new AtomicInteger(STUDY_TIME);
    JButton b_study;
    JButton b_exit;
    JLabel l_studyTime;

    TimerTicker() {
        JPanel gui = new JPanel();

        b_study = new JButton("Study");
        ClickListener listener = new ClickListener();
        b_study.addActionListener(listener);
        gui.add(b_study);

        b_exit = new JButton("Exit");
        b_exit.addActionListener(listener);
        gui.add(b_exit);

        l_studyTime = new JLabel("" + atomicDown.get());
        gui.add(l_studyTime);

        JOptionPane.showMessageDialog(null, gui);
    }

    private class ClickListener implements ActionListener {

        Timer timer;

        public void actionPerformed(ActionEvent e){
            if (e.getSource() == b_study) {
                ActionListener countDown = new ActionListener() {

                    public void actionPerformed(ActionEvent ae) {
                        if (!(atomicDown.get() > 0)) {
                            timer.stop();
                            // reset the count.
                            atomicDown.set(STUDY_TIME);
                        } else {
                            l_studyTime.setText(
                                Integer.toString(
                                    atomicDown.decrementAndGet()));
                        }
                    }
                };
                timer = new Timer(1000,countDown);
                timer.start();
            } else if(e.getSource() == b_exit) {
                System.exit(0);
            } else {
                System.out.println("ERROR: button troll");
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TimerTicker();
            }
        });
    }
}
2012-04-05 03:26
by Andrew Thompson
I swear, I learn more here than at school. I had a prof who wanted just to name b_ because it's a button and l_ for label. :/ I really appreciate your time and patience. I will make better effort re. SSCCE in the future. Thank you! - OverAir 2012-04-05 04:29
You're welcome. Glad it helped. :) "I had a prof who wanted just to.." People in educational institutions often lack the 'more focused' knowledge gained by people in the industry (theory is fine, but what works in practice might be completely different) - Andrew Thompson 2012-04-05 04:40
I also wanted to mention that I had a non-working program with 323 lines of code and yours works perfectly with 68 - OverAir 2012-04-05 04:41
That's an SSCCE for you. ;) Trim all the cruft from code with problems and not only will the problem become clear most times, but in the cases it doesn't, you'll have reproduced the error in just a handful of lines of code that are easy for others to debug. That code could have been shorter still (e.g. the Exit button was irrelevant to something appearing in a JOptionPane), but I wanted to stay close to the existing GUI controls and logic - Andrew Thompson 2012-04-05 04:47
+1 for doing the effort converting the code to an SSCC - Robin 2012-04-05 06:03
Ads