Threads Java

/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly 
*/
// InvokeExample.java
//This class demonstrates several examples of how to handle long-running
//tasks (such as querying a remote resource). Some of the examples are
//good, some are not!
//
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class InvokeExample {
  private static JButton good = new JButton("Good");
  private static JButton bad = new JButton("Bad");
  private static JButton bad2 = new JButton("Bad2");
  private static JLabel resultLabel = new JLabel("Ready", JLabel.CENTER);
  public static void main(String[] args) {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Layout . . .
    JPanel p = new JPanel();
    p.setOpaque(true);
    p.setLayout(new FlowLayout());
    p.add(good);
    p.add(bad);
    p.add(bad2);
    Container c = f.getContentPane();
    c.setLayout(new BorderLayout());
    c.add(p, BorderLayout.CENTER);
    c.add(resultLabel, BorderLayout.SOUTH);
    // Listeners
    good.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        resultLabel.setText("Working . . .");
        setEnabled(false);
        // We're going to do something that takes a long time, so we
        // spin off a thread and update the display when we're done.
        Thread worker = new Thread() {
          public void run() {
            // Something that takes a long time . . . in real life,
            // this
            // might be a DB query, remote method invocation, etc.
            try {
              Thread.sleep(5000);
            } catch (InterruptedException ex) {
            }
            // Report the result using invokeLater().
            SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                resultLabel.setText("Ready");
                setEnabled(true);
              }
            });
          }
        };
        worker.start(); // So we don't hold up the dispatch thread.
      }
    });
    bad.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        resultLabel.setText("Working . . .");
        setEnabled(false);
        // We're going to do the same thing, but not in a separate
        // thread.
        try {
          Thread.sleep(5000); // Dispatch thread is starving!
        } catch (InterruptedException ex) {
        }
        // Report the result.
        resultLabel.setText("Ready");
        setEnabled(true);
      }
    });
    bad2.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ev) {
        resultLabel.setText("Working . . . ");
        setEnabled(false);
        // The wrong way to use invokeLater(). The runnable() shouldn't
        // starve the dispatch thread.
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            try {
              Thread.sleep(5000); // Dispatch thread is starving!
            } catch (InterruptedException ex) {
            }
            resultLabel.setText("Ready");
            setEnabled(true);
          }
        });
      }
    });
    f.setSize(300, 100);
    f.setVisible(true);
  }
  // Allows us to turn the buttons on or off while we work.
  static void setEnabled(boolean b) {
    good.setEnabled(b);
    bad.setEnabled(b);
    bad2.setEnabled(b);
  }
}