0

I was able to make a timer in java, but I cant stop the timer with timer.stop() Here is my code

import javax.swing.*;
import java.awt.*;

public class Countdown {
    public static void main(String[] args) {
        
        JFrame frame = new JFrame("Countdown");


        frame.setSize(300, 200);


        JLabel label = new JLabel("300");


        label.setFont(new Font("Arial", Font.BOLD, 48));
        label.setHorizontalAlignment(SwingConstants.CENTER);


        frame.add(label);

        // Show the frame
        frame.setVisible(true);


        Timer timer = new Timer(1000, e -> {

            int count = Integer.parseInt(label.getText());


            count--;


            label.setText(String.valueOf(count));


            if (count == 0) {
                timer.stop();
            }
        });


        timer.start();
    }
}
if (count == 0) {
                timer.stop();
            }

This is the part that has an error, it says "Variable 'timer' might not have been initialized". what can I do to make the program recognize the timer?

  • `if (count <= 0) {`? – MadProgrammer Dec 12 '22 at 21:40
  • Also, the count should be pushed to the UI and not pulled from it – MadProgrammer Dec 12 '22 at 21:40
  • 1
    Before even thinking about making a timer, I would first strive to get all that code out of the static main method where you may be painting yourself into a static and limited scope corner. Make a decent OOPs-compliant class, one that has a `private Timer timer` Swing Timer field that you can reference in the instance methods of the class. – Hovercraft Full Of Eels Dec 12 '22 at 21:42
  • 3
    `timer` can not be referenced from within the anonymous class (ie the listener), use `((Timer)e.getSource()).stop();` instead or, as Hovercraft suggest, encapsulate the logic into a stand alone class – MadProgrammer Dec 12 '22 at 21:42
  • 2
    And despite the (now deleted) answer, your idea to use of the `.stop()` method *is* correct, since you're using a Swing Timer (which is a good idea) and not a `java.util.Timer` (which would be a bad idea here). – Hovercraft Full Of Eels Dec 12 '22 at 21:44

1 Answers1

2

timer can not be referenced from within the anonymous class (ie the listener), use ((Timer)e.getSource()).stop(); instead or, as Hovercraft suggest, encapsulate the logic into a stand alone class, for example...

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer timer;
        private int count = 300;
        private JLabel label;

        public TestPane() {
            setLayout(new GridBagLayout());
            setBorder(new EmptyBorder(32, 32, 32, 32));
            JLabel label = new JLabel(Integer.toString(count));
            label.setFont(new Font("Arial", Font.BOLD, 48));
            label.setHorizontalAlignment(SwingConstants.CENTER);
            add(label);

            timer = new Timer(50, e -> {
                count--;
                if (count <= 0) {
                    timer.stop();
                    count = 0;
                }

                label.setText(String.valueOf(count));
            });

            timer.start();
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    I agree with this answer but am confused by the paintComponent method as it appears to be somewhat futile code, the Swing equivalent of "spinning one's wheels". – Hovercraft Full Of Eels Dec 12 '22 at 21:58
  • 1
    @HovercraftFullOfEels Because, custom painting is awesome! ‍♂️ Template code – MadProgrammer Dec 12 '22 at 22:28
  • 1
    it is indeed beyond awesome. And thanks for the explanation – Hovercraft Full Of Eels Dec 12 '22 at 22:45
  • @HovercraftFullOfEels not surprised that you agree (it's your comment flashed out with code :) - but surprised that you, Mad, didn't stick to the most simple solution you, Mad, outlined in the comment: creating a new view just to allow access to the enclosing timer is .. full-blown over-blast, IMO, borderline acceptable only due to updating the contained label ;) It's a basic java problem that can be solved in basic java way, no need for any fluff .. just saying :))) – kleopatra Dec 13 '22 at 11:23
  • @kleopatra I would argue it all comes down to context and this is just one example of one possible solution to the problem ;) – MadProgrammer Dec 13 '22 at 22:06