You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing BPM计算器界面不更新问题求助

解决BPM计算器界面不更新的问题

我帮你排查了代码里的几个关键问题,正是这些问题导致点击后界面没有变化:

核心问题分析

  1. 每次点击都重置时间存储数组:在按钮的ActionListener里,你每次点击都会执行counter = new int[2];,这会把之前存储的第一次点击时间清空,导致第二次点击时计算的时间差完全错误(用当前时间减去0),最终得到的BPM是0或者极小值,看起来和初始显示没区别。
  2. 变量初始化不明确:buttonPressed没有显式初始化为0(虽然Java默认int是0,但显式初始化更清晰,避免潜在问题)。
  3. 缺少除以0的防护:如果两次点击间隔极短(理论上可能),time3会是0,导致60000 / time3抛出算术异常。

修改后的完整代码

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

public class BPM extends JPanel implements ActionListener {
    JLabel label;
    public String display;
    public int bpm;
    public int buttonPressed = 0; // 显式初始化点击计数器
    public int[] counter = new int[2]; // 把数组初始化移到类成员位置,避免每次点击重置
    private int time1;
    private int time2;
    private int time3;

    public void addComponents(Container pane) {
        JPanel buttons = new JPanel();
        JButton bpmButton = new JButton("Click");
        bpmButton.setSize(new Dimension(100, 50));
        bpmButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                buttonPressed++;
                // 移除每次点击都新建数组的代码
                if (buttonPressed == 1) {
                    counter[0] = (int)(System.currentTimeMillis());
                } else if (buttonPressed == 2) {
                    counter[1] = (int)(System.currentTimeMillis());
                    calculateTimeBetweenClicks();
                    setTime();
                } else {
                    counter[0] = counter[1];
                    counter[1] = (int)(System.currentTimeMillis());
                    calculateTimeBetweenClicks();
                    setTime();
                }
            }
        });

        display = "0";
        label = new JLabel(display, SwingConstants.CENTER);
        label.setFont(label.getFont().deriveFont(100.0f));
        pane.add(label, BorderLayout.PAGE_START);
        pane.add(bpmButton, BorderLayout.CENTER);
    }

    // 计算两次点击的时间差
    public void calculateTimeBetweenClicks() {
        time1 = counter[0];
        time2 = counter[1];
        time3 = time2 - time1;
    }

    // 计算BPM并更新显示,添加除以0防护
    public void setTime() {
        if (time3 <= 0) {
            display = "Invalid";
        } else {
            bpm = 60000 / time3;
            display = String.valueOf(bpm);
        }
        label.setText(display);
        // 强制刷新标签,确保界面更新(虽然Swing通常会自动刷新,但加上更稳妥)
        label.repaint();
    }

    // 实现ActionListener接口的方法(当前未使用,可以保留或移除)
    public void actionPerformed(ActionEvent e) {}

    public static void createAndShowGUI() {
        JFrame frame = new JFrame("BPM Calculator");
        frame.setPreferredSize(new Dimension(300, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        BPM window = new BPM();
        window.addComponents(frame.getContentPane());

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

关键修改点说明

  • 将counter数组初始化移到类成员位置:这样数组只会在类实例化时创建一次,每次点击只会更新数组里的值,不会丢失之前存储的时间。
  • 显式初始化buttonPressed为0:让代码逻辑更清晰,避免依赖Java默认值。
  • 添加除以0的防护逻辑:防止极端情况下的算术异常,同时给出友好提示。
  • 优化calculateTimeBetweenClicks方法:移除不必要的分支,因为只有当buttonPressed>=2时才会调用这个方法,不需要处理buttonPressed==1的情况。
  • 将time1、time2、time3改为类成员变量:避免在方法里重复定义,让代码结构更合理。

现在你运行修改后的代码,点击两次按钮后就能正确显示BPM,后续每次点击都会实时更新结果啦!

内容的提问来源于stack exchange,提问作者Snurgler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:13:48