Timer in Java with GUI

chrysaetos99 :

I've tried to write a litte java-program that should work as a timer.

The problem is (probably) that I need to use Thread.sleep(), which throws InterruptedException. So if I start the program, I am able to enter the seconds an minutes, but when pressing "OK", nothing happens (it also doesn't show any warnings or errors in the terminal).

Here's the code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.NumberFormat;
import javax.swing.text.NumberFormatter;

import static javax.swing.WindowConstants.EXIT_ON_CLOSE;

public class Timer {

   public static void main(String[] args) throws InterruptedException {

       SwingUtilities.invokeLater(Timer::new);
   }

   private JButton button;
   private JTextField minutes;
   private JTextField seconds;

   Timer() {
       JFrame frame = new JFrame();
       frame.setSize(300, 200);
       frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
       JPanel panel = new JPanel(new BorderLayout());
       JPanel subpanel1 = new JPanel(new GridLayout(1, 2));

       /* 
        * The following lines ensure that the user can 
        * only enter numbers.
       */

       NumberFormat format = NumberFormat.getInstance();
       NumberFormatter formatter = new NumberFormatter(format);
       formatter.setValueClass(Integer.class);
       formatter.setMinimum(0);
       formatter.setMaximum(Integer.MAX_VALUE);
       formatter.setAllowsInvalid(false);
       formatter.setCommitsOnValidEdit(true);

       minutes = new JFormattedTextField(formatter);
       seconds = new JFormattedTextField(formatter);
       minutes.setText("0");
       seconds.setText("0");

       JPanel subpanel2 = new JPanel();

       /*
        * When the user presses the OK-button, the program will
        * start to count down.
       */

       button = new JButton("OK");
       button.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent actionEvent) {
               try {
                   timer();
               }
               catch(InterruptedException e) {

               }
           }
       });

       JButton button2 = new JButton("Reset");
       button2.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent actionEvent) {
               minutes.setText("0");
               seconds.setText("0");
               button.setEnabled(true);
           }
       });
       subpanel1.add(minutes);
       subpanel1.add(seconds);
       subpanel2.add(button);
       subpanel2.add(button2);
       panel.add(subpanel1, BorderLayout.CENTER);
       panel.add(subpanel2, BorderLayout.PAGE_END);
       frame.add(panel);
       frame.setVisible(true);
   }


   //Method for the timer
   void timer() throws InterruptedException {
       int min = Integer.valueOf(minutes.getText());
       int sec = Integer.valueOf(seconds.getText());
       button.setEnabled(false);


       while(min > 0 || sec > 0) {
           Thread.sleep(1000);
           if(sec >= 1) {
               sec = sec - 1;
               seconds.setText(String.valueOf(sec));
           }
           else if(sec == 0 || min > 0) {
               sec = 59;
               min = min - 1;
               seconds.setText(String.valueOf(sec));
               minutes.setText(String.valueOf(min));
           }
       }
   }
}

What can I do to make it work?


I know replaced Thread.sleep() with the following:

Timer timer = new Timer(delay, taskPerformer);
timer.setRepeats( false );
timer.start();

Now an error occurs: The constructor cannot applied to given types (it wants no arguments). What did I do wrong? (The variables delay and taskPerformer are defined, and I did not import java.util.Timer)

c0der :

The following mre shows how you can use javax.swing.Timer to get the desired countdown :

import static javax.swing.WindowConstants.EXIT_ON_CLOSE;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.text.NumberFormat;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.text.NumberFormatter;

public class MyTimer {

    public static void main(String[] args) throws InterruptedException {
        SwingUtilities.invokeLater(MyTimer::new);
    }

    private final JButton startButton, resetButton;
    private final JTextField minutes;
    private final JTextField seconds;
    private static final int SECOND = 1000;

    private Timer timer;

    MyTimer() {
        JFrame frame = new JFrame();
        //frame.setSize(300, 200);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

        /*
         * The following lines ensure that the user can
         * only enter numbers.
         */
        NumberFormat format = NumberFormat.getInstance();
        NumberFormatter formatter = new NumberFormatter(format);
        formatter.setValueClass(Integer.class);
        formatter.setMinimum(0);
        formatter.setMaximum(Integer.MAX_VALUE);
        formatter.setAllowsInvalid(false);
        formatter.setCommitsOnValidEdit(true);

        minutes = new JFormattedTextField(formatter);
        seconds = new JFormattedTextField(formatter);
        minutes.setText("0");
        seconds.setText("0");

        /*
         * When the user presses the OK-button, the program will
         * start to count down.
         */
        startButton = new JButton("OK");
        startButton.addActionListener(actionEvent -> {
            timer();
        });

        resetButton = new JButton("Reset");
        resetButton.setEnabled(false);
        resetButton.addActionListener(actionEvent -> {
            reset();
        });

        JPanel subpanel1 = new JPanel(new GridLayout(1, 2));
        subpanel1.add(minutes);
        subpanel1.add(seconds);

        JPanel subpanel2 = new JPanel();
        subpanel2.add(startButton);
        subpanel2.add(resetButton);

        JPanel panel = new JPanel(new BorderLayout());
        panel.add(subpanel1, BorderLayout.CENTER);
        panel.add(subpanel2, BorderLayout.PAGE_END);
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    void timer() {

        startButton.setEnabled(false);

        timer = new Timer(SECOND, e->{

            final int min = Integer.valueOf(minutes.getText());
            final int sec = Integer.valueOf(seconds.getText());
            if(sec == 0 && min == 0){
                reset();
            }else if(sec >= 1) {
                seconds.setText(String.valueOf(sec-1));
            }
            else if(sec == 0 || min > 0) {
                seconds.setText(String.valueOf(59));
                minutes.setText(String.valueOf(min-1));
            }
        });

        timer.setRepeats(true);
        timer.start();
        resetButton.setEnabled(true);
    }

    private void reset() {

        if(timer != null) {
            timer.stop();
        }
        minutes.setText("0");
        seconds.setText("0");
        startButton.setEnabled(true);
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=237974&siteId=1