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");
     }
}
Community
  • 1
  • 1
OverAir
  • 173
  • 2
  • 6
  • 16
  • 1
    *"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](http://sscce.org/). – Andrew Thompson Apr 05 '12 at 02:40
  • 4
    `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](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. – Andrew Thompson Apr 05 '12 at 02:41
  • 1
    @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 Apr 05 '12 at 02:55

1 Answers1

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();
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    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 Apr 05 '12 at 04:29
  • 1
    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 Apr 05 '12 at 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 Apr 05 '12 at 04:41
  • 1
    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 Apr 05 '12 at 04:47