【问题标题】:Metronome in JavaJava中的节拍器
【发布时间】:2018-03-09 13:00:22
【问题描述】:

我正在用 Java 实现节拍器。我已经阅读过,使用 Thread.sleep 并不是正确同步时间的最佳方法,这可能是我问题的根源。但是,我在实施的开始阶段遇到的问题是,当我使用 +/- 按钮时,bpm 会发生变化,但是当您仅从 60 开始更改时,“RUNNING”文本的速度会急剧增加到 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");
    }
}
}

【问题讨论】:

  • 您好,欢迎来到 Stack Overflow!发布代码时,尽量将您的代码减少到 minimal reproducible example ;意思是,尝试用最少的代码重新创建您的问题。由于我们没有编写您的代码,我们不知道每一行的所有细微差别或意图,所以我们不知道什么是重要的,什么不是,但您知道。简化您发布的代码将帮助我们帮助您更轻松地定位代码的错误。在这种情况下,Thread.sleep 行的问题很快就找到了,但以后的错误可能不会那么简单,所以试着养成minimal reproducible examples 的习惯

标签: java multithreading metronome


【解决方案1】:

问题出在这一行:

Thread.sleep((long)(1000*(60/bpm)));

bpm 变为 61 时,您的超时变为 0。这是因为整数除法 60/61 = 0

试试吧:

Thread.sleep((long)(1000*(60.0/bpm)));

【讨论】:

  • 这可以改变速度!非常感谢!它总是一些你看不起的小东西......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 2021-06-02
  • 2023-01-07
  • 2020-11-30
  • 2011-06-28
相关资源
最近更新 更多