为了账号安全,请及时绑定邮箱和手机立即绑定

按下按钮时不会重置时间

按下按钮时不会重置时间

胡说叔叔 2023-07-13 15:44:01
我想创建一个有 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 分钟时,当我按“停止”时,它会打印 1,但是当我按下 Go 并且已经过去 3 分钟时,它会打印 34,3 是重置时间,4 是旧时间1 。我该如何更改它,以便在 time1 和 time2 都重置的情况下只打印 3?
查看完整描述

1 回答

?
杨__羊羊

TA贡献1943条经验 获得超7个赞

在 go 的监听器中添加 stop 的动作监听器是搬起石头砸自己的脚,因为这意味着 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.TimeGregorianCalendar。

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

在此示例中,goButton 的 ActionListener 将:

  • 将 LocalTime 字段的 startTime 设置为当前时间,LocalTime.now()

  • 检查 Swing Timer 是否正在运行,如果是,则停止它

  • 然后创建一个新的 Swing Timer 并启动它。该计时器将每 50 微秒重复检查从开始到当前时间的持续时间,然后用表示该持续时间的文本更新 JLabel

stopButton 的侦听器将:

  • 检查是否按下了 go 按钮,startTime 是否不再为空。

  • 如果是这样,它将检查 Swing Timer(计时器)是否不为空,如果它当前正在运行,则停止它。

  • 如果 Swing Timer 仍在运行,则停止计时器并设置一个表示停止时间 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());

    }

}


查看完整回答
反对 回复 2023-07-13
  • 1 回答
  • 0 关注
  • 65 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信