Question

First of all hi! This is my first post on stackoverflow! This is my second attempt to program something in Java and the first ever attempt with a gui.

I'm actually having 2 problems. The first being the program and the second understanding a part of the code.

How the program should work:

When pressing start it counts down from 01:00 to 00:00 every minute (01:00 -> 00:59 -> 00:58). When you press stop, it stops counting down (duh) and when you press start again, it starts from 01:00 like the first time.

The program problem:

With that said. This only works the first time I press start. When I press start multiple times it subtracts that amount of times from the clock. Pressed 2 times (01:00 -> 00:58 -> 00:56). Pressed 4 times (01:00 -> 00:56 -> 00:52). etc... This obviously should not be happening.

The understanding problem:

I am having a hard time understanding why the timer requires an ActionListener and why it works when you use 'null'. In some cases it also works when using 'this' (which I also don't understand.).

Java Swing Timer Documentation

import java.awt.*;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CountdownClock extends JFrame
{

    private int oneSecond = 1000; //Milliseconds
    private Timer timer = new Timer(oneSecond * 60, null);
    private int timerCount = 59;

    public static void main(String args[])
    {
        new CountdownClock();
    }

    CountdownClock()
    {
        this.getContentPane().setLayout(null);
        this.setBounds(800, 450, 300, 125);

        final JLabel countdownLabel = new JLabel("01:00");
        countdownLabel.setBounds(110, 10, 125, 30);
        countdownLabel.setFont(new Font("Serif", Font.PLAIN, 30));

        JButton startButton = new JButton("Start");
        startButton.setBounds(10, 50, 125, 30);
        startButton.addActionListener(new ActionListener() 
        {
        public void actionPerformed(ActionEvent e)
        {
            timer.setRepeats(true);
            timer.stop();
            countdownLabel.setText("01:00");
            timerCount = 59;
            timer.start();
            timer.addActionListener(new ActionListener() 
            {
                public void actionPerformed(ActionEvent evt)
                {     
                    if (timerCount == 0)
                    {
                        timer.stop();
                        countdownLabel.setText("00:00");
                        timerCount = 59;
                    }
                    else if (timerCount <= 9)
                    {
                        countdownLabel.setText("00:0" + String.valueOf(timerCount));
                        timerCount = timerCount - 1;
                    }
                    else
                    {
                        countdownLabel.setText("00:" + String.valueOf(timerCount));
                        timerCount = timerCount - 1;
                    }
                }
            });
        }
    });

    JButton stopButton = new JButton("Stop");
    stopButton.setBounds(150, 50, 125, 30);
    stopButton.addActionListener(new ActionListener() 
    {
        public void actionPerformed(ActionEvent e)
        {
            timer.stop();
            countdownLabel.setText("01:00");
            timerCount = 59;
        }
    });

    add(countdownLabel);
    add(startButton);
    add(stopButton);

    setVisible(true);
    }
}
Was it helpful?

Solution

This happens because you are adding an ActionListener to the Timer every time that you press the button. So, since a Timer allows multiple listeners, everyone of them gets notified when the timer ticks.

To solve the problems you could just instantiate a new Timer every time you press the start button (timer = new Timer()). Or add the ActionListener just once in your JFrame constructor . Or even remove the listener (but you should save a reference to it somewhere).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top