package extensions.awt;
import java.awt.*;

/**
 * Implement your action event handler by overriding
 * the run() method in your derived class.
 * Handlers that may not block should also override
 * the mayBlock() method to avoid running in a separate
 * thread when permissable.  If mayBlock() returns
 * true, the handler is executed in a separate
 * thread from the awt toolkit callback thread.  If
 * the callback thread were to block the GUI would
 * crash!
 * @see extensions.awt.ActionProtocol
 * @see extensions.awt.FrameExtended#action
 * @see extensions.awt.DialogExtended#action
 * @see extensions.awt.MenuItemAction
 * @see extensions.awt.ButtonAction
 * @version 1.0.2
 * @author John Webster Small
 */
public abstract class Action
  implements ActionProtocol, Runnable
{
  protected Component forward;
  protected Event evt;
  protected Object what;

  /** Constructs a action event handler. */
  public Action()  {}

  /**
    * Run action handler/adapter.  Override to define
    * your action event handler.
    * The actual parameters passed
    * to action() are available as data members of this
    * class instance, i.e. forward, evt, and what.
    * @see #action
    */
  public abstract void run();

  /** Returns true.  If your action handler never has
    * a possibility of not blocking you can override
    * this method to return false when it is guaranteed
    * no to block!
    * @see #action
    */
  public boolean mayBlock()
    { return true; }

  /**
    * An action event has occurred, perform the
    * required action and if there is a possibility
    * of blocking, execute action in a separate
    * thread.
    * @param forward the component (i.e. FrameExtended,
    *   DialogExtended) forwarding action event
    * @param evt the event that caused the action
    * @param what the action
    * @see #mayBlock
    * @see extensions.awt.ActionProtocol
    */
  public final void action
    (Component forward, Event evt, Object what)
  {
    this.forward = forward;
    this.evt = evt;
    this.what = what;
    if (mayBlock())
      (new Thread(this,"Action")).start();
    else
      run();
  }
}
