Java 中的节拍器
Metronome in Java
我正在为 Java 中的节拍器实现。我已经了解到,使用 Thread.sleep 并不是真正正确同步时间的最佳方式,这可能是我问题的根源。然而,我在实施的开始阶段 运行 遇到的问题是,当我使用 +/- 按钮时,bpm 会发生变化,但是文本的速度 "RUNNING" 当你只是从 60 变为 61 bpm。
任何关于为什么会出现这种情况的帮助都会很棒。我也有兴趣将 thread.sleep() 更改为不同的东西,但是 midi 选项有点让我头疼,我找不到任何好的文档来帮助我使用该选项。
谢谢
到目前为止,这是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class mainWindow
{
public static void main (String[] args){
frameClass frame = new frameClass();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350,275);
frame.setVisible(true);
}
}
class frameClass extends JFrame
{
private JButton onOff;
private JButton plus;
private JButton minus;
public frameClass()
{
setLayout(new FlowLayout());
onOff = new JButton("On/Off");
plus = new JButton("+");
minus = new JButton("-");
add(onOff);
add(plus);
add(minus);
toggleHandler handler = new toggleHandler();
onOff.addActionListener(handler);
plusHandler plusHandle = new plusHandler();
plus.addActionListener(plusHandle);
minusHandler minusHandle = new minusHandler();
minus.addActionListener(minusHandle);
}
private class toggleHandler implements ActionListener {
private Metronome metro;
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
if (e.getSource() == onOff) {
if (metro == null) {
metro = new Metronome();
Thread t = new Thread(metro);
t.start();
} else {
metro.end();
metro = null;
}
}
}
}
private class plusHandler implements ActionListener
{
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
{
Metronome.bpm++;
}
}
private class minusHandler implements ActionListener
{
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
{
Metronome.bpm--;
}
}
}
class Metronome extends Thread
{
private AtomicBoolean keepRunning;
static double bpm = 60;
public Metronome()
{
keepRunning = new AtomicBoolean(true);
}
public void end()
{
keepRunning.set(false);
System.out.println("STOPPED");
}
@Override
public void run()
{
while (keepRunning.get())
{
try
{
Thread.sleep((long)(1000*(60.0/bpm)));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("RUNNING");
}
}
}
问题出在这一行:
Thread.sleep((long)(1000*(60/bpm)));
当 bpm
变为 61 时,您的超时变为 0。这是因为整数除法 60/61 = 0
。
试试看:
Thread.sleep((long)(1000*(60.0/bpm)));
我正在为 Java 中的节拍器实现。我已经了解到,使用 Thread.sleep 并不是真正正确同步时间的最佳方式,这可能是我问题的根源。然而,我在实施的开始阶段 运行 遇到的问题是,当我使用 +/- 按钮时,bpm 会发生变化,但是文本的速度 "RUNNING" 当你只是从 60 变为 61 bpm。
任何关于为什么会出现这种情况的帮助都会很棒。我也有兴趣将 thread.sleep() 更改为不同的东西,但是 midi 选项有点让我头疼,我找不到任何好的文档来帮助我使用该选项。
谢谢
到目前为止,这是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.concurrent.atomic.AtomicBoolean;
public class mainWindow
{
public static void main (String[] args){
frameClass frame = new frameClass();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(350,275);
frame.setVisible(true);
}
}
class frameClass extends JFrame
{
private JButton onOff;
private JButton plus;
private JButton minus;
public frameClass()
{
setLayout(new FlowLayout());
onOff = new JButton("On/Off");
plus = new JButton("+");
minus = new JButton("-");
add(onOff);
add(plus);
add(minus);
toggleHandler handler = new toggleHandler();
onOff.addActionListener(handler);
plusHandler plusHandle = new plusHandler();
plus.addActionListener(plusHandle);
minusHandler minusHandle = new minusHandler();
minus.addActionListener(minusHandle);
}
private class toggleHandler implements ActionListener {
private Metronome metro;
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
if (e.getSource() == onOff) {
if (metro == null) {
metro = new Metronome();
Thread t = new Thread(metro);
t.start();
} else {
metro.end();
metro = null;
}
}
}
}
private class plusHandler implements ActionListener
{
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
{
Metronome.bpm++;
}
}
private class minusHandler implements ActionListener
{
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
{
Metronome.bpm--;
}
}
}
class Metronome extends Thread
{
private AtomicBoolean keepRunning;
static double bpm = 60;
public Metronome()
{
keepRunning = new AtomicBoolean(true);
}
public void end()
{
keepRunning.set(false);
System.out.println("STOPPED");
}
@Override
public void run()
{
while (keepRunning.get())
{
try
{
Thread.sleep((long)(1000*(60.0/bpm)));
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.out.println("RUNNING");
}
}
}
问题出在这一行:
Thread.sleep((long)(1000*(60/bpm)));
当 bpm
变为 61 时,您的超时变为 0。这是因为整数除法 60/61 = 0
。
试试看:
Thread.sleep((long)(1000*(60.0/bpm)));