|
| |
Here's a simple example of how one might provide visual feedback from
time-consuming work processing in a background thread: A "2-Phase
Responder"
package multiResponse;
/**
* This is an interface for a two-phase progress responder.
*/
public interface TwoPhaseResponder
{
/**
* Called when the work has started
*/
public void started();
/**
* Called when the first phase of the work is complete
*/
public void phase1Complete();
/**
* Called when the second phase of the work is complete
*/
public void phase2Complete();
/**
* Called when all the work is complete
*/
public void done();
}
|
package multiResponse;
/**
* This is a two-phase worker thread
*/
public class TwoPhaseWorker extends Thread
{
public TwoPhaseWorker(TwoPhaseResponder responder)
{
m_responder = responder;
}
public void run()
{
m_responder.started();
try
{
Thread.sleep(5000); // represents a long operation of some kind.
m_responder.phase1Complete();
Thread.sleep(5000); // represents another long operation of some kind.
m_responder.phase2Complete();
Thread.sleep(500); // Give the user a chance to see the second phase completed message
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
m_responder.done();
}
private TwoPhaseResponder m_responder;
}
|
package multiResponse;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* This is a frame which shows how we can provide visual responses from each of
* several phases of time-consuming work in a background worker thread.
*/
public class TwoPhaseResponderExample extends JFrame
{
public TwoPhaseResponderExample()
{
setTitle("Two-phase Responder Example");
setSize(200, 200);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add( new ButtonPanel(), BorderLayout.CENTER );
contentPane.add(m_progressLabel, BorderLayout.SOUTH);
}
class ButtonPanel extends JPanel implements ActionListener, TwoPhaseResponder
{
ButtonPanel()
{
setBackground(Color.blue);
m_clickMeButton.addActionListener(this);
add(m_clickMeButton);
m_nowClickMeButton.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
ButtonPanel.this.setBackground(Color.yellow);
}
}
);
m_nowClickMeButton.setEnabled(false); // Disable for now
add(m_nowClickMeButton);
}
public void actionPerformed(ActionEvent ev)
{
setBackground(Color.red);
m_nowClickMeButton.setEnabled(true);
m_progressLabel.setText("Background work in progress");
TwoPhaseWorker thread = new TwoPhaseWorker(this);
thread.start();
}
public void started()
{
setStatus("Started work...");
}
public void phase1Complete()
{
setStatus("Phase 1 complete");
}
public void phase2Complete()
{
setStatus("Phase 2 complete");
}
public void done()
{
setStatus("Work Completed");
}
private void setStatus(final String text)
{
SwingUtilities.invokeLater( new Runnable()
{
public void run()
{
m_progressLabel.setText(text);
}
}
);
}
}
public static void main(String[] args)
{
TwoPhaseResponderExample frame = new TwoPhaseResponderExample();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private JButton m_clickMeButton = new JButton("Click me!");
private JButton m_nowClickMeButton = new JButton("Now try to click me!");
private JLabel m_progressLabel = new JLabel(" ", SwingUtilities.CENTER);
}
|
Try It!
Here is an applet that invokes the above code when you click on its
"Start" button:
|
|
After you've brought up the JFrame, click on the "Click me!"
button, and see what actually happens! |
Results
The resulting JFrame should contain a JLabel field that is updated at appropriate places in the program, to indicate
when work has started, when phase 1 is complete, when phase 2 is complete, and
when all work has completed.
|