title: Metronome in Java
body: <p>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. </p>
  
  <p>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. </p>
  
  <p>Thanks</p>
  
  <p>Here is my code so far: </p>
  
  <pre><code>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");
      }
  }
  }
  </code></pre>