title: Why doesn't the EDT shut down when all live threads are daemon?
body: <p>The following code slides a <a href="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Queen_of_diamonds_en.svg/209px-Queen_of_diamonds_en.svg.png" rel="nofollow noreferrer">card</a> across the screen. When I shut down the main window, I expect the event dispatch thread to shut down as well, but it does not. Any ideas on why the ScheduledExecutorService thread prevents the EDT from shutting down?</p>
  
  <pre><code>import java.awt.Graphics;
  import java.net.URL;
  import java.util.concurrent.Executors;
  import java.util.concurrent.ScheduledExecutorService;
  import java.util.concurrent.ThreadFactory;
  import java.util.concurrent.TimeUnit;
  import javax.swing.ImageIcon;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.SwingUtilities;
  
  public class Main extends JPanel
  {
    private float x = 1;
  
    public void next()
    {
      x *= 1.1;
      System.out.println(x);
      repaint();
    }
  
    @Override
    protected void paintComponent(Graphics g)
    {
      super.paintComponent(g);
      URL url = getClass().getResource("/209px-Queen_of_diamonds_en.svg.png");
      g.drawImage(new ImageIcon(url).getImage(), (int) x, 50, null);
    }
  
    public static void main(String[] args)
    {
      JFrame frame = new JFrame();
      final Main main = new Main();
      frame.getContentPane().add(main);
      frame.setSize(800, 600);
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.setVisible(true);
  
      ScheduledExecutorService timer = Executors.newScheduledThreadPool(1, new ThreadFactory()
      {
        public Thread newThread(Runnable r)
        {
          Thread result = new Thread(r);
          result.setDaemon(true);
          return result;
        }
      });
      timer.scheduleAtFixedRate(new Runnable()
      {
        public void run()
        {
          SwingUtilities.invokeLater(new Runnable()
          {
            public void run()
            {
              main.next();
            }
          });
        }
      }, 100, 100, TimeUnit.MILLISECONDS);
    }
  }
  </code></pre>