A 2-Phase Responder
Home ] Up ]

 

 

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:

Your browser does not have Java support. Please install the Java Plug-in. 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.

 

The page was last updated February 19, 2008