/*
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);
}
}