/* BasicInternalFrameTitlePane.java --
   Copyright (C) 2004, 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.plaf.basic;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

/**
 * This class acts as a titlebar for JInternalFrames.
 */
public class BasicInternalFrameTitlePane extends JComponent
{
  /**
   * The Action responsible for closing the JInternalFrame.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class CloseAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public CloseAction()
    {
      super("Close");
    }

    /**
     * This method is called when something closes the JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      if (frame.isClosable())
        {
          try
            {
              frame.setClosed(true);
            }
          catch (PropertyVetoException pve)
            {
              // We do nothing if the attempt has been vetoed.
            }
        }
    }
  }

  /**
   * This Action is responsible for iconifying the JInternalFrame.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class IconifyAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public IconifyAction()
    {
      super("Minimize");
    }

    /**
     * This method is called when the user wants to iconify the
     * JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      if (frame.isIconifiable() && ! frame.isIcon())
        {
          try
            {
              frame.setIcon(true);
            }
          catch (PropertyVetoException pve)
            {
              // We do nothing if the attempt has been vetoed.
            }
        }
    }
  }

  /**
   * This Action is responsible for maximizing the JInternalFrame.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class MaximizeAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public MaximizeAction()
    {
      super("Maximize");
    }
    /**
     * This method is called when the user wants to maximize the
     * JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      try
        {
          if (frame.isMaximizable() && ! frame.isMaximum())
            {
              frame.setMaximum(true);
              maxButton.setIcon(minIcon);
            }
          else if (frame.isMaximum())
            {
              frame.setMaximum(false);
              maxButton.setIcon(maxIcon);
            }
        }
      catch (PropertyVetoException pve)
        {
          // We do nothing if the attempt has been vetoed.
        }
    }
  }

  /**
   * This Action is responsible for dragging the JInternalFrame.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class MoveAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public MoveAction()
    {
      super("Move");
    }
    /**
     * This method is called when the user wants to drag the JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      // FIXME: Implement keyboard driven? move actions.
    }
  }

  /**
   * This Action is responsible for restoring the JInternalFrame. Restoring
   * the JInternalFrame is the same as setting the maximum property to false.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class RestoreAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public RestoreAction()
    {
      super("Restore");
    }
    /**
     * This method is called when the user wants to restore the
     * JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      if (frame.isMaximum())
        {
          try
            {
              frame.setMaximum(false);
            }
          catch (PropertyVetoException pve)
            {
              // We do nothing if the attempt has been vetoed.
            }
        }
    }
  }

  /**
   * This action is responsible for sizing the JInternalFrame.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class SizeAction extends AbstractAction
  {
    /**
     * Creates a new action.
     */
    public SizeAction()
    {
      super("Size");
    }
    /**
     * This method is called when the user wants to resize the JInternalFrame.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      // FIXME: Not sure how size actions should be handled.
    }
  }

  /**
   * This class is responsible for handling property change events from the
   * JInternalFrame and adjusting the Title Pane as necessary.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * This method is called when a PropertyChangeEvent is received by the
     * Title Pane.
     *
     * @param evt The PropertyChangeEvent.
     */
    public void propertyChange(PropertyChangeEvent evt)
    {
      String propName = evt.getPropertyName();
      if (propName.equals("closable"))
        {
          if (evt.getNewValue().equals(Boolean.TRUE))
            closeButton.setVisible(true);
          else
            closeButton.setVisible(false);
        }
      else if (propName.equals("iconable"))
        {
          if (evt.getNewValue().equals(Boolean.TRUE))
            iconButton.setVisible(true);
          else
            iconButton.setVisible(false);
        }
      else if (propName.equals("maximizable"))
        {
          if (evt.getNewValue().equals(Boolean.TRUE))
            maxButton.setVisible(true);
          else
            maxButton.setVisible(false);
        }
      enableActions();
    }
  }

  /**
   * This class acts as the MenuBar for the TitlePane. Clicking on the Frame
   * Icon in the top left corner will activate it.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class SystemMenuBar extends JMenuBar
  {
    /**
     * This method returns true if it can receive focus.
     *
     * @return True if this Component can receive focus.
     */
    public boolean isFocusTraversable()
    {
      return true;
    }

    /**
     * This method returns true if this Component is expected to paint all of
     * itself.
     *
     * @return True if this Component is expect to paint all of itself.
     */
    public boolean isOpaque()
    {
      return true;
    }

    /**
     * This method paints this Component.
     *
     * @param g The Graphics object to paint with.
     */
    public void paint(Graphics g)
    {
      Icon frameIcon = frame.getFrameIcon();
      if (frameIcon == null)
        frameIcon = BasicDesktopIconUI.defaultIcon;
      frameIcon.paintIcon(this, g, 0, 0);
    }

    /**
     * This method requests that focus be given to this Component.
     */
    public void requestFocus()
    {
      super.requestFocus();
    }
  }

  /**
   * This class acts as the Layout Manager for the TitlePane.
   *
   * @specnote Apparently this class was intended to be protected,
   *           but was made public by a compiler bug and is now
   *           public for compatibility.
   */
  public class TitlePaneLayout implements LayoutManager
  {
    /**
     * Creates a new <code>TitlePaneLayout</code> object.
     */
    public TitlePaneLayout()
    {
      // Do nothing.
    }

    /**
     * This method is called when adding a Component to the Container.
     *
     * @param name The name to reference the added Component by.
     * @param c The Component to add.
     */
    public void addLayoutComponent(String name, Component c)
    {
      // Do nothing.
    }

    /**
     * This method is called to lay out the children of the Title Pane.
     *
     * @param c The Container to lay out.
     */
    public void layoutContainer(Container c)
    {
      Dimension size = c.getSize();
      Insets insets = c.getInsets();
      int width = size.width - insets.left - insets.right;
      int height = size.height - insets.top - insets.bottom;

      // MenuBar is always present and located at the top left corner.
      Dimension menupref = menuBar.getPreferredSize();
      menuBar.setBounds(insets.left, insets.top, menupref.width, height);

      int loc = width + insets.left - 1;
      int top = insets.top + 1;
      int buttonHeight = height - 4;
      if (closeButton.isVisible())
        {
          int buttonWidth = closeIcon.getIconWidth();
          loc -= buttonWidth + 2;
          closeButton.setBounds(loc, top, buttonWidth, buttonHeight);
        }

      if (maxButton.isVisible())
        {
          int buttonWidth = maxIcon.getIconWidth();
          loc -= buttonWidth + 2;
          maxButton.setBounds(loc, top, buttonWidth, buttonHeight);
        }

      if (iconButton.isVisible())
        {
          int buttonWidth = iconIcon.getIconWidth();
          loc -= buttonWidth + 2;
          iconButton.setBounds(loc, top, buttonWidth, buttonHeight);
        }

      if (title != null)
        title.setBounds(insets.left + menupref.width, insets.top,
                        loc - menupref.width - insets.left, height);
    }

    /**
     * This method returns the minimum size of the given Container given the
     * children that it has.
     *
     * @param c The Container to get a minimum size for.
     *
     * @return The minimum size of the Container.
     */
    public Dimension minimumLayoutSize(Container c)
    {
      return preferredLayoutSize(c);
    }

    /**
     * This method returns the preferred size of the given Container taking
     * into account the children that it has.
     *
     * @param c The Container to lay out.
     *
     * @return The preferred size of the Container.
     */
    public Dimension preferredLayoutSize(Container c)
    {
      return new Dimension(22, 18);
    }

    /**
     * This method is called when removing a Component from the Container.
     *
     * @param c The Component to remove.
     */
    public void removeLayoutComponent(Component c)
    {
      // Nothing to do here.
    }
  }

  /**
   * This helper class is used to create the minimize, maximize and close
   * buttons in the top right corner of the Title Pane. These buttons are
   * special since they cannot be given focus and have no border.
   */
  private class PaneButton extends JButton
  {
    /**
     * Creates a new PaneButton object with the given Action.
     *
     * @param a The Action that the button uses.
     */
    public PaneButton(Action a)
    {
      super(a);
      setMargin(new Insets(0, 0, 0, 0));
    }

    /**
     * This method returns true if the Component can be focused.
     *
     * @return false.
     */
    public boolean isFocusable()
    {
      // These buttons cannot be given focus.
      return false;
    }

  }

  /** The action command for the Close action. */
  protected static final String CLOSE_CMD;

  /** The action command for the Minimize action. */
  protected static final String ICONIFY_CMD;

  /** The action command for the Maximize action. */
  protected static final String MAXIMIZE_CMD;

  /** The action command for the Move action. */
  protected static final String MOVE_CMD;

  /** The action command for the Restore action. */
  protected static final String RESTORE_CMD;

  /** The action command for the Size action. */
  protected static final String SIZE_CMD;

  /** The action associated with closing the JInternalFrame. */
  protected Action closeAction;

  /** The action associated with iconifying the JInternalFrame. */
  protected Action iconifyAction;

  /** The action associated with maximizing the JInternalFrame. */
  protected Action maximizeAction;

  /** The action associated with moving the JInternalFrame. */
  protected Action moveAction;

  /** The action associated with restoring the JInternalFrame. */
  protected Action restoreAction;

  /** The action associated with resizing the JInternalFrame. */
  protected Action sizeAction;

  /** The button that closes the JInternalFrame. */
  protected JButton closeButton;

  /** The button that iconifies the JInternalFrame. */
  protected JButton iconButton;

  /** The button that maximizes the JInternalFrame. */
  protected JButton maxButton;

  /** The icon displayed in the restore button. */
  protected Icon minIcon = BasicIconFactory.createEmptyFrameIcon();

  /** The icon displayed in the maximize button. */
  protected Icon maxIcon = BasicIconFactory.createEmptyFrameIcon();

  /** The icon displayed in the iconify button. */
  protected Icon iconIcon = BasicIconFactory.createEmptyFrameIcon();

  /** The icon displayed in the close button. */
  protected Icon closeIcon;

  /** The JInternalFrame that this TitlePane is used in. */
  protected JInternalFrame frame;

  /** The JMenuBar that is located at the top left of the Title Pane. */
  protected JMenuBar menuBar;

  /** The JMenu inside the menuBar. */
  protected JMenu windowMenu;

  /**
   * The text color of the TitlePane when the JInternalFrame is not selected.
   */
  protected Color notSelectedTextColor;

  /**
   * The background color of the TitlePane when the JInternalFrame is not
   * selected.
   */
  protected Color notSelectedTitleColor;

  /** The text color of the titlePane when the JInternalFrame is selected. */
  protected Color selectedTextColor;

  /**
   * The background color of the TitlePane when the JInternalFrame is
   * selected.
   */
  protected Color selectedTitleColor;

  /** The Property Change listener that listens to the JInternalFrame. */
  protected PropertyChangeListener propertyChangeListener;

  /**
   * The label used to display the title. This label is not added to the
   * TitlePane.
   * This is package-private to avoid an accessor method.
   */
  transient JLabel title;

  static
    {
      // not constants in JDK
      CLOSE_CMD = "Close";
      ICONIFY_CMD = "Minimize";
      MAXIMIZE_CMD = "Maximize";
      MOVE_CMD = "Move";
      RESTORE_CMD = "Restore";
      SIZE_CMD = "Size";
    }

  /**
   * Creates a new BasicInternalFrameTitlePane object that is used in the
   * given JInternalFrame.
   *
   * @param f The JInternalFrame this BasicInternalFrameTitlePane will be used
   *        in.
   */
  public BasicInternalFrameTitlePane(JInternalFrame f)
  {
    frame = f;
    setLayout(createLayout());
    title = new JLabel();
    title.setHorizontalAlignment(SwingConstants.LEFT);
    title.setHorizontalTextPosition(SwingConstants.LEFT);
    title.setOpaque(false);
    setOpaque(true);

    setBackground(Color.LIGHT_GRAY);
    setOpaque(true);

    installTitlePane();
  }

  /**
   * This method installs the TitlePane onto the JInternalFrameTitlePane. It
   * also creates any children components that need to be created and adds
   * listeners to the appropriate components.
   */
  protected void installTitlePane()
  {
    installDefaults();
    installListeners();
    createActions();

    assembleSystemMenu();

    createButtons();
    setButtonIcons();
    addSubComponents();
    enableActions();
  }

  /**
   * This method adds the sub components to the TitlePane.
   */
  protected void addSubComponents()
  {
    add(menuBar);

    add(closeButton);
    add(iconButton);
    add(maxButton);
  }

  /**
   * This method creates the actions that are used to manipulate the
   * JInternalFrame.
   */
  protected void createActions()
  {
    closeAction = new CloseAction();
    closeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, CLOSE_CMD);

    iconifyAction = new IconifyAction();
    iconifyAction.putValue(AbstractAction.ACTION_COMMAND_KEY, ICONIFY_CMD);

    maximizeAction = new MaximizeAction();
    maximizeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, MAXIMIZE_CMD);

    sizeAction = new SizeAction();
    sizeAction.putValue(AbstractAction.ACTION_COMMAND_KEY, SIZE_CMD);

    restoreAction = new RestoreAction();
    restoreAction.putValue(AbstractAction.ACTION_COMMAND_KEY, RESTORE_CMD);

    moveAction = new MoveAction();
    moveAction.putValue(AbstractAction.ACTION_COMMAND_KEY, MOVE_CMD);
  }

  /**
   * This method is used to install the listeners.
   */
  protected void installListeners()
  {
    propertyChangeListener = createPropertyChangeListener();
    frame.addPropertyChangeListener(propertyChangeListener);
  }

  /**
   * This method is used to uninstall the listeners.
   */
  protected void uninstallListeners()
  {
    frame.removePropertyChangeListener(propertyChangeListener);
    propertyChangeListener = null;
  }

  /**
   * This method installs the defaults determined by the look and feel.
   */
  protected void installDefaults()
  {
    title.setFont(UIManager.getFont("InternalFrame.titleFont"));
    selectedTextColor = UIManager.getColor("InternalFrame.activeTitleForeground");
    selectedTitleColor = UIManager.getColor("InternalFrame.activeTitleBackground");
    notSelectedTextColor = UIManager.getColor("InternalFrame.inactiveTitleForeground");
    notSelectedTitleColor = UIManager.getColor("InternalFrame.inactiveTitleBackground");

    closeIcon = UIManager.getIcon("InternalFrame.closeIcon");
    iconIcon = UIManager.getIcon("InternalFrame.iconifyIcon");
    maxIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
  }

  /**
   * This method uninstalls the defaults.
   */
  protected void uninstallDefaults()
  {
    setFont(null);
    selectedTextColor = null;
    selectedTitleColor = null;
    notSelectedTextColor = null;
    notSelectedTitleColor = null;

    closeIcon = null;
    iconIcon = null;
    maxIcon = null;
  }

  /**
   * This method creates the buttons used in the TitlePane.
   */
  protected void createButtons()
  {
    closeButton = new PaneButton(closeAction);
    closeButton.setText(null);
    if (!frame.isClosable())
      closeButton.setVisible(false);
    iconButton = new PaneButton(iconifyAction);
    iconButton.setText(null);
    if (!frame.isIconifiable())
      iconButton.setVisible(false);
    maxButton = new PaneButton(maximizeAction);
    maxButton.setText(null);
    if (!frame.isMaximizable())
      maxButton.setVisible(false);
  }

  /**
   * Set icons for the minimize-, maximize- and close-buttons.
   */
  protected void setButtonIcons()
  {
    if (closeIcon != null && closeButton != null)
      closeButton.setIcon(closeIcon);
    if (iconIcon != null && iconButton != null)
      iconButton.setIcon(iconIcon);
    if (maxIcon != null && maxButton != null)
      maxButton.setIcon(maxIcon);
  }

  /**
   * This method creates the MenuBar used in the TitlePane.
   */
  protected void assembleSystemMenu()
  {
    menuBar = createSystemMenuBar();
    windowMenu = createSystemMenu();

    menuBar.add(windowMenu);

    addSystemMenuItems(windowMenu);
    enableActions();
  }

  /**
   * This method adds the MenuItems to the given JMenu.
   *
   * @param systemMenu The JMenu to add MenuItems to.
   */
  protected void addSystemMenuItems(JMenu systemMenu)
  {
    JMenuItem tmp;

    tmp = new JMenuItem(RESTORE_CMD);
    tmp.addActionListener(restoreAction);
    tmp.setMnemonic(KeyEvent.VK_R);
    systemMenu.add(tmp);

    tmp = new JMenuItem(MOVE_CMD);
    tmp.addActionListener(moveAction);
    tmp.setMnemonic(KeyEvent.VK_M);
    systemMenu.add(tmp);

    tmp = new JMenuItem(SIZE_CMD);
    tmp.addActionListener(sizeAction);
    tmp.setMnemonic(KeyEvent.VK_S);
    systemMenu.add(tmp);

    tmp = new JMenuItem(ICONIFY_CMD);
    tmp.addActionListener(iconifyAction);
    tmp.setMnemonic(KeyEvent.VK_N);
    systemMenu.add(tmp);

    tmp = new JMenuItem(MAXIMIZE_CMD);
    tmp.addActionListener(maximizeAction);
    tmp.setMnemonic(KeyEvent.VK_X);
    systemMenu.add(tmp);

    systemMenu.addSeparator();

    tmp = new JMenuItem(CLOSE_CMD);
    tmp.addActionListener(closeAction);
    tmp.setMnemonic(KeyEvent.VK_C);
    systemMenu.add(tmp);
  }

  /**
   * This method creates a new JMenubar.
   *
   * @return A new JMenuBar.
   */
  protected JMenuBar createSystemMenuBar()
  {
    if (menuBar == null)
      menuBar = new SystemMenuBar();
    menuBar.removeAll();
    return menuBar;
  }

  /**
   * This method creates a new JMenu.
   *
   * @return A new JMenu.
   */
  protected JMenu createSystemMenu()
  {
    if (windowMenu == null)
      windowMenu = new JMenu();
    windowMenu.removeAll();
    return windowMenu;
  }

  /**
   * This method programmatically shows the JMenu.
   */
  protected void showSystemMenu()
  {
    // FIXME: Untested as KeyEvents are not hooked up.
    menuBar.getMenu(1).getPopupMenu().show();
  }

  /**
   * This method paints the TitlePane.
   *
   * @param g The Graphics object to paint with.
   */
  public void paintComponent(Graphics g)
  {
    paintTitleBackground(g);
    if (frame.getTitle() != null && title != null)
      {
        Color saved = g.getColor();
        Font f = title.getFont();
        g.setFont(f);
        FontMetrics fm = g.getFontMetrics(f);
        if (frame.isSelected())
          g.setColor(selectedTextColor);
        else
          g.setColor(notSelectedTextColor);
        title.setText(getTitle(frame.getTitle(), fm, title.getBounds().width));
        SwingUtilities.paintComponent(g, title, null, title.getBounds());
        g.setColor(saved);
      }
  }

  /**
   * This method paints the TitlePane's background.
   *
   * @param g The Graphics object to paint with.
   */
  protected void paintTitleBackground(Graphics g)
  {
    if (!isOpaque())
      return;

    Color saved = g.getColor();
    Dimension dims = getSize();

    Color bg = getBackground();
    if (frame.isSelected())
      bg = selectedTitleColor;
    else
      bg = notSelectedTitleColor;
    g.setColor(bg);
    g.fillRect(0, 0, dims.width, dims.height);
    g.setColor(saved);
  }

  /**
   * This method returns the title string based on the available width and the
   * font metrics.
   *
   * @param text The desired title.
   * @param fm The FontMetrics of the font used.
   * @param availableWidth The available width.
   *
   * @return The allowable string.
   */
  protected String getTitle(String text, FontMetrics fm, int availableWidth)
  {
    Rectangle vr = new Rectangle(0, 0, availableWidth, fm.getHeight());
    Rectangle ir = new Rectangle();
    Rectangle tr = new Rectangle();
    String value = SwingUtilities.layoutCompoundLabel(this, fm, text, null,
                                                      SwingConstants.CENTER,
                                                      SwingConstants.LEFT,
                                                      SwingConstants.CENTER,
                                                      SwingConstants.LEFT, vr,
                                                      ir, tr, 0);
    return value;
  }

  /**
   * This method fires something similar to a WINDOW_CLOSING event.
   *
   * @param frame The JInternalFrame that is being closed.
   */
  protected void postClosingEvent(JInternalFrame frame)
  {
    // FIXME: Implement postClosingEvent when I figure out what
    // it's supposed to do.
    // It says that this fires an WINDOW_CLOSING like event.
    // So the closest thing is some kind of InternalFrameEvent.
    // But none is fired.
    // Can't see it called or anything.
  }

  /**
   * This method enables the actions for the TitlePane given the frame's
   * properties.
   */
  protected void enableActions()
  {
    closeAction.setEnabled(frame.isClosable());

    iconifyAction.setEnabled(frame.isIconifiable());
    // The maximize action is responsible for restoring it
    // as well, if clicked from the button
    maximizeAction.setEnabled(frame.isMaximizable());

    // The restoring action is only active when selected
    // from the menu.
    restoreAction.setEnabled(frame.isMaximum());

    sizeAction.setEnabled(frame.isResizable());

    // FIXME: Tie MoveAction enabled status to a variable.
    moveAction.setEnabled(false);
  }

  /**
   * This method creates a new PropertyChangeListener.
   *
   * @return A new PropertyChangeListener.
   */
  protected PropertyChangeListener createPropertyChangeListener()
  {
    return new PropertyChangeHandler();
  }

  /**
   * This method creates a new LayoutManager for the TitlePane.
   *
   * @return A new LayoutManager.
   */
  protected LayoutManager createLayout()
  {
    return new TitlePaneLayout();
  }
}
