-2

I am working on an implementation for a metronome in Java. I have read around that using Thread.sleep isn't the best way to actually sync the times properly which may be the root of my problem. However, the issue I am running across in the beginning stages of my implementation are that when i utilize the +/- buttons, the bpm changes, however the speed of the text "RUNNING" drastically increases when you're only changing from like 60 to 61 bpm.

Any help with why that might be the case would be great. I am also interested in changing the thread.sleep() to something different however the midi option is a little over my head and i can't find any good documentation to help me with that option.

Thanks

Here is my code so far:

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");
    }
}
}
Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
Alien8tr96
  • 23
  • 1
  • 11
  • Hello, and welcome to Stack Overflow! When posting code, try to reduce your code to an [MCVE] ; meaning, try to re-create your problem with the least amount of code. Since we didn't write your code, we don't know all of the nuances or intentions of each line, so we don't know what is important and what isn't, but you do. Simplifying the code you post will help us help you by making locating the code's errors easier. In this case, the problem with the `Thread.sleep` line was quick to find, but in the future errors might not be so simple, so try to get in the habit of [MCVE]s – Davy M Sep 27 '17 at 22:29

1 Answers1

1

The problem is in this line:

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

When bpm becomes 61 your timeout becomes 0. This is because with integer division 60/61 = 0.

Try instead:

Thread.sleep((long)(1000*(60.0/bpm)));
algrid
  • 5,600
  • 3
  • 34
  • 37