Illustrating The Problem
Home ] Up ] [ Illustrating The Problem ] What's Happening? ] Fixing the Problem ]

 

 

Consider the following code:

package hangThread;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
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.SwingConstants;
import javax.swing.SwingUtilities;

/**
 * This is a frame which illustrates the problems associated with trying to
 * do large amounts of work from within the Event Dispatch Thread.
 */

public class HangThreadExample extends JFrame
{
  public HangThreadExample()
  {
    setTitle("Hang Thread Example");
    setSize(200, 200);
    Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout());
    contentPane.add( new ButtonPanel(), BorderLayout.CENTER );
    contentPane.add(m_progressLabel, BorderLayout.SOUTH);
  }
  
  private void doWork()
  {
    try
    {
      Thread.sleep(10000); // represents a long operation of some kind.
    }
    catch (InterruptedException ie)
    {
      ie.printStackTrace();
    }
  }
  
  private void setProgress(final String text)
  {
    m_progressLabel.setText(text);
  }
  
  class ButtonPanel extends JPanel implements ActionListener
  {
    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)
    {
      m_clickMeButton.setEnabled(false);
      Color oldColor = getBackground(); // Save color
      setBackground(Color.red);
      m_nowClickMeButton.setEnabled(true);
      
      setProgress("Working...");
      doWork();
      setProgress("Done");
      
      m_clickMeButton.setEnabled(true);
    }
  }
  
  public static void main(String[] args)
  {
    HangThreadExample frame = new HangThreadExample();
    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(" ", SwingConstants.CENTER);
}

It simulates doing a lot of time-consuming work from the AWT event dispatch thread.

Note the ButtonPanel's actionPerformed method, which is invoked (from the AWT event dispatch thread) when you click on the "Click me!" button.  It  does the following:

  • Sets the background color of the ButtonPanel to red
  • Enables the "Now try to click me!" button.
  • Calls the HangThreadExample class's doWork() method
  • After returning from the doWork() method, it sets the background back to its original color, and disables the "Now try to click me!" button.

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 the JFrame up, try clicking on the "Click me!" button, and see what actually happens!
 
The page was last updated February 19, 2008