Button doesn't reset time when pressed

kristian goshi :

I wanted to create a program that has 2 buttons Go and Stop. When i press Go the program finds the time the button is pressed and when i press Stop it finds the time this button is pressed and then shows me time2-time1. The problem is when i repress the Go button it shows me the new time2-time1 with both of them reseted but also prints a new reseted time2 minus the first time1 like its stuck in a loop.

    go.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {

            GregorianCalendar timesi= new GregorianCalendar();
            int time1 =timesi.get(Calendar.MINUTE);

        stop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                GregorianCalendar timesi1= new GregorianCalendar();
                int time2 =timesi1.get(Calendar.MINUTE);

                System.out.println(time2-time1);
            }
        });
        }
    });

When i first hit Go and 1 min has passed it prints 1 when i press Stop as it should, but when i repress go and 3 minutes have passed this time it prints 34, 3 is for the reseted time and 4 is for the old time1. How can i change it so it only prints 3 with both of time1 and time2 reseted?

Hovercraft Full Of Eels :

You're shooting yourself in the foot by adding the stop's action listener within the go's listener since this means that stop will likely get multiple listeners added to it needlessly. So instead of doing this, add stop's listener once and only once, outside of go's listener and on the same code level as where you add go's listener. Also, make the time1 variable a private field of the class so that it is visible within stop's listener. Something like:

public class MyGui {
    private JButton go = new JButton("Go");
    private JButton stop = new JButton("stop");
    private int time = 0;

    public MyGui() {
        go.addActionListener(new ActionListener() {
            GregorianCalendar timesi = new GregorianCalendar();
            // int time1 = timesi.get(Calendar.MINUTE);
            time1 = timesi.get(Calendar.MINUTE); // use the field not a local class
        });

        // stop's listener added at the same level as the go's listener
        stop.addActionListener(new ActionListener() {
            GregorianCalendar timesi1 = new GregorianCalendar();
            int time2 = timesi1.get(Calendar.MINUTE);

            System.out.println(time2-time1);
        });

        // more code here
    }       

    // main method....
}

Notes:

  • The code above has not been compiled nor tested and is posted more to show concepts not to copy and paste as a direct solution.
  • Better to use the newer and cleaner java.time.LocalTime class rather than java.util.Time or GregorianCalendar.

Here is a more complete example, one that uses LocalTime.

In this example, the goButton's ActionListener will:

  • set the startTime LocalTime field to the current time, LocalTime.now()
  • Check to see if a Swing Timer is running, and if so, stop it
  • Then create a new Swing Timer and start it. This Timer will check the time duration from start to the current time repeatedly every 50 microseconds, and then update a JLabel with text that represents this time duration

The stopButton's listener will:

  • check if the go button has been pressed, if startTime is no longer null.
  • If so, it will check if the Swing Timer, timer, is not null and if it is currently running, stop it.
  • If the Swing Timer is still running, then stop the timer and set a field that represents the stop time LocalTime.
  • Calculate the time difference between the start and stop time, and print it out.
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import javax.swing.*;

@SuppressWarnings("serial")
public class TimerGui extends JPanel {
    private static final int TIMER_DELAY = 50;
    private LocalTime startTime;
    private LocalTime stopTime;
    private JLabel timerLabel = new JLabel("00:00", SwingConstants.CENTER);
    private Timer timer = null;
    private JButton goButton = new JButton("Go");
    private JButton stopButton = new JButton("Stop");
    private JButton exitButton = new JButton("Exit");

    public TimerGui() {
        // make the timer label's text larger
        timerLabel.setFont(timerLabel.getFont().deriveFont(Font.BOLD, 24f));
        timerLabel.setBorder(BorderFactory.createTitledBorder("Elapsed Time"));

        // alt-key hotkeys for my buttons
        goButton.setMnemonic(KeyEvent.VK_G);
        stopButton.setMnemonic(KeyEvent.VK_S);
        exitButton.setMnemonic(KeyEvent.VK_X);

        // add ActionListeners
        goButton.addActionListener(e -> {
            // reset startTime
            startTime = LocalTime.now();

            // if timer running, stop it
            if (timer != null && timer.isRunning()) {
                timer.stop();
            }
            timer = new Timer(TIMER_DELAY, new TimerListener());
            timer.start();
        });
        stopButton.addActionListener(e -> {
            // if start has already been pressed
            if (startTime != null) {
                // if timer running, stop it
                if (timer != null && timer.isRunning()) {
                    timer.stop();
                    stopTime = LocalTime.now();
                }
                long minuteDifference = startTime.until(stopTime, ChronoUnit.MINUTES);
                long secondDifference = startTime.until(stopTime, ChronoUnit.SECONDS);
                System.out.println("Time difference in minutes: " + minuteDifference);
                System.out.println("Time difference in seconds: " + secondDifference);
            }            
        });
        exitButton.addActionListener(e -> {
            System.exit(0);
        });

        JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 5, 5));
        buttonPanel.add(goButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(exitButton);

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout(5, 5));
        add(timerLabel, BorderLayout.PAGE_START);
        add(buttonPanel);
    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            LocalTime endTime = LocalTime.now();
            long secondDifference = startTime.until(endTime, ChronoUnit.SECONDS);

            int minutes = (int) (secondDifference / 60);
            int seconds = (int) (secondDifference % 60);
            String timeText = String.format("%02d:%02d", minutes, seconds);
            timerLabel.setText(timeText);
        }
    }

    private static void createAndShowGui() {
        TimerGui mainPanel = new TimerGui();

        JFrame frame = new JFrame("Timer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Guess you like

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