title: Java Swing Movement Stutter
body: <p>I'm experiencing stuttering while moving a block in Java Swing.</p>
  
  <p>The following code will show the problem. When run, I'd like the box to move smoothly without any stuttering. Is there any way to achieve this in Swing? Or should I just move on to JavaFX?</p>
  
  <p>MovementStutter.java</p>
  
  <pre><code>package movementstutter;
  
  import javax.swing.JFrame;
  
  public class MovementStutter {
  
  public static void main(String[] args) {
      JFrame win = new JFrame("Stutter Demo");
      win.getContentPane().add(new GamePanel());
      win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      win.setResizable(false);
      win.pack();
      win.setVisible(true);
  }
  
  }
  </code></pre>
  
  <p>GamePanel.java</p>
  
  <pre><code>package movementstutter;
  
  import java.awt.Dimension;
  import java.awt.Graphics;
  import javax.swing.JPanel;
  
  public class GamePanel extends JPanel implements Runnable {
  
  private boolean running;
  private Thread thread;
  private double x;
  private double y;
  private double movementFactor;
  
  public GamePanel() {
      setPreferredSize(new Dimension(640, 480));
      setFocusable(true);
      grabFocus();
      movementFactor = 1;
      running = true;
  }
  
  @Override
  public void addNotify() {
      super.addNotify();
      if (thread == null) {
          thread = new Thread(this);
          thread.start();
      }
  }
  
  @Override
  public void run() {
      long time = System.currentTimeMillis();
      while (running) {
          update();
          repaint();
          long sleep = 16 - (System.currentTimeMillis() - time);
          time += 16;
          if (sleep &lt; 0) {
              sleep = 16;
          }
          try {
              Thread.sleep(sleep);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }
  
  private void update() {
      if (x &lt; 0) {
          movementFactor = 1;
      } else if (x &gt; 608) {
          movementFactor = -1;
      }
      x += movementFactor * 200 * 0.016;
  }
  
  @Override
  public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.fillRect((int) x, (int) y, 32, 32);
  }
  
  }
  </code></pre>