按下按钮不会重置时间

时间:2019-09-06 11:53:19

标签: java swing date jpanel jbutton

我想创建一个具有2个按钮Go和Stop的程序。 当我按Go时,程序会找到按钮被按下的时间,而当我按Stop时,它将找到按下此按钮的时间,然后向我显示time2-time1。问题是,当我按下“ Go”按钮时,它会向我显示新的time2-time1,它们都已重置,但还会打印一个新的重置的time2减去第一个time1,就像它陷入循环一样。

    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);
            }
        });
        }
    });

当我第一次按下Go并且经过1分钟时,按我应该按的Stop时会打印1,但是当我按下go并且经过3分钟时,它会显示34,其中3是重置时间,4是旧时光1。我该如何更改它,使其仅在重置time1和time2的同时打印3?

1 个答案:

答案 0 :(得分:3)

您要通过在go的侦听器内添加止动动作侦听器来射击自己,因为这意味着stop可能会不必要地添加多个侦听器。因此,除了执行此操作外,在go的侦听器之外并在与添加go的侦听器相同的代码级别上,仅一次添加stop的侦听器。另外,将time1变量设置为类的私有字段,以便在stop的侦听器中可见。像这样:

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....
}

注意:

  • 上面的代码尚未经过编译或测试,因此更多地发布以表明概念不应该作为直接解决方案进行复制和粘贴。
  • 最好使用更新,更清洁的java.time.LocalTime类,而不是java.util.Time或GregorianCalendar。

这是一个更完整的示例,它使用LocalTime。

在此示例中,goButton的ActionListener将:

  • 将startTime LocalTime字段设置为当前时间LocalTime.now()
  • 检查Swing计时器是否正在运行,如果正在运行,则将其停止
  • 然后创建一个新的Swing Timer并启动它。此计时器将每隔50微秒重复检查从开始到当前时间的持续时间,然后使用表示该持续时间的文本更新JLabel

stopButton的侦听器将:

  • 如果startTime不再为null,请检查是否已按下执行按钮。
  • 如果是,它将检查Swing计时器(计时器)是否不为null,如果当前正在运行,则将其停止。
  • 如果Swing计时器仍在运行,请停止计时器并设置一个代表停止时间LocalTime的字段。
  • 计算开始时间和结束时间之间的时差,然后打印出来。
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());
    }
}