This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gui][PATCH] JInternalFrames


And here it is without printlns.

On Wed, 2004-06-09 at 16:35, Kim Ho wrote:
> Hi,
> 
> This implements JInternalFrame, JDesktopPane, JDesktopIcon + UI
> delegates + DefaultDesktopManager.
> 
> Cheers,
> 
> Kim
> 
> 2004-06-09  Kim Ho  <kho@redhat.com>
> 
> 	* Makefile.am: New files
> 	* Makefile.in: Regenerated
> 	* java/awt/Container.java
> 	(getComponentAt): Removed.
> 	* javax/swing/AbstractAction.java
> 	(ENABLED_PROPERTY): New property.
> 	(putValue): Fire PropertyChangeEvents.
> 	(setEnabled): ditto.
> 	(firePropertyChange): Javadoc and implement
> 	convenience method.
> 	* javax/swing/AbstractButton.java
> 	(setAction): Don't create PropertyChangeListener
> 	if new Action is null.
> 	(setIcon): Don't set icon till after comparing
> 	it.
> 	(configurePropertiesFromAction): Check mnemonic
> 	key before calling intValue().
> 	(createActionPropertyChangeListener): Check
> 	properties rather than bulk change.
> 	* javax/swing/DefaultDesktopManager.java:
> 	Implement.
> 	* javax/swing/DesktopManager.java:
> 	Jalopy and javadoc.
> 	* javax/swing/JComponent.java
> 	(fireVetoableChange): Implement.
> 	(paintImmediately): Use root component.
> 	* javax/swing/JDesktopPane.java: Implement
> 	* javax/swing/JInternalFrame.java: Implement
> 	* javax/swing/JLabel.java
> 	(getDisabledIcon): Return grayscaled icon if
> 	no disabled icon specified.
> 	* javax/swing/JMenuBar.java
> 	(getComponentAtIndex): Use getComponent
> 	* javax/swing/JOptionPane.java
> 	(getDesktopPaneForComponent): Use SwingUtilities'
> 	getAncestorOfClass
> 	(getFrameForComponent): ditto.
> 	* javax/swing/JSplitPane.java
> 	(remove): Use getComponent.
> 	* javax/swing/SwingUtilities.java
> 	(convertPoint): Implement.
> 	* javax/swing/plaf/basic/BasicButtonUI.java
> 	(paintButtonNormal): Check opaqueness before
> 	filling background.
> 	* javax/swing/plaf/basic/BasicDesktopIconUI.java:
> 	Implement
> 	* javax/swing/plaf/basic/BasicDesktopPaneUI.java:
> 	Implement.
> 	* javax/swing/plaf/basic/BasicInternalFrameTitlePane.java:
> 	Implement.
> 	* javax/swing/plaf/basic/BasicInternalFrameUI.java:
> 	Implement.
> 	* javax/swing/plaf/basic/BasicLookAndFeel.java:
> 	Change InternalFrame and Desktop colors.
> 	
> 	
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.361.2.13
diff -u -r1.361.2.13 Makefile.am
--- Makefile.am	20 May 2004 15:13:17 -0000	1.361.2.13
+++ Makefile.am	9 Jun 2004 20:46:57 -0000
@@ -1248,7 +1248,11 @@
 javax/swing/plaf/basic/BasicButtonListener.java \
 javax/swing/plaf/basic/BasicButtonUI.java \
 javax/swing/plaf/basic/BasicCheckBoxUI.java \
+javax/swing/plaf/basic/BasicDesktopIconUI.java \
+javax/swing/plaf/basic/BasicDesktopPaneUI.java \
 javax/swing/plaf/basic/BasicGraphicsUtils.java \
+javax/swing/plaf/basic/BasicInternalFrameTitlePane.java \
+javax/swing/plaf/basic/BasicInternalFrameUI.java \
 javax/swing/plaf/basic/BasicLabelUI.java \
 javax/swing/plaf/basic/BasicListUI.java \
 javax/swing/plaf/basic/BasicMenuUI.java \
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.in,v
retrieving revision 1.385.2.13
diff -u -r1.385.2.13 Makefile.in
--- Makefile.in	20 May 2004 15:13:17 -0000	1.385.2.13
+++ Makefile.in	9 Jun 2004 20:46:59 -0000
@@ -953,7 +953,11 @@
 javax/swing/plaf/basic/BasicButtonListener.java \
 javax/swing/plaf/basic/BasicButtonUI.java \
 javax/swing/plaf/basic/BasicCheckBoxUI.java \
+javax/swing/plaf/basic/BasicDesktopIconUI.java \
+javax/swing/plaf/basic/BasicDesktopPaneUI.java \
 javax/swing/plaf/basic/BasicGraphicsUtils.java \
+javax/swing/plaf/basic/BasicInternalFrameTitlePane.java \
+javax/swing/plaf/basic/BasicInternalFrameUI.java \
 javax/swing/plaf/basic/BasicLabelUI.java \
 javax/swing/plaf/basic/BasicListUI.java \
 javax/swing/plaf/basic/BasicMenuUI.java \
@@ -3001,7 +3005,11 @@
 javax/swing/plaf/basic/BasicButtonListener.lo \
 javax/swing/plaf/basic/BasicButtonUI.lo \
 javax/swing/plaf/basic/BasicCheckBoxUI.lo \
+javax/swing/plaf/basic/BasicDesktopIconUI.lo \
+javax/swing/plaf/basic/BasicDesktopPaneUI.lo \
 javax/swing/plaf/basic/BasicGraphicsUtils.lo \
+javax/swing/plaf/basic/BasicInternalFrameTitlePane.lo \
+javax/swing/plaf/basic/BasicInternalFrameUI.lo \
 javax/swing/plaf/basic/BasicLabelUI.lo \
 javax/swing/plaf/basic/BasicListUI.lo \
 javax/swing/plaf/basic/BasicMenuUI.lo \
@@ -5095,8 +5103,12 @@
 .deps/javax/swing/plaf/basic/BasicButtonUI.P \
 .deps/javax/swing/plaf/basic/BasicCheckBoxMenuItemUI.P \
 .deps/javax/swing/plaf/basic/BasicCheckBoxUI.P \
+.deps/javax/swing/plaf/basic/BasicDesktopIconUI.P \
+.deps/javax/swing/plaf/basic/BasicDesktopPaneUI.P \
 .deps/javax/swing/plaf/basic/BasicGraphicsUtils.P \
 .deps/javax/swing/plaf/basic/BasicIconFactory.P \
+.deps/javax/swing/plaf/basic/BasicInternalFrameTitlePane.P \
+.deps/javax/swing/plaf/basic/BasicInternalFrameUI.P \
 .deps/javax/swing/plaf/basic/BasicLabelUI.P \
 .deps/javax/swing/plaf/basic/BasicListUI.P \
 .deps/javax/swing/plaf/basic/BasicLookAndFeel.P \
Index: java/awt/Container.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/Container.java,v
retrieving revision 1.34.2.11
diff -u -r1.34.2.11 Container.java
--- java/awt/Container.java	9 Jun 2004 20:33:02 -0000	1.34.2.11
+++ java/awt/Container.java	9 Jun 2004 20:47:00 -0000
@@ -876,11 +876,6 @@
   {
     return locate (x, y);
   }
-  
-  public Component getComponentAt(int index)
-  {
-    return component[index];
-  }
 
   /**
    * Returns the component located at the specified point.  This is done
Index: javax/swing/AbstractAction.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractAction.java,v
retrieving revision 1.6
diff -u -r1.6 AbstractAction.java
--- javax/swing/AbstractAction.java	23 Jan 2004 15:19:28 -0000	1.6
+++ javax/swing/AbstractAction.java	9 Jun 2004 20:47:00 -0000
@@ -60,6 +60,8 @@
    * enabled
    */
   protected boolean enabled = true;
+  
+  public static final String ENABLED_PROPERTY = "enabled";
 
   /**
    * changeSupport
@@ -162,7 +164,12 @@
    */
   public void putValue(String key, Object value)
   {
-    store.put(key, value);
+    Object old = getValue(key);
+    if (old != value)
+    {
+      store.put(key, value);
+      firePropertyChange(key, old, value);
+    }
   }
 
   /**
@@ -182,7 +189,11 @@
    */
   public void setEnabled(boolean enabled)
   {
-    this.enabled = enabled;
+    if (enabled != this.enabled)
+    {
+      this.enabled = enabled;
+      firePropertyChange(ENABLED_PROPERTY, !this.enabled, this.enabled);
+    }
   }
 
   /**
@@ -195,17 +206,31 @@
   }
 
   /**
-   * firePropertyChange
+   * This method fires a PropertyChangeEvent given the propertyName 
+   * and the old and new values.
    *
-   * @param propertyName TODO
-   * @param oldValue TODO
-   * @param newValue TODO
+   * @param propertyName The property that changed.
+   * @param oldValue The old value of the property.
+   * @param newValue The new value of the property.
    */
   protected void firePropertyChange(String propertyName, Object oldValue,
                                     Object newValue)
   {
     changeSupport.firePropertyChange(propertyName, oldValue, newValue);
   }
+  
+  /**
+   * This convenience method fires a PropertyChangeEvent given 
+   * the propertyName and the old and new values.
+   *
+   * @param propertyName The property that changed.
+   * @param oldValue The old value of the property.
+   * @param newValue The new value of the property.
+   */
+  private void firePropertyChange(String propertyName, boolean oldValue, boolean newValue)
+  {
+    changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+  }
 
   /**
    * addPropertyChangeListener
Index: javax/swing/AbstractButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/AbstractButton.java,v
retrieving revision 1.5.2.5
diff -u -r1.5.2.5 AbstractButton.java
--- javax/swing/AbstractButton.java	8 Jun 2004 20:32:14 -0000	1.5.2.5
+++ javax/swing/AbstractButton.java	9 Jun 2004 20:47:00 -0000
@@ -1039,15 +1039,17 @@
             action.removePropertyChangeListener(actionPropertyChangeListener);
             actionPropertyChangeListener = null;
           }
-        actionPropertyChangeListener = createActionPropertyChangeListener(a);
+
+
   }
+  
 
     Action old = action;
     action = a;
     configurePropertiesFromAction(action);
-
     if (action != null)
       {
+        actionPropertyChangeListener = createActionPropertyChangeListener(a);      
         action.addPropertyChangeListener(actionPropertyChangeListener);
         addActionListener(action);
       }
@@ -1070,15 +1072,15 @@
    * @param i The new default icon
    */
   public void setIcon(Icon i)
+  {
+    if (default_icon != i)
       {
-    Icon old = default_icon;
-    default_icon = i;
-    if (old != i)
-      {
-        firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
+    Icon old = default_icon;      
+    default_icon = i;      
+    firePropertyChange(ICON_CHANGED_PROPERTY, old, i);
     revalidate();
     repaint();
-  }
+      }
   }
 
   /**
@@ -1382,7 +1384,8 @@
         setIcon((Icon)(a.getValue(Action.SMALL_ICON)));
         setEnabled(a.isEnabled());
         setToolTipText((String)(a.getValue(Action.SHORT_DESCRIPTION)));
-        setMnemonic(((Integer)(a.getValue(Action.MNEMONIC_KEY))).intValue());
+	if (a.getValue(Action.MNEMONIC_KEY) != null)
+          setMnemonic(((Integer)(a.getValue(Action.MNEMONIC_KEY))).intValue());
         setActionCommand((String)(a.getValue(Action.ACTION_COMMAND_KEY)));
       }
   }
@@ -1440,9 +1443,21 @@
       {
         public void propertyChange(PropertyChangeEvent e)
         {
-          Action act = (Action)(e.getSource());
-          AbstractButton.this.configurePropertiesFromAction(act);
-        }
+          Action act = (Action) (e.getSource());	
+	  if (e.getPropertyName().equals(AbstractAction.ENABLED_PROPERTY))
+	    setEnabled(act.isEnabled());
+	  else if (e.getPropertyName().equals(Action.NAME))
+            setText((String)(act.getValue(Action.NAME)));
+	  else if (e.getPropertyName().equals(Action.SMALL_ICON))
+	    setIcon((Icon)(act.getValue(Action.SMALL_ICON)));
+	  else if (e.getPropertyName().equals(Action.SHORT_DESCRIPTION))
+            setToolTipText((String)(act.getValue(Action.SHORT_DESCRIPTION)));
+	  else if (e.getPropertyName().equals(Action.MNEMONIC_KEY))
+            if (act.getValue(Action.MNEMONIC_KEY) != null)
+              setMnemonic(((Integer)(act.getValue(Action.MNEMONIC_KEY))).intValue());
+	  else if (e.getPropertyName().equals(Action.ACTION_COMMAND_KEY))
+            setActionCommand((String)(act.getValue(Action.ACTION_COMMAND_KEY)));
+	}
       };
   }
 
Index: javax/swing/DefaultDesktopManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DefaultDesktopManager.java,v
retrieving revision 1.3
diff -u -r1.3 DefaultDesktopManager.java
--- javax/swing/DefaultDesktopManager.java	9 Jan 2004 10:18:47 -0000	1.3
+++ javax/swing/DefaultDesktopManager.java	9 Jun 2004 20:47:01 -0000
@@ -37,249 +37,618 @@
 
 package javax.swing;
 
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
 import java.awt.Rectangle;
+import java.beans.PropertyVetoException;
 import java.io.Serializable;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+
 
 /**
- * DefaultDesktopManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * DefaultDesktopManager is the default implementation of DesktopManager for
+ * swing. It implements the basic beaviours for JInternalFrames in arbitrary
+ * parents. The methods provided by the class are not meant to be called by
+ * the user, instead, the JInternalFrame methods will call these methods.
  */
 public class DefaultDesktopManager implements DesktopManager, Serializable
 {
+  /** DOCUMENT ME! */
   static final long serialVersionUID = 4657624909838017887L;
 
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * HAS_BEEN_ICONIFIED_PROPERTY
-	 */
-	static final String HAS_BEEN_ICONIFIED_PROPERTY = ""; // TODO
-
-	/**
-	 * DEFAULT_DRAG_MODE
-	 */
-	static final int DEFAULT_DRAG_MODE = 0; // TODO
-
-	/**
-	 * OUTLINE_DRAG_MODE
-	 */
-	static final int OUTLINE_DRAG_MODE = 0; // TODO
-
-	/**
-	 * FASTER_DRAG_MODE
-	 */
-	static final int FASTER_DRAG_MODE = 0; // TODO
-
-	/**
-	 * dragMode
-	 */
-	int dragMode;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor DefaultDesktopManager
-	 */
-	public DefaultDesktopManager() {
-		// TODO
-	} // DefaultDesktopManager()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * openFrame
-	 * @param frame TODO
-	 */
-	public void openFrame(JInternalFrame frame) {
-		// TODO
-	} // openFrame()
-
-	/**
-	 * closeFrame
-	 * @param frame TODO
-	 */
-	public void closeFrame(JInternalFrame frame) {
-		// TODO
-	} // closeFrame()
-
-	/**
-	 * maximizeFrame
-	 * @param frame TODO
-	 */
-	public void maximizeFrame(JInternalFrame frame) {
-		// TODO
-	} // maximizeFrame()
-
-	/**
-	 * minimizeFrame
-	 * @param frame TODO
-	 */
-	public void minimizeFrame(JInternalFrame frame) {
-		// TODO
-	} // minimizeFrame()
-
-	/**
-	 * iconifyFrame
-	 * @param frame TODO
-	 */
-	public void iconifyFrame(JInternalFrame frame) {
-		// TODO
-	} // iconifyFrame()
-
-	/**
-	 * deiconifyFrame
-	 * @param frame TODO
-	 */
-	public void deiconifyFrame(JInternalFrame frame) {
-		// TODO
-	} // deiconifyFrame()
-
-	/**
-	 * activateFrame
-	 * @param frame TODO
-	 */
-	public void activateFrame(JInternalFrame frame) {
-		// TODO
-	} // activateFrame()
-
-	/**
-	 * deactivateFrame
-	 * @param frame TODO
-	 */
-	public void deactivateFrame(JInternalFrame frame) {
-		// TODO
-	} // deactivateFrame()
-
-	/**
-	 * beginDraggingFrame
-	 * @param component TODO
-	 */
-	public void beginDraggingFrame(JComponent component) {
-		// TODO
-	} // beginDraggingFrame()
-
-	/**
-	 * dragFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 */
-	public void dragFrame(JComponent component, int newX, int newY) {
-		// TODO
-	} // dragFrame()
-
-	/**
-	 * endDraggingFrame
-	 * @param component TODO
-	 */
-	public void endDraggingFrame(JComponent component) {
-		// TODO
-	} // endDraggingFrame()
-
-	/**
-	 * beginResizingFrame
-	 * @param component TODO
-	 * @param direction TODO
-	 */
-	public void beginResizingFrame(JComponent component, int direction) {
-		// TODO
-	} // beginResizingFrame()
-
-	/**
-	 * resizeFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 * @param newWidth TODO
-	 * @param newHeight TODO
-	 */
-	public void resizeFrame(JComponent component, int newX, int newY,
-			int newWidth, int newHeight) {
-		// TODO
-	} // resizeFrame()
-
-	/**
-	 * endResizingFrame
-	 * @param component TODO
-	 */
-	public void endResizingFrame(JComponent component) {
-		// TODO
-	} // endResizingFrame()
-
-	/**
-	 * setBoundsForFrame
-	 * @param component TODO
-	 * @param newX TODO
-	 * @param newY TODO
-	 * @param newWidth TODO
-	 * @param newHeight TODO
-	 */
-	public void setBoundsForFrame(JComponent component, int newX,
-			int newY, int newWidth, int newHeight) {
-		// TODO
-	} // setBoundsForFrame()
-
-	/**
-	 * removeIconFor
-	 * @param frame TODO
-	 */
-	protected void removeIconFor(JInternalFrame frame) {
-		// TODO
-	} // removeIconFor()
-
-	/**
-	 * getBoundsForIconOf
-	 * @param frame TODO
-	 * @returns Rectangle
-	 */
-	protected Rectangle getBoundsForIconOf(JInternalFrame frame) {
-		return null; // TODO
-	} // getBoundsForIconOf()
-
-	/**
-	 * setPreviousBounds
-	 * @param frame TODO
-	 * @param rect TODO
-	 */
-	protected void setPreviousBounds(JInternalFrame frame, Rectangle rect) {
-		// TODO
-	} // setPreviousBounds()
-
-	/**
-	 * getPreviousBounds
-	 * @param frame TODO
-	 * @returns Rectangle
-	 */
-	protected Rectangle getPreviousBounds(JInternalFrame frame) {
-		return null; // TODO
-	} // getPreviousBounds()
-
-	/**
-	 * setWasIcon
-	 * @param frame TODO
-	 * @param value TODO
-	 */
-	protected void setWasIcon(JInternalFrame frame, Boolean value) {
-		// TODO
-	} // setWasIcon()
-
-	/**
-	 * wasIcon
-	 * @param frame TODO
-	 * @returns boolean
-	 */
-	protected boolean wasIcon(JInternalFrame frame) {
-		return false; // TODO
-	} // wasIcon()
-
+  /** The property change event fired when the wasIcon property changes. */
+  static final String WAS_ICON_ONCE_PROPERTY = "wasIconOnce";
 
+  /**
+   * The method of dragging used by the JDesktopPane that parents the
+   * JInternalFrame that is being dragged.
+   */
+  private int currentDragMode = 0;
+
+  /**
+   * The cache of the bounds used to draw the outline rectangle when
+   * OUTLINE_DRAG_MODE is used.
+   */
+  private transient Rectangle dragCache = new Rectangle();
+
+  /**
+   * A cached JDesktopPane that is stored when the JInternalFrame is initially
+   * dragged.
+   */
+  private transient Container pane;
+
+  /**
+   * An array of Rectangles that holds the bounds of the JDesktopIcons in the 
+   * JDesktopPane when looking for where to place a new icon.
+   */
+  private transient Rectangle[] iconRects;
+
+  /**
+   * This creates a new DefaultDesktopManager object.
+   */
+  public DefaultDesktopManager()
+  {
+  } // DefaultDesktopManager()
+
+  /**
+   * This method is not normally called since the user will typically add the
+   * JInternalFrame to a Container. If this is called, it will try to
+   * determine the parent of the JInternalFrame and remove any icon that
+   * represents this JInternalFrame and add this JInternalFrame.
+   *
+   * @param frame The JInternalFrame to open.
+   */
+  public void openFrame(JInternalFrame frame)
+  {
+    Container c = frame.getParent();
+    if (c == null)
+      c = frame.getDesktopIcon().getParent();
+    if (c == null)
+      return;
+
+    c.remove(frame.getDesktopIcon());
+    c.add(frame);
+    frame.setVisible(true);
+  } // openFrame()
+
+  /**
+   * This method removes the JInternalFrame and JDesktopIcon (if one is
+   * present) from their parents.
+   *
+   * @param frame The JInternalFrame to close.
+   */
+  public void closeFrame(JInternalFrame frame)
+  {
+    Container c = frame.getParent();
+    frame.doDefaultCloseAction();
+
+    if (c != null)
+      {
+	if (frame.isIcon())
+	  c.remove(frame.getDesktopIcon());
+	else
+	  c.remove(frame);
+	c.repaint();
+      }
+  } // closeFrame()
+
+  /**
+   * This method resizes the JInternalFrame to match its parent's bounds.
+   *
+   * @param frame The JInternalFrame to maximize.
+   */
+  public void maximizeFrame(JInternalFrame frame)
+  {
+    // Can't maximize from iconified state.
+    // It can only return to maximized state, but that would fall under
+    // deiconify.
+    if (frame.isIcon())
+      return;
+    frame.setNormalBounds(frame.getBounds());
+
+    Container p = frame.getParent();
+    if (p != null)
+      {
+	Rectangle pBounds = p.getBounds();
+	Insets insets = p.getInsets();
+	pBounds.width -= insets.left + insets.right;
+	pBounds.height -= insets.top + insets.bottom;
+
+	setBoundsForFrame(frame, 0, 0, pBounds.width, pBounds.height);
+      }
+    if (p instanceof JDesktopPane)
+      ((JDesktopPane) p).setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+  } // maximizeFrame()
+
+  /**
+   * This method restores the JInternalFrame's bounds to what they were
+   * previous to the setMaximize call.
+   *
+   * @param frame The JInternalFrame to minimize.
+   */
+  public void minimizeFrame(JInternalFrame frame)
+  {
+    Rectangle normalBounds = frame.getNormalBounds();
+
+    JDesktopPane p = frame.getDesktopPane();
+    if (p != null)
+      p.setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+
+    setBoundsForFrame(frame, normalBounds.x, normalBounds.y,
+                      normalBounds.width, normalBounds.height);
+  } // minimizeFrame()
+
+  /**
+   * This method removes the JInternalFrame from its parent and adds its
+   * JDesktopIcon representation.
+   *
+   * @param frame The JInternalFrame to iconify.
+   */
+  public void iconifyFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+    JDesktopIcon icon = frame.getDesktopIcon();
+    if (p != null && p.getSelectedFrame() == frame)
+      p.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+
+    Container c = frame.getParent();
+
+    if (! wasIcon(frame))
+      {
+	Rectangle r = getBoundsForIconOf(frame);
+	icon.setBounds(r);
+	setWasIcon(frame, true);
+      }
+
+    if (c != null)
+      {
+	if (icon != null)
+	  {
+	    c.add(icon);
+	    icon.setVisible(true);
+	  }
+	c.remove(frame);
+      }
+  } // iconifyFrame()
+
+  /**
+   * This method removes the JInternalFrame's JDesktopIcon representation and
+   * adds the JInternalFrame back to its parent.
+   *
+   * @param frame The JInternalFrame to deiconify.
+   */
+  public void deiconifyFrame(JInternalFrame frame)
+  {
+    JDesktopIcon icon = frame.getDesktopIcon();
+    Container c = icon.getParent();
+
+    removeIconFor(frame);
+    c.add(frame);
+    frame.setVisible(true);
+
+    if (! frame.isSelected())
+      {
+	JDesktopPane p = frame.getDesktopPane();
+	if (p != null)
+	  p.setSelectedFrame(frame);
+	else
+	  {
+	    try
+	      {
+		frame.setSelected(true);
+	      }
+	    catch (PropertyVetoException e)
+	      {
+		// Do nothing.
+	      }
+	  }
+      }
+
+    c.invalidate();
+  } // deiconifyFrame()
+
+  /**
+   * This method activates the JInternalFrame by moving it to the front and
+   * selecting it.
+   *
+   * @param frame The JInternalFrame to activate.
+   */
+  public void activateFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+
+    if (p != null)
+      p.setSelectedFrame(frame);
+    else
+      {
+	try
+	  {
+	    frame.setSelected(true);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+
+    frame.toFront();
+  } // activateFrame()
+
+  /**
+   * This method is called when the JInternalFrame loses focus.
+   *
+   * @param frame The JInternalFram to deactivate.
+   */
+  public void deactivateFrame(JInternalFrame frame)
+  {
+    JDesktopPane p = frame.getDesktopPane();
+    if (p != null)
+      {
+	if (p.getSelectedFrame() == frame)
+	  p.setSelectedFrame(null);
+      }
+    else
+      {
+	try
+	  {
+	    frame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+  } // deactivateFrame()
+
+  /**
+   * This method is called to indicate that the DesktopManager should prepare
+   * to drag the JInternalFrame. Any state information needed to drag the
+   * frame will be prepared now.
+   *
+   * @param component The JComponent to drag, usually a JInternalFrame.
+   */
+  public void beginDraggingFrame(JComponent component)
+  {
+    if (component instanceof JDesktopIcon)
+      pane = ((JDesktopIcon) component).getInternalFrame().getDesktopPane();
+    else
+      pane = ((JInternalFrame) component).getDesktopPane();
+    if (pane == null)
+      return;
+
+    dragCache = component.getBounds();
+
+    if (! (pane instanceof JDesktopPane))
+      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
+    else
+      currentDragMode = ((JDesktopPane) pane).getDragMode();
+  } // beginDraggingFrame()
+
+  /**
+   * This method is called to drag the JInternalFrame to a new location.
+   *
+   * @param component The JComponent to drag, usually a JInternalFrame.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   */
+  public void dragFrame(JComponent component, int newX, int newY)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	// FIXME: Do outline drag mode painting.
+      }
+    else
+      {
+	Rectangle b = component.getBounds();
+	if (component instanceof JDesktopIcon)
+	  component.setBounds(newX, newY, b.width, b.height);
+	else
+	  setBoundsForFrame((JInternalFrame) component, newX, newY, b.width,
+	                    b.height);
+      }
+  } // dragFrame()
+
+  /**
+   * This method indicates that the dragging is done. Any state information
+   * stored by the DesktopManager can be cleared.
+   *
+   * @param component The JComponent that has finished dragging.
+   */
+  public void endDraggingFrame(JComponent component)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	setBoundsForFrame((JInternalFrame) component, dragCache.x,
+	                  dragCache.y, dragCache.width, dragCache.height);
+	pane = null;
+	dragCache = null;
+      }
+    component.repaint();
+  } // endDraggingFrame()
+
+  /**
+   * This method is called to indicate that the given JComponent will be
+   * resized. Any state information necessary to resize the JComponent will
+   * be prepared now.
+   *
+   * @param component The JComponent to resize, usually a JInternalFrame.
+   * @param direction The direction to drag in (a SwingConstant).
+   */
+  public void beginResizingFrame(JComponent component, int direction)
+  {
+    pane = ((JInternalFrame) component).getDesktopPane();
+    if (pane == null)
+      return;
+
+    dragCache = component.getBounds();
+    if (! (pane instanceof JDesktopPane))
+      currentDragMode = JDesktopPane.LIVE_DRAG_MODE;
+    else
+      currentDragMode = ((JDesktopPane) pane).getDragMode();
+  } // beginResizingFrame()
+
+  /**
+   * This method resizes the give JComponent.
+   *
+   * @param component The JComponent to resize.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   * @param newWidth The new width.
+   * @param newHeight The new height.
+   */
+  public void resizeFrame(JComponent component, int newX, int newY,
+                          int newWidth, int newHeight)
+  {
+    dragCache.setBounds(newX, newY, newWidth, newHeight);
+    dragCache = findMinimum(dragCache, component);
+
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	// FIXME: Do outline drag painting.
+      }
+    else
+      setBoundsForFrame(component, dragCache.x, dragCache.y, dragCache.width,
+                        dragCache.height);
+  } // resizeFrame()
+
+  /**
+   * This method is called to indicate that the given JComponent has finished
+   * dragging. Any state information stored by the DesktopManager can be
+   * cleared.
+   *
+   * @param component The JComponent that finished resizing.
+   */
+  public void endResizingFrame(JComponent component)
+  {
+    if (currentDragMode == JDesktopPane.OUTLINE_DRAG_MODE)
+      {
+	setBoundsForFrame((JInternalFrame) component, dragCache.x,
+	                  dragCache.y, dragCache.width, dragCache.height);
+	pane = null;
+	dragCache = null;
+      }
+    component.repaint();
+  } // endResizingFrame()
+
+  /**
+   * This method calls setBounds with the given parameters and repaints the
+   * JComponent.
+   *
+   * @param component The JComponent to set bounds for.
+   * @param newX The new x coordinate.
+   * @param newY The new y coordinate.
+   * @param newWidth The new width.
+   * @param newHeight The new height.
+   */
+  public void setBoundsForFrame(JComponent component, int newX, int newY,
+                                int newWidth, int newHeight)
+  {
+    component.setBounds(newX, newY, newWidth, newHeight);
+    component.revalidate();
+
+    // If not null, I'd rather repaint the parent
+    if (component.getParent() != null)
+      component.getParent().repaint();
+    else
+      component.repaint();
+  } // setBoundsForFrame()
+
+  /**
+   * This is a helper method that removes the JDesktopIcon of the given
+   * JInternalFrame from the parent.
+   *
+   * @param frame The JInternalFrame to remove an icon for.
+   */
+  protected void removeIconFor(JInternalFrame frame)
+  {
+    JDesktopIcon icon = frame.getDesktopIcon();
+    Container c = icon.getParent();
+    if (c != null && icon != null)
+      c.remove(icon);
+  } // removeIconFor()
+
+  /**
+   * This method is called by iconifyFrame to determine the bounds of the
+   * JDesktopIcon for the given JInternalFrame.
+   *
+   * @param frame The JInternalFrame to find the bounds of its JDesktopIcon
+   *        for.
+   *
+   * @return The bounds of the JDesktopIcon.
+   */
+  protected Rectangle getBoundsForIconOf(JInternalFrame frame)
+  {
+    // IconRects has no order to it.
+    // The icon _must_ be placed in the first free slot (working from 
+    // the bottom left corner)
+    // The icon also must not be placed where another icon is placed 
+    // (regardless whether that frame is an icon currently or not)
+    JDesktopPane desktopPane = frame.getDesktopPane();
+    Rectangle paneBounds = desktopPane.getBounds();
+    Insets insets = desktopPane.getInsets();
+    Dimension pref = frame.getDesktopIcon().getPreferredSize();
+
+    if (desktopPane == null)
+      return frame.getDesktopIcon().getBounds();
+
+    Component[] frames = desktopPane.getComponents();
+
+    int count = 0;
+    for (int i = 0, j = 0; i < frames.length; i++)
+      if (frames[i] instanceof JDesktopIcon
+          || frames[i] instanceof JInternalFrame
+          && ((JInternalFrame) frames[i]).getWasIcon() && frames[i] != frame)
+	count++;
+    iconRects = new Rectangle[count];
+    for (int i = 0, j = 0; i < frames.length; i++)
+      if (frames[i] instanceof JDesktopIcon)
+	iconRects[--count] = frames[i].getBounds();
+      else if (frames[i] instanceof JInternalFrame
+               && ((JInternalFrame) frames[i]).getWasIcon()
+               && frames[i] != frame)
+	iconRects[--count] = ((JInternalFrame) frames[i]).getDesktopIcon()
+	                      .getBounds();
+
+    int startingX = insets.left;
+    int startingY = paneBounds.height - insets.bottom - pref.height;
+    Rectangle ideal = new Rectangle(startingX, startingY, pref.width,
+                                    pref.height);
+    boolean clear = true;
+
+    while (iconRects.length > 0)
+      {
+	clear = true;
+	for (int i = 0; i < iconRects.length; i++)
+	  {
+	    if (iconRects[i] != null && iconRects[i].intersects(ideal))
+	      {
+		clear = false;
+		break;
+	      }
+	  }
+	if (clear)
+	  return ideal;
+
+	startingX += pref.width;
+	if (startingX + pref.width > paneBounds.width - insets.right)
+	  {
+	    startingX = insets.left;
+	    startingY -= pref.height;
+	  }
+	ideal.setBounds(startingX, startingY, pref.width, pref.height);
+      }
+
+    return ideal;
+  } // getBoundsForIconOf()
+
+  /**
+   * This method sets the bounds of the JInternalFrame right before the
+   * maximizeFrame call.
+   *
+   * @param frame The JInternalFrame being maximized.
+   * @param rect The normal bounds.
+   */
+  protected void setPreviousBounds(JInternalFrame frame, Rectangle rect)
+  {
+    frame.setNormalBounds(rect);
+  } // setPreviousBounds()
+
+  /**
+   * This method returns the normal bounds of the JInternalFrame from before
+   * the maximize call.
+   *
+   * @param frame The JInternalFrame that is being restored.
+   *
+   * @return The previous bounds of the JInternalFrame.
+   */
+  protected Rectangle getPreviousBounds(JInternalFrame frame)
+  {
+    return frame.getNormalBounds();
+  } // getPreviousBounds()
+
+  /**
+   * This method sets the value to true if the given JInternalFrame has been
+   * iconized and the bounds of its DesktopIcon are valid.
+   *
+   * @param frame The JInternalFrame for the JDesktopIcon.
+   * @param value True if the JInternalFrame has been iconized and the bounds
+   *        of the JDesktopIcon are valid.
+   */
+  protected void setWasIcon(JInternalFrame frame, boolean value)
+  {
+    frame.setWasIcon(value, WAS_ICON_ONCE_PROPERTY);
+  } // setWasIcon()
+
+  /**
+   * This method returns true if the given JInternalFrame has been iconized
+   * and the bounds of its DesktopIcon are valid.
+   *
+   * @param frame The JInternalFrame for the JDesktopIcon.
+   *
+   * @return True if the given JInternalFrame has been iconized and the bounds
+   *         of its DesktopIcon are valid.
+   */
+  protected boolean wasIcon(JInternalFrame frame)
+  {
+    return frame.getWasIcon();
+  } // wasIcon()
+
+  /**
+   * This is a helper method that determines the minimum size a 
+   * JInternalFrame can be resized to.
+   *
+   * @param r The desired size.
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size a JInternalFrame can be resized to.
+   */
+  private Rectangle findMinimum(Rectangle r, JComponent c)
+  {
+    if (r != null && c != null)
+      {
+	Dimension d = c.getPreferredSize();
+	if (d != null)
+	  {
+	    r.width = Math.max(d.width, r.width);
+	    r.height = Math.max(d.height, r.height);
+	  }
+      }
+    return r;
+  }
 } // DefaultDesktopManager
Index: javax/swing/DesktopManager.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/DesktopManager.java,v
retrieving revision 1.2
diff -u -r1.2 DesktopManager.java
--- javax/swing/DesktopManager.java	12 Oct 2003 13:20:49 -0000	1.2
+++ javax/swing/DesktopManager.java	9 Jun 2004 20:47:01 -0000
@@ -1,5 +1,5 @@
 /* DesktopManager.java --
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -38,118 +38,140 @@
 package javax.swing;
 
 /**
- * DesktopManager
- * @author	Andrew Selkirk
- * @version	1.0
+ * DesktopManagers are responsible for implementing the behaviours for the
+ * JInternalFrames that belong to JDesktopPanes. Actions such as maximizing,
+ * minimizing, iconifying, etc will be delegated to the DesktopManager.
  */
-public interface DesktopManager {
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * openFrame
-	 * @param frame TODO
-	 */
-	void openFrame(JInternalFrame frame);
-
-	/**
-	 * closeFrame
-	 * @param frame TODO
-	 */
-	void closeFrame(JInternalFrame frame);
-
-	/**
-	 * maximizeFrame
-	 * @param frame TODO
-	 */
-	void maximizeFrame(JInternalFrame frame);
-
-	/**
-	 * minimizeFrame
-	 * @param frame TODO
-	 */
-	void minimizeFrame(JInternalFrame frame);
-
-	/**
-	 * iconifyFrame
-	 * @param frame TODO
-	 */
-	void iconifyFrame(JInternalFrame frame);
-
-	/**
-	 * deiconifyFrame
-	 * @param frame TODO
-	 */
-	void deiconifyFrame(JInternalFrame frame);
-
-	/**
-	 * activateFrame
-	 * @param frame TODO
-	 */
-	void activateFrame(JInternalFrame vframe);
-
-	/**
-	 * deactivateFrame
-	 * @param frame TODO
-	 */
-	void deactivateFrame(JInternalFrame frame);
-
-	/**
-	 * beginDraggingFrame
-	 * @param frame TODO
-	 */
-	void beginDraggingFrame(JComponent frame);
-
-	/**
-	 * dragFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 */
-	void dragFrame(JComponent frame, int x, int y);
-
-	/**
-	 * endDraggingFrame
-	 * @param frame TODO
-	 */
-	void endDraggingFrame(JComponent frame);
-
-	/**
-	 * beginResizingFrame
-	 * @param frame TODO
-	 * @param direction TODO
-	 */
-	void beginResizingFrame(JComponent frame, int direction);
-
-	/**
-	 * resizeFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param width TODO
-	 * @param height TODO
-	 */
-	void resizeFrame(JComponent frame, int x, int y, 
-					int width, int height);
-
-	/**
-	 * endResizingFrame
-	 * @param frame TODO
-	 */
-	void endResizingFrame(JComponent frame);
-
-	/**
-	 * setBoundsForFrame
-	 * @param frame TODO
-	 * @param x TODO
-	 * @param y TODO
-	 * @param width TODO
-	 * @param height TODO
-	 */
-	void setBoundsForFrame(JComponent frame, int x, int y, 
-					int width, int height);
-
-
+public interface DesktopManager
+{
+  /**
+   * This method will cause the JInternalFrame to be displayed in the set
+   * location. This usually is not needed since the user will add the
+   * JInternalFrame to a Container separately.
+   *
+   * @param frame The JInternalFrame to open.
+   */
+  void openFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JInternalFrame from its parent.
+   *
+   * @param frame The JInternalFrame to close.
+   */
+  void closeFrame(JInternalFrame frame);
+
+  /**
+   * This method should maximize the JInternalFrame to match its parent's
+   * bounds.
+   *
+   * @param frame The JInternalFrame to maximize.
+   */
+  void maximizeFrame(JInternalFrame frame);
+
+  /**
+   * This method should restore the JInternalFrame to its normal bounds.
+   *
+   * @param frame The JInternalFrame to minimize.
+   */
+  void minimizeFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JInternalFrame from its parent and replace
+   * it with a JDesktopIcon.
+   *
+   * @param frame The JInternalFrame to iconify.
+   */
+  void iconifyFrame(JInternalFrame frame);
+
+  /**
+   * This method should remove the JDesktopIcon from its parent and replace it
+   * with the JInternalFrame that the JDesktopIcon represents.
+   *
+   * @param frame The JInternalFrame to deiconify.
+   */
+  void deiconifyFrame(JInternalFrame frame);
+
+  /**
+   * This method should give focus to the JInternalFrame and its default focus
+   * owner.
+   *
+   * @param frame The JInternalFrame to activate.
+   */
+  void activateFrame(JInternalFrame vframe);
+
+  /**
+   * This method should be called when the JInternalFrame gets deselected and
+   * subsequently loses focus.
+   *
+   * @param frame The JInternalFrame to deactivate.
+   */
+  void deactivateFrame(JInternalFrame frame);
+
+  /**
+   * This method should be called in preparation for dragging. This needs to
+   * be called prior to dragFrame calls so that the DesktopManager can
+   * prepare any state information.
+   *
+   * @param frame The JInternalFrame to prepare for dragging.
+   */
+  void beginDraggingFrame(JComponent frame);
+
+  /**
+   * This method drags the given JInternalFrame to the given x and y
+   * coordinates.
+   *
+   * @param frame The JInternalFrame to drag.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   */
+  void dragFrame(JComponent frame, int x, int y);
+
+  /**
+   * This method should be called after dragFrame calls. Any information used
+   * by the DesktopManager for dragging the JInternalFrame can be cleared.
+   *
+   * @param frame The JInternalFrame that finished dragging.
+   */
+  void endDraggingFrame(JComponent frame);
+
+  /**
+   * This method should be called prior to any resizeFrame calls. Any state
+   * information needed by the DesktopManager to resize the JInternalFrame
+   * will be prepared here.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param direction One of eight directions specified by SwingConstants.
+   */
+  void beginResizingFrame(JComponent frame, int direction);
+
+  /**
+   * This method is called to resize the given JInternalFrame to the given
+   * bounds.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   * @param width The new width.
+   * @param height The new height.
+   */
+  void resizeFrame(JComponent frame, int x, int y, int width, int height);
+
+  /**
+   * This method is called to signify that the resize is finished. Any
+   * information used to resize the JInternalFrame can now be cleared.
+   *
+   * @param frame The JInternalFrame that just finished dragging.
+   */
+  void endResizingFrame(JComponent frame);
+
+  /**
+   * This method does the actual work for reshaping the JInternalFrame.
+   *
+   * @param frame The JInternalFrame to resize.
+   * @param x The new x coordinate.
+   * @param y The new y coordinate.
+   * @param width The new width.
+   * @param height The new height.
+   */
+  void setBoundsForFrame(JComponent frame, int x, int y, int width, int height);
 } // DesktopManager
Index: javax/swing/JButton.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JButton.java,v
retrieving revision 1.4
diff -u -r1.4 JButton.java
--- javax/swing/JButton.java	12 Feb 2004 00:17:23 -0000	1.4
+++ javax/swing/JButton.java	9 Jun 2004 20:47:01 -0000
@@ -87,6 +87,7 @@
     protected  void configurePropertiesFromAction(Action a)
     {
 	//Factory method which sets the AbstractButton's properties according to values from the Action instance. 
+	super.configurePropertiesFromAction(a);
     }
     
     public AccessibleContext getAccessibleContext()
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JComponent.java,v
retrieving revision 1.7.2.10
diff -u -r1.7.2.10 JComponent.java
--- javax/swing/JComponent.java	8 Jun 2004 20:11:46 -0000	1.7.2.10
+++ javax/swing/JComponent.java	9 Jun 2004 20:47:01 -0000
@@ -57,6 +57,7 @@
 import java.awt.geom.Rectangle2D;
 import java.awt.image.ImageObserver;
 import java.awt.peer.LightweightPeer;
+import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyVetoException;
 import java.beans.VetoableChangeListener;
@@ -738,7 +739,12 @@
                                     Object newValue)
     throws PropertyVetoException
   {
-    //       Support for reporting constrained property changes.
+    VetoableChangeListener[] listeners = getVetoableChangeListeners();
+    
+    PropertyChangeEvent evt = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
+    
+    for (int i = 0; i < listeners.length; i++)
+      ((VetoableChangeListener) listeners[i]).vetoableChange(evt);
   }
 
   /**
@@ -1385,7 +1391,7 @@
             g2 = doubleBuffer.getGraphics();
             g2.setClip(g.getClipBounds());
           }
-
+	  
         g2 = getComponentGraphics(g2);
         paintComponent(g2);
         paintBorder(g2);
@@ -1477,7 +1483,7 @@
    */
   public void paintImmediately(Rectangle r)
   {
-    Component root = this.getRootPane();
+    Component root = SwingUtilities.getRoot(this);
     if (root == null || ! root.isShowing())
       return;
     Graphics g = root.getGraphics();
Index: javax/swing/JDesktopPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JDesktopPane.java,v
retrieving revision 1.3.8.2
diff -u -r1.3.8.2 JDesktopPane.java
--- javax/swing/JDesktopPane.java	8 Jun 2004 09:28:42 -0000	1.3.8.2
+++ javax/swing/JDesktopPane.java	9 Jun 2004 20:47:01 -0000
@@ -37,6 +37,8 @@
 
 package javax.swing;
 
+import java.awt.Component;
+import java.beans.PropertyVetoException;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import javax.accessibility.Accessible;
@@ -44,25 +46,51 @@
 import javax.accessibility.AccessibleRole;
 import javax.swing.plaf.DesktopPaneUI;
 
+
 /**
- * JDesktopPane
- * @author	Andrew Selkirk
- * @version	1.0
+ * JDesktopPane is a container (usually for JInternalFrames) that simulates a
+ * desktop. Typically, the user will create JInternalFrames and place thme in
+ * a JDesktopPane. The user can then interact with JInternalFrames like they
+ * usually would with JFrames. The actions (minimize, maximize, close, etc)
+ * are done by using a DesktopManager that is associated with the
+ * JDesktopPane.
  */
 public class JDesktopPane extends JLayeredPane implements Accessible
 {
+  /** DOCUMENT ME! */
   private static final long serialVersionUID = 766333777224038726L;
-  
+
+  /**
+   * This specifies that when dragged, a JInternalFrame should be completely
+   * visible.
+   */
+  public static int LIVE_DRAG_MODE = 0;
+
+  /**
+   * This specifies that when dragged, a JInternalFrame should only be visible
+   * as an outline.
+   */
+  public static int OUTLINE_DRAG_MODE = 1;
+
+  /** The selected frame in the JDesktopPane. */
+  private transient JInternalFrame selectedFrame;
+
+  /** The JDesktopManager to use for acting on JInternalFrames. */
+  transient DesktopManager desktopManager;
+
+  /** The drag mode used by the JDesktopPane. */
+  private transient int dragMode = LIVE_DRAG_MODE;
+
   /**
    * AccessibleJDesktopPane
    */
   protected class AccessibleJDesktopPane extends AccessibleJComponent
   {
+    /** DOCUMENT ME! */
     private static final long serialVersionUID = 6079388927946077570L;
 
     /**
      * Constructor AccessibleJDesktopPane
-     * @param component TODO
      */
     protected AccessibleJDesktopPane()
     {
@@ -70,194 +98,223 @@
 
     /**
      * getAccessibleRole
-     * @returns AccessibleRole
+     *
+     * @return AccessibleRole
      */
     public AccessibleRole getAccessibleRole()
     {
       return AccessibleRole.DESKTOP_PANE;
     }
   }
-	
-	/**
-	 * LIVE_DRAG_MODE
-	 */
-	public static int LIVE_DRAG_MODE = 0;
-
-	/**
-	 * OUTLINE_DRAG_MODE
-	 */
-	public static int OUTLINE_DRAG_MODE = 1;
-
-	/**
-	 * uiClassID
-	 */
-	private static final String uiClassID = "DesktopPaneUI";
-
-
-	//-------------------------------------------------------------
-	// Variables --------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * selectedFrame
-	 */
-	private transient JInternalFrame selectedFrame;
-
-        /**
-         * desktopManager
-         */
-	private transient DesktopManager desktopManager;
-
-
-	/**
-	 * dragMode
-	 */
-	private int dragMode;
-
-
-	//-------------------------------------------------------------
-	// Initialization ---------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * Constructor JDesktopPane
-	 */
-	public JDesktopPane() {
-		// TODO
-	} // JDesktopPane()
-
-
-	//-------------------------------------------------------------
-	// Methods ----------------------------------------------------
-	//-------------------------------------------------------------
-
-	/**
-	 * writeObject
-	 * @param stream TODO
-	 * @exception IOException TODO
-	 */
-	private void writeObject(ObjectOutputStream stream) throws IOException {
-		// TODO
-	} // writeObject()
-
-	/**
-	 * getUI
-	 * @returns DesktopPaneUI
-	 */
-	public DesktopPaneUI getUI() {
-		return (DesktopPaneUI) ui;
-	} // getUI()
-
-	/**
-	 * setUI
-	 * @param ui TODO
-	 */
-	public void setUI(DesktopPaneUI ui) {
-		super.setUI(ui);
-	} // setUI()
-
-	/**
-	 * setDragMode
-	 * @param mode TODO
-	 */
-	public void setDragMode(int mode) {
-		this.dragMode = mode;
-		// TODO
-	} // setDragMode()
-
-	/**
-	 * getDragMode
-	 * @returns int
-	 */
-	public int getDragMode() {
-		return dragMode;
-	} // getDragMode()
-
-	/**
-	 * getDesktopManager
-	 * @returns DesktopManager
-	 */
-	public DesktopManager getDesktopManager() {
-		return desktopManager;
-	} // getDesktopManager()
-
-	/**
-	 * setDesktopManager
-	 * @param manager TODO
-	 */
-	public void setDesktopManager(DesktopManager manager) {
-		this.desktopManager = manager;
-		// TODO
-	} // setDesktopManager()
-
-	/**
-	 * updateUI
-	 */
-	public void updateUI() {
-		setUI((DesktopPaneUI) UIManager.get(this));
-		invalidate();
-	} // updateUI()
-
-	/**
-	 * getUIClassID
-	 * @returns String
-	 */
-	public String getUIClassID() {
-		return uiClassID;
-	} // getUIClassID()
-
-	/**
-	 * getAllFrames
-	 * @returns JInternalFrame[]
-	 */
-	public JInternalFrame[] getAllFrames() {
-		return null; // TODO
-	} // getAllFrames()
-
-	/**
-	 * getSelectedFrame
-	 * @returns JInternalFrame
-	 */
-	public JInternalFrame getSelectedFrame() {
-		return null; // TODO
-	} // getSelectedFrame()
-
-	/**
-	 * setSelectedFrame
-	 * @param frame TODO
-	 */
-	public void setSelectedFrame(JInternalFrame frame) {
-		// TODO
-	} // setSelectedFrame()
-
-	/**
-	 * getAllFramesInLayer
-	 * @param layer TODO
-	 * @returns JInternalFrame[]
-	 */
-	public JInternalFrame[] getAllFramesInLayer(int layer) {
-		return null; // TODO
-	} // getAllFramesInLayer()
-
-	/**
-	 * isOpaque
-	 * @returns boolean
-	 */
-	public boolean isOpaque() {
-		return true;
-	} // isOpaque()
-
-	/**
-	 * paramString
-	 * @returns String
-	 */
-	protected String paramString() {
-		return null; // TODO
-	} // paramString()
+
+  /**
+   * Creates a new JDesktopPane object.
+   */
+  public JDesktopPane()
+  {
+    setLayout(null);
+    updateUI();
+  }
+
+  /**
+   * This method returns the UI used with the JDesktopPane.
+   *
+   * @return The UI used with the JDesktopPane.
+   */
+  public DesktopPaneUI getUI()
+  {
+    return (DesktopPaneUI) ui;
+  }
+
+  /**
+   * This method sets the UI used with the JDesktopPane.
+   *
+   * @param ui The UI to use with the JDesktopPane.
+   */
+  public void setUI(DesktopPaneUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method sets the drag mode to use with the JDesktopPane.
+   *
+   * @param mode The drag mode to use.
+   *
+   * @throws IllegalArgumentException If the drag mode given is not
+   *         LIVE_DRAG_MODE or OUTLINE_DRAG_MODE.
+   */
+  public void setDragMode(int mode)
+  {
+    if ((mode != LIVE_DRAG_MODE) && (mode != OUTLINE_DRAG_MODE))
+      throw new IllegalArgumentException("Drag mode not valid.");
+
+    // FIXME: Unsupported mode.
+    if (mode == OUTLINE_DRAG_MODE)
+      throw new IllegalArgumentException("Outline drag modes are unsupported.");
+
+    dragMode = mode;
+  }
+
+  /**
+   * This method returns the drag mode used with the JDesktopPane.
+   *
+   * @return The drag mode used with the JDesktopPane.
+   */
+  public int getDragMode()
+  {
+    return dragMode;
+  }
+
+  /**
+   * This method returns the DesktopManager used with the JDesktopPane.
+   *
+   * @return The DesktopManager to use with the JDesktopPane.
+   */
+  public DesktopManager getDesktopManager()
+  {
+    return desktopManager;
+  }
+
+  /**
+   * This method sets the DesktopManager to use with the JDesktopPane.
+   *
+   * @param manager The DesktopManager to use with the JDesktopPane.
+   */
+  public void setDesktopManager(DesktopManager manager)
+  {
+    desktopManager = manager;
+  }
+
+  /**
+   * This method restores the UI used with the JDesktopPane to the default.
+   */
+  public void updateUI()
+  {
+    setUI((DesktopPaneUI) UIManager.getUI(this));
+    invalidate();
+  }
+
+  /**
+   * This method returns a String identifier that allows the UIManager to know
+   * which class will act as JDesktopPane's UI.
+   *
+   * @return A String identifier for the UI class to use.
+   */
+  public String getUIClassID()
+  {
+    return "DesktopPaneUI";
+  }
+
+  /**
+   * This method returns all JInternalFrames that are in the JDesktopPane.
+   *
+   * @return All JInternalFrames that are in the JDesktopPane.
+   */
+  public JInternalFrame[] getAllFrames()
+  {
+    return getFramesFromComponents(getComponents());
+  }
+
+  /**
+   * This method returns the currently selected frame in the JDesktopPane.
+   *
+   * @return The currently selected frame in the JDesktopPane.
+   */
+  public JInternalFrame getSelectedFrame()
+  {
+    return selectedFrame;
+  }
+
+  /**
+   * This method sets the selected frame in the JDesktopPane.
+   *
+   * @param frame The selected frame in the JDesktopPane.
+   */
+  public void setSelectedFrame(JInternalFrame frame)
+  {
+    if (selectedFrame != null)
+      {
+	try
+	  {
+	    selectedFrame.setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	  }
+      }
+    selectedFrame = null;
+
+    try
+      {
+	if (frame != null)
+	  frame.setSelected(true);
+
+	selectedFrame = frame;
+      }
+    catch (PropertyVetoException e)
+      {
+      }
+  }
+
+  /**
+   * This method returns all the JInternalFrames in the given layer.
+   *
+   * @param layer The layer to grab frames in.
+   *
+   * @return All JInternalFrames in the given layer.
+   */
+  public JInternalFrame[] getAllFramesInLayer(int layer)
+  {
+    return getFramesFromComponents(getComponentsInLayer(layer));
+  }
+
+  /**
+   * This method always returns true to indicate that it is not transparent.
+   *
+   * @return true.
+   */
+  public boolean isOpaque()
+  {
+    return true;
+  }
+
+  /**
+   * This method returns a String that describes the JDesktopPane.
+   *
+   * @return A String that describes the JDesktopPane.
+   */
+  protected String paramString()
+  {
+    return "JDesktopPane";
+  }
+
+  /**
+   * This method returns all the JInternalFrames in the given Component array.
+   *
+   * @param components An array to search for JInternalFrames in.
+   *
+   * @return An array of JInternalFrames found in the Component array.
+   */
+  private static JInternalFrame[] getFramesFromComponents(Component[] components)
+  {
+    int count = 0;
+
+    for (int i = 0; i < components.length; i++)
+	if (components[i] instanceof JInternalFrame)
+	  count++;
+	  
+    JInternalFrame[] value = new JInternalFrame[count];
+    for (int i = 0, j = 0; i < components.length && j != count; i++)
+      if (components[i] instanceof JInternalFrame)
+	value[j++] = (JInternalFrame) components[i];
+    return value;
+  }
 
   /**
    * getAccessibleContext
-   * @returns AccessibleContext
+   *
+   * @return AccessibleContext
    */
   public AccessibleContext getAccessibleContext()
   {
Index: javax/swing/JInternalFrame.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JInternalFrame.java,v
retrieving revision 1.2.18.1
diff -u -r1.2.18.1 JInternalFrame.java
--- javax/swing/JInternalFrame.java	7 Jun 2004 14:00:33 -0000	1.2.18.1
+++ javax/swing/JInternalFrame.java	9 Jun 2004 20:47:01 -0000
@@ -1,4 +1,4 @@
-/* JInternalFrame.java -- 
+/* JInternalFrame.java --
    Copyright (C) 2002, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -35,24 +35,1673 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package javax.swing;
 
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Graphics;
+import java.awt.KeyboardFocusManager;
+import java.awt.LayoutManager;
+import java.awt.Rectangle;
+import java.beans.PropertyVetoException;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleContext;
+import javax.accessibility.AccessibleRole;
+import javax.accessibility.AccessibleValue;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.InternalFrameUI;
+
 
-public class JInternalFrame extends JComponent
-/*implements Accessible, WindowConstants, RootPaneContainer*/
+/**
+ * This class implements a Swing widget that looks and acts like a native
+ * frame. The frame can be dragged, resized, closed, etc. Typically,
+ * JInternalFrames are placed in JDesktopPanes. The actions that the
+ * JInternalFrame performs (maximizing, minimizing, etc.) are performed by a
+ * DesktopManager. As with regular frames, components are added by calling
+ * frame.getContentPane().add.
+ */
+public class JInternalFrame extends JComponent implements Accessible,
+                                                          WindowConstants,
+                                                          RootPaneContainer
 {
+  /** DOCUMENT ME! */
   private static final long serialVersionUID = -5425177187760785402L;
 
-  public static final String CONTENT_PANE_PROPERTY = "contentPane";
-  public static final String MENU_BAR_PROPERTY = "JMenuBar";
-  public static final String TITLE_PROPERTY = "title";
-  public static final String LAYERED_PANE_PROPERTY = "layeredPane";
-  public static final String ROOT_PANE_PROPERTY = "rootPane";
-  public static final String GLASS_PANE_PROPERTY = "glassPane";
-  public static final String FRAME_ICON_PROPERTY = "frameIcon";
-  public static final String IS_SELECTED_PROPERTY = "selected";
-  public static final String IS_CLOSED_PROPERTY = "closed";
-  public static final String IS_MAXIMUM_PROPERTY = "maximum";
-  public static final String IS_ICON_PROPERTY = "icon";
-}
+  /**
+   * DOCUMENT ME!
+   */
+  protected class AccessibleJInternalFrame extends AccessibleJComponent
+    implements AccessibleValue
+  {
+    /**
+     * Creates a new AccessibleJInternalFrame object.
+     */
+    protected AccessibleJInternalFrame()
+    {
+      super();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public String getAccessibleName()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleRole getAccessibleRole()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleValue getAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getCurrentAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMaximumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public Number getMinimumAccessibleValue()
+    {
+      return null;
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @param n DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public boolean setCurrentAccessibleValue(Number n)
+    {
+      return false;
+    }
+  }
+
+  /**
+   * This class represents the JInternalFrame while it is iconified.
+   */
+  public static class JDesktopIcon extends JComponent implements Accessible
+  {
+    /**
+     * DOCUMENT ME!
+     */
+    protected class AccessibleJDesktopIcon extends AccessibleJComponent
+      implements AccessibleValue
+    {
+      /**
+       * Creates a new AccessibleJDesktopIcon object.
+       */
+      protected AccessibleJDesktopIcon()
+      {
+	super();
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public AccessibleRole getAccessibleRole()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public AccessibleValue getAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getCurrentAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getMaximumAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public Number getMinimumAccessibleValue()
+      {
+	return null;
+      }
+
+      /**
+       * DOCUMENT ME!
+       *
+       * @param n DOCUMENT ME!
+       *
+       * @return DOCUMENT ME!
+       */
+      public boolean setCurrentAccessibleValue(Number n)
+      {
+	return false;
+      }
+    }
+
+    /** The JInternalFrame this DesktopIcon represents. */
+    JInternalFrame frame;
+
+    /**
+     * Creates a new JDesktopIcon object for representing the given frame.
+     *
+     * @param f The JInternalFrame to represent.
+     */
+    public JDesktopIcon(JInternalFrame f)
+    {
+      frame = f;
+      updateUI();
+    }
+
+    /**
+     * DOCUMENT ME!
+     *
+     * @return DOCUMENT ME!
+     */
+    public AccessibleContext getAccessibleContext()
+    {
+      if (accessibleContext == null)
+	accessibleContext = new AccessibleJDesktopIcon();
+      return accessibleContext;
+    }
+
+    /**
+     * This method returns the JDesktopPane this JDesktopIcon is in.
+     *
+     * @return The JDesktopPane this JDesktopIcon is in.
+     */
+    public JDesktopPane getDesktopPane()
+    {
+      JDesktopPane p = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                        this);
+      return p;
+    }
+
+    /**
+     * This method returns the JInternalFrame this JDesktopIcon represents.
+     *
+     * @return The JInternalFrame this JDesktopIcon represents.
+     */
+    public JInternalFrame getInternalFrame()
+    {
+      return frame;
+    }
+
+    /**
+     * This method returns the UI that is responsible for the JDesktopIcon.
+     *
+     * @return The UI that is responsible for the JDesktopIcon.
+     */
+    public DesktopIconUI getUI()
+    {
+      return (DesktopIconUI) ui;
+    }
+
+    /**
+     * This method returns the String identifier that is used to determine
+     * which class is used for JDesktopIcon's UI.
+     *
+     * @return A String identifier for the UI class.
+     */
+    public String getUIClassID()
+    {
+      return "DesktopIconUI";
+    }
+
+    /**
+     * This method sets the JInternalFrame that this JDesktopIcon represents.
+     *
+     * @param f The JInternalFrame that this JDesktopIcon represents.
+     */
+    public void setInternalFrame(JInternalFrame f)
+    {
+      frame = f;
+    }
+
+    /**
+     * This method sets the UI used for this JDesktopIcon.
+     *
+     * @param ui The UI to use.
+     */
+    public void setUI(DesktopIconUI ui)
+    {
+      super.setUI(ui);
+    }
+
+    /**
+     * This method restores the UI property to the defaults.
+     */
+    public void updateUI()
+    {
+      setUI((DesktopIconUI) UIManager.getUI(this));
+    }
+  }
+
+  /**
+   * The property fired in a PropertyChangeEvent when the contentPane property
+   * changes.
+   */
+  public static String CONTENT_PANE_PROPERTY = "contentPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the frameIcon property
+   * changes.
+   */
+  public static String FRAME_ICON_PROPERTY = "frameIcon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the glassPane property
+   * changes.
+   */
+  public static String GLASS_PANE_PROPERTY = "glassPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the closed property
+   * changes.
+   */
+  public static String IS_CLOSED_PROPERTY = "closed";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the icon property
+   * changes.
+   */
+  public static String IS_ICON_PROPERTY = "icon";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the maximum property
+   * changes.
+   */
+  public static String IS_MAXIMUM_PROPERTY = "maximum";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the selected property
+   * changes.
+   */
+  public static String IS_SELECTED_PROPERTY = "selected";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the layeredPane property
+   * changes.
+   */
+  public static String LAYERED_PANE_PROPERTY = "layeredPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the jMenuBar property
+   * changes.
+   */
+  public static String MENU_BAR_PROPERTY = "jMenuBar";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the rootPane property
+   * changes.
+   */
+  public static String ROOT_PANE_PROPERTY = "rootPane";
+
+  /**
+   * The property fired in a PropertyChangeEvent when the title property
+   * changes.
+   */
+  public static String TITLE_PROPERTY = "title";
+
+  /** Whether the JInternalFrame is closable. */
+  protected boolean closable;
+
+  /** Whether the JInternalFrame can be iconified. */
+  protected boolean iconable;
+
+  /** Whether the JInternalFrame is closed. */
+  protected boolean isClosed;
+
+  /** Whether the JInternalFrame has been iconified. */
+  protected boolean isIcon;
+
+  /** Whether the JInternalFrame has been maximized. */
+  protected boolean isMaximum;
+
+  /** Whether the JInternalFrame is the active frame. */
+  protected boolean isSelected;
+
+  /** Whether the JInternalFrame can be maximized. */
+  protected boolean maximizable;
+
+  /** Whether the JInternalFrame has rootPaneChecking enabled. */
+  protected boolean rootPaneCheckingEnabled = true;
+
+  /** Whether the JInternalFrame is resizable. */
+  protected boolean resizable;
+
+  /**
+   * The JDesktopIcon that represents the JInternalFrame while it is
+   * iconified.
+   */
+  protected JDesktopIcon desktopIcon;
+
+  /** The icon used in the JMenuBar in the TitlePane. */
+  protected Icon frameIcon;
+
+  /** The rootPane of the JInternalFrame. */
+  protected JRootPane rootPane;
+
+  /** The title on the TitlePane of the JInternalFrame. */
+  protected String title;
+
+  /** The bounds of the JInternalFrame before it was maximized. */
+  private transient Rectangle storedBounds;
+
+  /** The Component that receives focus by default. */
+  private transient Component defaultFocus;
+
+  /** The default close action taken, */
+  private transient int defaultCloseOperation = DISPOSE_ON_CLOSE;
+
+  /** Whether the JInternalFrame has become visible for the very first time. */
+  private transient boolean isFirstTimeVisible = true;
+
+  /**
+   * Whether the JInternalFrame is in the transition from being a maximized
+   * frame back to a regular sized frame.
+   */
+  private transient boolean maxTransition = false;
+
+  /** DOCUMENT ME! */
+  private transient boolean wasIcon = false;
+
+  /**
+   * Creates a new JInternalFrame object that has no title, and is
+   * non-resizable, non-maximizable, non-iconifiable, and non-closable.
+   */
+  public JInternalFrame()
+  {
+    this(null, false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and is
+   * non-resizable, non-maximizable, non-iconifiable, and non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   */
+  public JInternalFrame(String title)
+  {
+    this(title, false, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title and resizable
+   * properties. The JInternalFrame is non-maximizable, non-iconifiable, and
+   * non-closable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   */
+  public JInternalFrame(String title, boolean resizable)
+  {
+    this(title, resizable, false, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable, and
+   * closable properties. The JInternalFrame is non-maximizable and
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable)
+  {
+    this(title, resizable, closable, false, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable and maximizable properties. The JInternalFrame is
+   * non-iconifiable.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable)
+  {
+    this(title, resizable, closable, maximizable, false);
+  }
+
+  /**
+   * Creates a new JInternalFrame object with the given title, resizable,
+   * closable, maximizable and iconifiable properties.
+   *
+   * @param title The title displayed in the JInternalFrame.
+   * @param resizable Whether the JInternalFrame is resizable.
+   * @param closable Whether the JInternalFrame is closable.
+   * @param maximizable Whether the JInternalFrame is maximizable.
+   * @param iconifiable Whether the JInternalFrame is iconifiable.
+   */
+  public JInternalFrame(String title, boolean resizable, boolean closable,
+                        boolean maximizable, boolean iconifiable)
+  {
+    this.title = title;
+    this.resizable = resizable;
+    this.closable = closable;
+    this.maximizable = maximizable;
+    this.iconable = iconifiable;
+    storedBounds = new Rectangle();
+
+    setRootPaneCheckingEnabled(false);
+    setRootPane(createRootPane());
+
+    updateUI();
+    setRootPaneCheckingEnabled(true);
+  }
+
+  /**
+   * This method adds Components to this Container. For JInternalFrames,
+   * instead of calling add directly on the JInternalFrame, it should be
+   * called with JInternalFrame.getContentPane().add. If root pane checking
+   * is enabled, calling this method will cause an exception to be thrown.
+   *
+   * @param comp The Component to add.
+   * @param constraints The constraints on the Component added.
+   * @param index The position to place the Component.
+   *
+   * @throws Error DOCUMENT ME!
+   */
+  protected void addImpl(Component comp, Object constraints, int index)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("Do not use add() on JInternalPane directly. Use getContentPane().add() instead");
+
+    super.addImpl(comp, constraints, index);
+  }
+
+  /**
+   * This method adds an InternalFrameListener to this JInternalFrame.
+   *
+   * @param l The listener to add.
+   */
+  public void addInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.add(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method is used to create a root pane for the JInternalFrame. This
+   * method is called by the constructors.
+   *
+   * @return A root pane for the JInternalFrame to use.
+   */
+  protected JRootPane createRootPane()
+  {
+    return new JRootPane();
+  }
+
+  /**
+   * This method makes this JInternalFrame invisible, unselected and closed.
+   * If this JInternalFrame is not closed already, it will fire an
+   * INTERNAL_FRAME_CLoSED event. This method is similar to setClosed but it
+   * doesn't give vetoable listeners a chance to veto and it will not fire an
+   * INTERNAL_FRAME_CLOSING event.
+   */
+  public void dispose()
+  {
+    hide();
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      pane.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing if they don't want to be unselected.
+	  }
+      }
+    isClosed = true;
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
+    removeNotify();
+  }
+
+  /**
+   * This method is used for closing this JInternalFrame. It fires an
+   * INTERNAL_FRAME_CLOSING event and then performs the action specified by
+   * the default close operation.
+   */
+  public void doDefaultCloseAction()
+  {
+    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+    switch (getDefaultCloseOperation())
+      {
+      case HIDE_ON_CLOSE:
+	hide();
+	break;
+      case DISPOSE_ON_CLOSE:
+	dispose();
+	break;
+      }
+  }
+
+  /**
+   * This method fires an InternalFrameEvent to the listeners.
+   *
+   * @param id The type of event being fired. See InternalFrameEvent.
+   */
+  protected void fireInternalFrameEvent(int id)
+  {
+    Object[] ifListeners = listenerList.getListenerList();
+    InternalFrameEvent evt = new InternalFrameEvent(this, id);
+    switch (id)
+      {
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameClosing(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameActivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameClosed(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeactivated(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameDeiconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1])
+	      .internalFrameIconified(evt);
+	  }
+	break;
+      case InternalFrameEvent.INTERNAL_FRAME_OPENED:
+	for (int i = ifListeners.length - 2; i >= 0; i -= 2)
+	  {
+	    if (ifListeners[i] == InternalFrameListener.class)
+	      ((InternalFrameListener) ifListeners[i + 1]).internalFrameOpened(evt);
+	  }
+	break;
+      }
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public AccessibleContext getAccessibleContext()
+  {
+    if (accessibleContext == null)
+      accessibleContext = new AccessibleJInternalFrame();
+    return accessibleContext;
+  }
+
+  /**
+   * This method returns the Content Pane for this JInternalFrame.
+   *
+   * @return The Content Pane for this JInternalFrame.
+   */
+  public Container getContentPane()
+  {
+    return getRootPane().getContentPane();
+  }
+
+  /**
+   * This method returns the default action taken when this JInternalFrame is
+   * closed.
+   *
+   * @return The default action taken when this JInternalFrame is closed.
+   */
+  public int getDefaultCloseOperation()
+  {
+    return defaultCloseOperation;
+  }
+
+  /**
+   * This method returns the JDesktopIcon that represents this JInternalFrame
+   * while it is iconified.
+   *
+   * @return The JDesktopIcon that represents this JInternalFrame while it is
+   *         iconified.
+   */
+  public JDesktopIcon getDesktopIcon()
+  {
+    if (desktopIcon == null)
+      desktopIcon = new JDesktopIcon(this);
+    return desktopIcon;
+  }
+
+  /**
+   * This method searches this JInternalFrame ancestors for an instance of
+   * JDesktopPane. If one is found, it is returned. If none is found, then it
+   * will search the JDesktopIcon for a JDesktopPane.
+   *
+   * @return The JDesktopPane that this JInternalFrame belongs to.
+   */
+  public JDesktopPane getDesktopPane()
+  {
+    JDesktopPane value = (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
+                                                                          this);
+    if (value == null && desktopIcon != null)
+      value = desktopIcon.getDesktopPane();
+    return value;
+  }
+
+  /**
+   * This method returns null because this must always be the root of a focus
+   * traversal.
+   *
+   * @return null.
+   */
+  public Container getFocusCycleRootAncestor()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method returns the child Component that will receive focus if this
+   * JInternalFrame is selected.
+   *
+   * @return The child Component that will receive focus.
+   */
+  public Component getFocusOwner()
+  {
+    if (isSelected())
+      {
+	Component focus = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+	if (SwingUtilities.isDescendingFrom(focus, this))
+	  {
+	    defaultFocus = focus;
+	    return focus;
+	  }
+      }
+    return null;
+  }
+
+  /**
+   * This method returns the Frame Icon (the icon used in the JInternalFrame
+   * TitlePane and iconified frame).
+   *
+   * @return The Frame Icon.
+   */
+  public Icon getFrameIcon()
+  {
+    return frameIcon;
+  }
+
+  /**
+   * This method returns the Glass Pane used with this JInternalFrame.
+   *
+   * @return The Glass Pane used with this JInternalFrame.
+   */
+  public Component getGlassPane()
+  {
+    return getRootPane().getGlassPane();
+  }
+
+  /**
+   * This method returns an array of InternalFrameListeners that are listening
+   * to this JInternalFrame.
+   *
+   * @return An array of InternalFrameListeners that are listening to this
+   *         JInternalFrame.
+   */
+  public InternalFrameListener[] getInternalFrameListeners()
+  {
+    return (InternalFrameListener[]) listenerList.getListeners(InternalFrameListener.class);
+  }
+
+  /**
+   * This method returns the JMenuBar for this JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   */
+  public JMenuBar getJMenuBar()
+  {
+    return getRootPane().getJMenuBar();
+  }
+
+  /**
+   * This method returns the layer that this JInternalFrame resides in.
+   *
+   * @return The layer that this JInternalFrame resides in.
+   */
+  public int getLayer()
+  {
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      return pane.getLayer(this).intValue();
+    return -1;
+  }
+
+  /**
+   * This method returns the LayeredPane for this JInternalFrame.
+   *
+   * @return The LayeredPane for this JInternalFrame.
+   */
+  public JLayeredPane getLayeredPane()
+  {
+    return getRootPane().getLayeredPane();
+  }
+
+  /**
+   * This method is deprecated. This method returns the JMenuBar for this
+   * JInternalFrame.
+   *
+   * @return The JMenuBar for this JInternalFrame.
+   */
+  public JMenuBar getMenuBar()
+  {
+    return getJMenuBar();
+  }
+
+  /**
+   * This method returns the child Component that will receive focus when the
+   * JInternalFrame is selected. If the JInternalFrame is selected, this
+   * method returns getFocusOwner(). Otherwise, it will return the child
+   * Component that most recently requested focus. If that is null, then the
+   * initial focus Component is returned. If that is null, then the default
+   * focus component is returned.
+   *
+   * @return The most recent focus owner.
+   */
+  public Component getMostRecentFocusOwner()
+  {
+    if (isSelected())
+      return getFocusOwner();
+    else
+      return defaultFocus;
+  }
+
+  /**
+   * This method returns the bounds of the JInternalFrame if it is not
+   * maximized. If it is maximized, it returns the bounds of the
+   * JInternalFrame before it was maximized (the bounds that it will be
+   * restored to).
+   *
+   * @return A Rectangle that contains this JInternalFrame's normal bounds (or
+   *         just its bounds if it is not maximized).
+   */
+  public Rectangle getNormalBounds()
+  {
+    if (! isMaximum() && ! maxTransition)
+      return getBounds();
+    else
+      return storedBounds;
+  }
+
+  /**
+   * This method returns the Root Pane for this JInternalFrame.
+   *
+   * @return The Root Pane for this JInternalFrame.
+   */
+  public JRootPane getRootPane()
+  {
+    return rootPane;
+  }
+
+  /**
+   * This method sets the title of the JInternalFrame.
+   *
+   * @return The String displayed in the TitlePane of this JInternalFrame.
+   */
+  public String getTitle()
+  {
+    return title;
+  }
+
+  /**
+   * This method returns the UI used to represent the JInternalFrame.
+   *
+   * @return The UI used to represent the JInternalFrame.
+   */
+  public InternalFrameUI getUI()
+  {
+    return (InternalFrameUI) ui;
+  }
+
+  /**
+   * This method returns a String identifier that is used to determine which
+   * class acts as the JInternalFrame's UI.
+   *
+   * @return A String identifier to determine a UI class.
+   */
+  public String getUIClassID()
+  {
+    return "InternalFrameUI";
+  }
+
+  /**
+   * This method returns null.
+   *
+   * @return null.
+   */
+  public String getWarningString()
+  {
+    // as defined.
+    return null;
+  }
+
+  /**
+   * This method deselects this JInternalFrame and hides it.
+   */
+  public void hide()
+  {
+    JDesktopPane pane = getDesktopPane();
+    if (pane != null)
+      pane.setSelectedFrame(null);
+    else
+      {
+	try
+	  {
+	    setSelected(false);
+	  }
+	catch (PropertyVetoException e)
+	  {
+	    // Do nothing.
+	  }
+      }
+    super.hide();
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is closable.
+   *
+   * @return Whether this JInternalFrame is closable.
+   */
+  public boolean isClosable()
+  {
+    return closable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame has been closed.
+   *
+   * @return Whether this JInternalFrame is closed.
+   */
+  public boolean isClosed()
+  {
+    return isClosed;
+  }
+
+  /**
+   * This must always return true.
+   *
+   * @return True
+   */
+  public boolean isFocusCycleRoot()
+  {
+    return true;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently iconified.
+   *
+   * @return Whether this JInternalFrame is currently iconified.
+   */
+  public boolean isIcon()
+  {
+    return isIcon;
+  }
+
+  /**
+   * This method returns whether the JInternalFrame can be iconified.
+   *
+   * @return Whether the JInternalFrame can be iconified.
+   */
+  public boolean isIconifiable()
+  {
+    return iconable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame can be maximized.
+   *
+   * @return Whether this JInternalFrame can be maximized.
+   */
+  public boolean isMaximizable()
+  {
+    return maximizable;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is currently maximized.
+   *
+   * @return Whether this JInternalFrame is maximized.
+   */
+  public boolean isMaximum()
+  {
+    return isMaximum;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is resizable.
+   *
+   * @return Whether this JInternalFrame is resizable.
+   */
+  public boolean isResizable()
+  {
+    return resizable;
+  }
+
+  /**
+   * This method returns whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @return Whether root pane checking is enabled.
+   */
+  protected boolean isRootPaneCheckingEnabled()
+  {
+    return rootPaneCheckingEnabled;
+  }
+
+  /**
+   * This method returns whether this JInternalFrame is selected.
+   *
+   * @return Whether this JInternalFrame is selected.
+   */
+  public boolean isSelected()
+  {
+    return isSelected;
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the back if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToBack()
+  {
+    if (getParent() instanceof JLayeredPane)
+      ((JLayeredPane) getParent()).moveToBack(this);
+  }
+
+  /**
+   * A helper method that moves this JInternalFrame to the front if the parent
+   * is a JLayeredPane.
+   */
+  public void moveToFront()
+  {
+    if (getParent() instanceof JLayeredPane)
+      ((JLayeredPane) getParent()).moveToFront(this);
+  }
+
+  /**
+   * This method causes the children of this JInternalFrame to be laid out.
+   * Before it begins, if this JInternalFrame is an icon, then it will be
+   * deiconified. If it is maximized, then it will be restored. If either
+   * operation fails, then this method will return.
+   */
+  public void pack()
+  {
+    try
+      {
+	if (isIcon())
+	  setIcon(false);
+	else if (isMaximum())
+	  setMaximum(false);
+      }
+    catch (PropertyVetoException e)
+      {
+	// Do nothing if they don't want to be restored first.
+      }
+    doLayout();
+  }
+
+  /**
+   * This method is overridden to allow for speedier painting while this
+   * JInternalFramme is being dragged.
+   *
+   * @param g The Graphics object to paint with.
+   */
+  protected void paintComponent(Graphics g)
+  {
+    super.paintComponent(g);
+  }
+
+  /**
+   * This method returns a String describing this JInternalFrame.
+   *
+   * @return A String describing this JInternalFrame.
+   */
+  protected String paramString()
+  {
+    return "JInternalFrame";
+  }
+
+  /**
+   * This method removes the given Component from the Container.
+   *
+   * @param comp The Component to remove.
+   */
+  public void remove(Component comp)
+  {
+    super.remove(comp);
+  }
+
+  /**
+   * This method removes an InternalFrameListener from this JInternalFrame.
+   *
+   * @param l The listener to remove.
+   */
+  public void removeInternalFrameListener(InternalFrameListener l)
+  {
+    listenerList.remove(InternalFrameListener.class, l);
+  }
+
+  /**
+   * This method resizes and positions this JInternalFrame. It also forces a
+   * relayout of the Container.
+   *
+   * @param x The x position of this JInternalFrame.
+   * @param y The y position of this JInternalFrame.
+   * @param width The width of this JInternalFrame.
+   * @param height The height of this JInternalFrame.
+   */
+  public void reshape(int x, int y, int width, int height)
+  {
+    super.reshape(x, y, width, height);
+    invalidate();
+    doLayout();
+  }
+
+  /**
+   * This method gives focus to the last child Component that had focus. This
+   * is used by the UI when this JInternalFrame is activated.
+   */
+  public void restoreSubcomponentFocus()
+  {
+    Component c = getMostRecentFocusOwner();
+    if (c != null)
+      c.requestFocus();
+  }
+
+  /**
+   * This method sets whether this JInternalFrame can be closed.
+   *
+   * @param b Whether this JInternalFrame can be closed.
+   */
+  public void setClosable(boolean b)
+  {
+    closable = b;
+  }
+
+  /**
+   * This method closes the JInternalFrame if the given boolean is true. If it
+   * is false, then the result of this method is unspecified. If the
+   * JInternalFrame is closed, this method does nothing. This method will
+   * first fire an INTERNAL_FRAME_CLOSING event and give a chance for veto
+   * listeners to cancel the close. If no listener vetoes the change, the
+   * closed property is set to true and the JInternalFrame is hidden and
+   * unselected. The method will finish by firing an INTERNAL_FRAME_CLOSED
+   * event.
+   *
+   * @param b Whether the JInternalFrame will be closed.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setClosed(boolean b) throws PropertyVetoException
+  {
+    if (b && ! isClosed())
+      {
+	fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
+	fireVetoableChange(IS_CLOSED_PROPERTY, false, true);
+
+	isClosed = b;
+
+	firePropertyChange(IS_CLOSED_PROPERTY, false, true);
+	fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
+      }
+  }
+
+  /**
+   * This method sets the Container to be used as a Content Pane for this
+   * JInternalFrame.
+   *
+   * @param c The Container to use as a Content Pane.
+   */
+  public void setContentPane(Container c)
+  {
+    if (c != getContentPane())
+      {
+	Container old = getContentPane();
+	getRootPane().setContentPane(c);
+	firePropertyChange(CONTENT_PANE_PROPERTY, old, c);
+      }
+  }
+
+  /**
+   * This method sets the action taken when this JInternalFrame is closed.
+   *
+   * @param operation One of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE or
+   *        DISPOSE_ON_CLOSE.
+   *
+   * @throws Error If the given operation is not one of the allowed modes.
+   */
+  public void setDefaultCloseOperation(int operation)
+  {
+    if (operation != DO_NOTHING_ON_CLOSE || operation != HIDE_ON_CLOSE
+        || operation != DISPOSE_ON_CLOSE)
+      throw new Error("Close operation must be one of DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, or DISPOSE_ON_CLOSE");
+    defaultCloseOperation = operation;
+  }
+
+  /**
+   * This method sets the JDesktopIcon that represents this JInternalFrame
+   * while it is iconified.
+   *
+   * @param d The JDesktopIcon that represents this JInternalFrame while it is
+   *        iconified.
+   */
+  public void setDesktopIcon(JDesktopIcon d)
+  {
+    d.setInternalFrame(this);
+    desktopIcon = d;
+  }
+
+  /**
+   * This method does nothing because this must be the root of a focus
+   * traversal cycle.
+   *
+   * @param focusCycleRoot Not used.
+   */
+  public final void setFocusCycleRoot(boolean focusCycleRoot)
+  {
+    // Do nothing
+  }
+
+  /**
+   * This method sets the Icon to be used in two places. The first is icon
+   * that is painted at the top left corner of the JInternalFrame when it is
+   * not iconified (clicking on that icon will activate the TitlePane
+   * JMenuBar). When the JInternalFrame is iconified, it will be the icon
+   * displayed in the JDesktopIcon. If no icon is set, the JInternalFrame
+   * will use a Look and Feel default.
+   *
+   * @param icon The Icon used in the TitlePane JMenuBar and iconified frames.
+   */
+  public void setFrameIcon(Icon icon)
+  {
+    if (icon != frameIcon)
+      {
+	Icon old = frameIcon;
+	frameIcon = icon;
+	firePropertyChange(FRAME_ICON_PROPERTY, old, frameIcon);
+      }
+  }
+
+  /**
+   * This method sets the Glass Pane used with this JInternalFrame.
+   *
+   * @param glass The Glass Pane to use with this JInternalFrame.
+   */
+  public void setGlassPane(Component glass)
+  {
+    if (glass != getGlassPane())
+      {
+	Component old = getGlassPane();
+	getRootPane().setGlassPane(glass);
+	firePropertyChange(GLASS_PANE_PROPERTY, old, glass);
+      }
+  }
+
+  /**
+   * This method iconifies or deiconifies this JInternalFrame given the
+   * boolean argument. If the JInternalFrame becomes iconified, it will fire
+   * an INTERNAL_FRAME_ICONIFIED event. If the JInternalFrame becomes
+   * deiconified, it will fire anINTERNAL_FRAME_DEICONIFIED event.
+   *
+   * @param b Whether this JInternalFrame is to be iconified or deiconified.
+   *
+   * @throws PropertyVetoException DOCUMENT ME!
+   */
+  public void setIcon(boolean b) throws PropertyVetoException
+  {
+    if (b != isIcon())
+      {
+	fireVetoableChange(IS_ICON_PROPERTY, b, isIcon);
+
+	isIcon = b;
+
+	firePropertyChange(IS_ICON_PROPERTY, ! isIcon, isIcon);
+	if (b)
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
+	else
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be iconified. (This means
+   * that the JInternalFrame can be turned into an icon if minimized).
+   *
+   * @param b Whether the JInternalFrame can be iconified.
+   */
+  public void setIconifiable(boolean b)
+  {
+    iconable = b;
+  }
+
+  /**
+   * This method sets the JMenuBar to be used with this JInternalFrame.
+   *
+   * @param b The JMenuBar to be used with this JInternalFrame.
+   */
+  public void setJMenuBar(JMenuBar b)
+  {
+    getRootPane().setJMenuBar(b);
+  }
+
+  /**
+   * A helper method that set the layer that this JInternalFrame resides in.
+   * Using this version of the method means that the user should not set it
+   * to values that are already defined in JLayeredPane. If predefined values
+   * are to be used, the user should use the setLayer(Integer) version.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(int layer)
+  {
+    setLayer(new Integer(layer));
+  }
+
+  /**
+   * A helper method that sets the layer that this JInternalFrame resides in.
+   * Calling this version of the method should use layer values that are
+   * already defined in JLayeredPane.
+   *
+   * @param layer The layer to place this JInternalFrame in.
+   */
+  public void setLayer(Integer layer)
+  {
+    JDesktopPane p = getDesktopPane();
+    if (p != null)
+      {
+	int pos = p.getPosition(this);
+	p.setLayer(this, layer.intValue(), pos);
+      }
+  }
+
+  /**
+   * This method sets the JLayeredPane to use with this JInternalFrame.
+   *
+   * @param layered The JLayeredPane to use as a layeredPane.
+   */
+  public void setLayeredPane(JLayeredPane layered)
+  {
+    if (layered != getLayeredPane())
+      {
+	JLayeredPane old = getLayeredPane();
+	getRootPane().setLayeredPane(layered);
+	firePropertyChange(LAYERED_PANE_PROPERTY, old, layered);
+      }
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be maximized.
+   *
+   * @param b Whether this JInternalFrame can be maximized.
+   */
+  public void setMaximizable(boolean b)
+  {
+    maximizable = b;
+  }
+
+  /**
+   * This method sets the Layout Manager used in the JInternalFrame. SetLayout
+   * should not be called on the JInternalFrame directly. Instead, it should
+   * be called with JInternalFrame.getContentPane().setLayout. Calls to this
+   * method with root pane checking enabled will cause exceptions to be
+   * thrown.
+   *
+   * @param manager The Layout Manager to be used with the JInternalFrame.
+   *
+   * @throws Error If rootPaneChecking is enabled.
+   */
+  public void setLayout(LayoutManager manager)
+  {
+    if (isRootPaneCheckingEnabled())
+      throw new Error("Cannot set layout. Use getContentPane().setLayout() instead.");
+    super.setLayout(manager);
+  }
+
+  /**
+   * This method sets the JInternalFrame to maximized (if the given argument
+   * is true) or restores the JInternalFrame to its normal bounds otherwise.
+   *
+   * @param b Whether this JInteralFrame will be maximized or restored.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setMaximum(boolean b) throws PropertyVetoException
+  {
+    if (b != isMaximum())
+      {
+	fireVetoableChange(IS_MAXIMUM_PROPERTY, b, isMaximum);
+	isMaximum = b;
+	if (b)
+	  setNormalBounds(getBounds());
+	maxTransition = ! b;
+	firePropertyChange(IS_MAXIMUM_PROPERTY, ! isMaximum, isMaximum);
+	maxTransition = false;
+      }
+  }
+
+  /**
+   * This method is deprecated. This method sets the JMenuBar used with this
+   * JInternalFrame.
+   *
+   * @param m The JMenuBar to use with this JInternalFrame.
+   */
+  public void setMenuBar(JMenuBar m)
+  {
+    setJMenuBar(m);
+  }
+
+  /**
+   * This method sets the bounds that this JInternalFrame will be restored to.
+   *
+   * @param r The bounds that this JInternalFrame will be restored to.
+   */
+  public void setNormalBounds(Rectangle r)
+  {
+    storedBounds.setBounds(r.x, r.y, r.width, r.height);
+  }
+
+  /**
+   * This method sets whether the JInternalFrame can be resized by a user
+   * action (like dragging at the frame borders).
+   *
+   * @param b Whether this JInternalFramer can be resized.
+   */
+  public void setResizable(boolean b)
+  {
+    resizable = b;
+  }
+
+  /**
+   * This method sets the Root Pane for this JInternalFrame.
+   *
+   * @param root The Root Pane for this JInternalFrame.
+   */
+  protected void setRootPane(JRootPane root)
+  {
+    if (rootPane != null)
+      remove(rootPane);
+
+    rootPane = root;
+    add(root);
+  }
+
+  /**
+   * This method sets whether root pane checking is enabled. If root pane
+   * checking is enabled, then calls to addImpl and setLayout will throw
+   * exceptions.
+   *
+   * @param enabled Whether root pane checking is enabled.
+   */
+  protected void setRootPaneCheckingEnabled(boolean enabled)
+  {
+    rootPaneCheckingEnabled = enabled;
+  }
+
+  /**
+   * This method sets whether this JInternalFrame is the selected frame in the
+   * JDesktopPane (or other container). When selected, a JInternalFrame will
+   * have focus and paint its TitlePane differently (usually a different
+   * colour). If this method selects the frame, this JInternalFrame will fire
+   * an INTERNAL_FRAME_ACTIVATED event. If it deselects this frame, it will
+   * fire an INTERNAL_FRAME_DEACTIVATED event.
+   *
+   * @param selected Whether this JInternalFrame will become selected or
+   *        deselected.
+   *
+   * @throws PropertyVetoException If a VetoableChangeListener vetoes the change.
+   */
+  public void setSelected(boolean selected) throws PropertyVetoException
+  {
+    if (selected != isSelected())
+      {
+	fireVetoableChange(IS_SELECTED_PROPERTY, selected, isSelected);
+
+	if (! selected)
+	  defaultFocus = getMostRecentFocusOwner();
+
+	isSelected = selected;
+
+	if (selected)
+	  restoreSubcomponentFocus();
+
+	firePropertyChange(IS_SELECTED_PROPERTY, ! isSelected, isSelected);
+
+	if (isSelected)
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
+	else
+	  fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
+      }
+  }
+
+  /**
+   * This method sets the title displayed in the TitlePane of this
+   * JInternalFrame.
+   *
+   * @param title The title displayed.
+   */
+  public void setTitle(String title)
+  {
+    if (title == null && this.title == null)
+      return;
+    if (title == null || this.title == null || ! this.title.equals(title))
+      {
+	String old = title;
+	this.title = title;
+	firePropertyChange(TITLE_PROPERTY, old, this.title);
+      }
+  }
+
+  /**
+   * This method displays the JInternalFrame. If it is not visible, this
+   * method will bring this JInternalFrame to the front, make it visible and
+   * select it. If this is the first time this JInternalFrame is made
+   * visible, an INTERNAL_FRAME_OPENED event will be fired.
+   */
+  public void show()
+  {
+    if (! isVisible())
+      {
+	moveToFront();
+	super.show();
+
+	JDesktopPane pane = getDesktopPane();
+	if (pane != null)
+	  pane.setSelectedFrame(this);
+	else
+	  {
+	    try
+	      {
+		setSelected(true);
+	      }
+	    catch (PropertyVetoException e)
+	      {
+		// Do nothing. if they don't want to be selected.
+	      }
+	  }
+	if (isFirstTimeVisible)
+	  {
+	    isFirstTimeVisible = false;
+	    fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
+	  }
+      }
+  }
+
+  /**
+   * This method is used to set the UI responsible for the JInternalFrame.
+   *
+   * @param ui The UI responsible for the JInternalFrame.
+   */
+  public void setUI(InternalFrameUI ui)
+  {
+    super.setUI(ui);
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brough to back in the
+   * z-order.
+   */
+  public void toBack()
+  {
+    moveToBack();
+  }
+
+  /**
+   * This method causes the JInternalFrame to be brought to front in the
+   * z-order.
+   */
+  public void toFront()
+  {
+    moveToFront();
+  }
+
+  /**
+   * This method resets the UI to the Look and Feel defaults.
+   */
+  public void updateUI()
+  {
+    setUI((InternalFrameUI) UIManager.getUI(this));
+  }
+
+  /**
+   * This helper method allows JInternalFrames to signal that they were
+   * iconned for the first time.
+   *
+   * @param b Whether the JInternalFrame was iconned.
+   * @param ID The identifier of the property change event to fire if the
+   *        JInternalFrame is iconned for the first time.
+   */
+  void setWasIcon(boolean b, String ID)
+  {
+    if (b && ! wasIcon)
+      {
+	wasIcon = b;
+	firePropertyChange(ID, ! b, b);
+      }
+  }
+
+  /**
+   * This helper method returns whether the JInternalFrame has been iconned
+   * once already.
+   *
+   * @return Whether the JInternalFrame has been iconned once already.
+   */
+  boolean getWasIcon()
+  {
+    return wasIcon;
+  }
+
+  /**
+   * This method is a convenience method to fire vetoable property changes.
+   *
+   * @param name The identifier of the property change.
+   * @param oldValue The old value.
+   * @param newValue The new value.
+   *
+   * @throws PropertyVetoException Fired if a vetoable change listener vetoes
+   *         the change.
+   */
+  private void fireVetoableChange(String name, boolean oldValue,
+                                  boolean newValue)
+                           throws PropertyVetoException
+  {
+    super.fireVetoableChange(name, new Boolean(oldValue), new Boolean(newValue));
+  }
+} // class JInternalFrame
Index: javax/swing/JLabel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JLabel.java,v
retrieving revision 1.4.2.4
diff -u -r1.4.2.4 JLabel.java
--- javax/swing/JLabel.java	23 Mar 2004 14:42:19 -0000	1.4.2.4
+++ javax/swing/JLabel.java	9 Jun 2004 20:47:01 -0000
@@ -331,9 +331,8 @@
    */
   public Icon getDisabledIcon()
   {
-    //FIXME: We should be gray-scaling the active icon and then returning it
     if (disabledIcon == null && activeIcon instanceof ImageIcon)
-      setDisabledIcon(activeIcon);
+      return new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) activeIcon).getImage()));
     return disabledIcon;
   }
 
Index: javax/swing/JMenuBar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JMenuBar.java,v
retrieving revision 1.2.18.3
diff -u -r1.2.18.3 JMenuBar.java
--- javax/swing/JMenuBar.java	7 Jun 2004 12:41:09 -0000	1.2.18.3
+++ javax/swing/JMenuBar.java	9 Jun 2004 20:47:01 -0000
@@ -140,7 +140,7 @@
    */
   public Component getComponentAtIndex(int i)
   {
-    return getComponentAt(i);
+    return getComponent(i);
   }
 
   /**
Index: javax/swing/JOptionPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JOptionPane.java,v
retrieving revision 1.3.2.4
diff -u -r1.3.2.4 JOptionPane.java
--- javax/swing/JOptionPane.java	8 Jun 2004 09:28:42 -0000	1.3.2.4
+++ javax/swing/JOptionPane.java	9 Jun 2004 20:47:02 -0000
@@ -421,21 +421,7 @@
    */
   public static JDesktopPane getDesktopPaneForComponent(Component parentComponent)
   {
-    if (parentComponent == null)
-      return null;
-    if (parentComponent instanceof JDesktopPane)
-      return (JDesktopPane) parentComponent;
-    JDesktopPane parent = null;
-    while (parentComponent.getParent() != null)
-      {
-	parentComponent = parentComponent.getParent();
-	if (parentComponent instanceof JDesktopPane)
-	  {
-	    parent = (JDesktopPane) parentComponent;
-	    break;
-	  }
-      }
-    return parent;
+    return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class, parentComponent);
   }
 
   /**
@@ -448,21 +434,7 @@
    */
   public static Frame getFrameForComponent(Component parentComponent)
   {
-    if (parentComponent == null)
-      return null;
-    if (parentComponent instanceof Frame)
-      return (Frame) parentComponent;
-    Frame parent = null;
-    while (parentComponent.getParent() != null)
-      {
-	parentComponent = parentComponent.getParent();
-	if (parentComponent instanceof Frame)
-	  {
-	    parent = (Frame) parentComponent;
-	    break;
-	  }
-      }
-    return parent;
+    return (Frame) SwingUtilities.getAncestorOfClass(Frame.class, parentComponent);
   }
 
   /**
Index: javax/swing/JSplitPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/JSplitPane.java,v
retrieving revision 1.2.8.3
diff -u -r1.2.8.3 JSplitPane.java
--- javax/swing/JSplitPane.java	8 Jun 2004 09:28:42 -0000	1.2.8.3
+++ javax/swing/JSplitPane.java	9 Jun 2004 20:47:02 -0000
@@ -563,7 +563,7 @@
    */
   public void remove(int index)
   {
-    Component component = getComponentAt(index);
+    Component component = getComponent(index);
     if (component == leftComponent)
       leftComponent = null;
     else if (component == rightComponent)
Index: javax/swing/SwingUtilities.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/SwingUtilities.java,v
retrieving revision 1.6.2.5
diff -u -r1.6.2.5 SwingUtilities.java
--- javax/swing/SwingUtilities.java	8 Jun 2004 20:00:25 -0000	1.6.2.5
+++ javax/swing/SwingUtilities.java	9 Jun 2004 20:47:02 -0000
@@ -376,8 +376,12 @@
 
     return pt;
   }
-
   
+  public static Point convertPoint(Component source, Point aPoint, Component destination)
+  {
+    return convertPoint(source, aPoint.x, aPoint.y, destination);
+  }
+
   /**
    * Converts a rectangle from the coordinate space of one component to
    * another. This is equivalent to converting the rectangle from
@@ -719,7 +723,6 @@
         iconR.y = centerLine - iconR.height/2;
         break;
       }
-
     // The two rectangles are laid out correctly now, but only assuming
     // that their upper left corner is at (0,0). If we have any alignment other
     // than TOP and LEFT, we need to adjust them.
Index: javax/swing/plaf/basic/BasicButtonUI.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicButtonUI.java,v
retrieving revision 1.6.2.3
diff -u -r1.6.2.3 BasicButtonUI.java
--- javax/swing/plaf/basic/BasicButtonUI.java	8 Jun 2004 20:15:48 -0000	1.6.2.3
+++ javax/swing/plaf/basic/BasicButtonUI.java	9 Jun 2004 20:47:02 -0000
@@ -343,7 +343,7 @@
    */
   protected void paintButtonNormal(Graphics g, Rectangle area, JComponent b)
   {
-    if (((AbstractButton)b).isContentAreaFilled())
+    if (((AbstractButton)b).isContentAreaFilled() && b.isOpaque())
       {
         g.setColor(b.getBackground());
         g.fillRect(area.x, area.y, area.width, area.height);
Index: javax/swing/plaf/basic/BasicDesktopIconUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicDesktopIconUI.java
diff -N javax/swing/plaf/basic/BasicDesktopIconUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicDesktopIconUI.java	9 Jun 2004 20:47:02 -0000
@@ -0,0 +1,596 @@
+/* BasicDesktopIconUI.java --
+   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyVetoException;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.DesktopPaneUI;
+
+
+/**
+ * This class acts as the UI delegate for JDesktopIcons for the Basic look and feel.
+ */
+public class BasicDesktopIconUI extends DesktopIconUI
+{
+  /**
+   * This helper class handles mouse events that occur on the JDesktopIcon.
+   */
+  public class MouseInputHandler extends MouseInputAdapter
+  {
+    /** The x offset from the MouseEvent coordinates to the top left corner. */
+    private transient int xOffset;
+
+    /** The y offset fromt he MouseEvent coordinates to the top left corner. */
+    private transient int yOffset;
+
+    /** A cached value of the JDesktopPane that parents this JDesktopIcon. */
+    private transient JDesktopPane pane;
+
+    /**
+     * This method is called when the mouse is dragged in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      Rectangle b = desktopIcon.getBounds();
+
+      moveAndRepaint(desktopIcon, b.x + e.getX() - xOffset,
+                     b.y + e.getY() - yOffset, b.width, b.height);
+    }
+
+    /**
+     * This method is called when the mouse is moved in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // Nothing to do.
+    }
+
+    /**
+     * This method is called when the mouse is pressed in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      xOffset = e.getX();
+      yOffset = e.getY();
+      pane = frame.getDesktopPane();
+      if (pane != null)
+	pane.getDesktopManager().beginDraggingFrame(desktopIcon);
+    }
+
+    /**
+     * This method is called when the mouse is released in the JDesktopIcon.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      if (pane != null)
+	pane.getDesktopManager().endDraggingFrame(desktopIcon);
+      xOffset = 0;
+      yOffset = 0;
+    }
+
+    /**
+     * This method moves and repaints the JDesktopIcon to the given bounds.
+     *
+     * @param f The JComponent to move and repaint.
+     * @param newX The new x coordinate.
+     * @param newY The new y coordinate.
+     * @param newWidth The new width.
+     * @param newHeight The new height.
+     */
+    public void moveAndRepaint(JComponent f, int newX, int newY, int newWidth,
+                               int newHeight)
+    {
+      if (pane != null)
+	pane.getDesktopManager().dragFrame(f, newX, newY);
+      else
+	desktopIcon.setBounds(newX, newY, newWidth, newHeight);
+    }
+  }
+
+  /**
+   * This class acts as the border for the JDesktopIcon.
+   */
+  private class DesktopIconBorder implements Border
+  {
+    /** The left inset value. */
+    int left = 10;
+
+    /** The top inset value. */
+    int top = 4;
+
+    /** The right inset value. */
+    int right = top;
+
+    /** The bottom inset value. */
+    int bottom = top;
+
+    /**
+     * This method returns the insets of the border.
+     *
+     * @param c The Component to find border insets for.
+     *
+     * @return The border insets.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(top, left, bottom, right);
+    }
+
+    /**
+     * This method returns whether the border is opaque.
+     *
+     * @return Whether the border is opaque.
+     */
+    public boolean isBorderOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method paints the border.
+     *
+     * @param c The Component the border is in.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate of the Component.
+     * @param y The y coordinate of the Component.
+     * @param width The width of the Component.
+     * @param height The height of the Component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+
+      g.setColor(Color.LIGHT_GRAY);
+
+      g.fillRect(0, 0, left, height);
+      g.fillRect(0, 0, width, top);
+      g.fillRect(0, height - bottom, width, bottom);
+      g.fillRect(width - right, 0, right, height);
+
+      g.setColor(Color.BLACK);
+      g.drawRect(0, 0, width - 1, height - 1);
+
+      int fHeight = height / 4;
+      int hLeft = left / 2;
+
+      g.setColor(Color.BLACK);
+      g.fillRect(hLeft, fHeight, 2, 2);
+      g.fillRect(hLeft, fHeight * 2, 2, 2);
+      g.fillRect(hLeft, fHeight * 3, 2, 2);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The static width and height of the iconSize. */
+  private static final int iconSize = 16;
+
+  /**
+   * This class represents the default frame icon when none
+   * is supplied by the JInternalFrame.
+   */
+  static class InternalFrameDefaultMenuIcon implements Icon
+  {
+    /**
+     * This returns the icon height.
+     *
+     * @return The icon height.
+     */
+    public int getIconHeight()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This returns the icon width.
+     *
+     * @return The icon width.
+     */
+    public int getIconWidth()
+    {
+      return iconSize;
+    }
+
+    /**
+     * This method paints the icon.
+     *
+     * @param c The Component this icon belongs to.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate to paint at.
+     * @param y The y coordinate to paint at.
+     */
+    public void paintIcon(Component c, Graphics g, int x, int y)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+
+      g.setColor(Color.BLUE);
+      g.fillRect(0, 0, iconSize, (int) ((double) iconSize / 3) + 1);
+
+      g.setColor(Color.WHITE);
+      g.fillRect(0, (int) ((double) iconSize / 3), iconSize, iconSize * 5 / 6);
+
+      g.setColor(Color.GRAY);
+      g.drawRect(0, 0, iconSize, iconSize);
+
+      g.setColor(saved);
+      g.translate(-x, -y);
+    }
+  }
+
+  /** The default JDesktopIcon width. */
+  private static final int iconWidth = 160;
+
+  /** The default JDesktopIcon height */
+  private static final int iconHeight = 35;
+
+  /** The JDesktopIcon this UI delegate represents. */
+  protected JDesktopIcon desktopIcon;
+
+  /** The JInternalFrame associated with the JDesktopIcon. */
+  protected JInternalFrame frame;
+
+  /** The MouseListener responsible for reacting to MouseEvents on the JDesktopIcon. */
+  private transient MouseInputListener mouseHandler;
+
+  /** The Button in the JDesktopIcon responsible for deiconifying it. */
+  private transient BoundButton button;
+
+  /** The PropertyChangeListener listening to the JDesktopIcon. */
+  private transient PropertyChangeListener propertyHandler;
+  
+  /** The default icon used when no frame icon is given by the JInternalFrame. */
+  static Icon defaultIcon = new InternalFrameDefaultMenuIcon();
+
+  /**
+   * This is a helper class that is used in JDesktopIcon and gives the Button a predetermined size.
+   */
+  private class BoundButton extends JButton
+  {
+    /**
+     * Creates a new BoundButton object.
+     *
+     * @param title The title of the button.
+     */
+    public BoundButton(String title)
+    {
+      super(title);
+    }
+
+    /**
+     * This method returns a standard size (based on the defaults of the JDesktopIcon) and the insets.
+     *
+     * @return The preferred size of the JDesktopIcon.
+     */
+    public Dimension getPreferredSize()
+    {
+      Insets insets = desktopIcon.getInsets();
+      return new Dimension(iconWidth - insets.left - insets.right,
+                           iconHeight - insets.top - insets.bottom);
+    }
+
+    /**
+     * This method returns the minimum size of the button.
+     *
+     * @return The minimum size of the button.
+     */
+    public Dimension getMinimumSize()
+    {
+      return getPreferredSize();
+    }
+
+    /**
+     * This method returns the maximum size of the button.
+     *
+     * @return The maximum size of the button.
+     */
+    public Dimension getMaximumSize()
+    {
+      return getPreferredSize();
+    }
+  }
+
+  /**
+   * Creates a new BasicDesktopIconUI object.
+   */
+  public BasicDesktopIconUI()
+  {
+  }
+
+  /**
+   * This method creates a new BasicDesktopIconUI for the given JComponent.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicDesktopIconUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicDesktopIconUI();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install this UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JDesktopIcon)
+      {
+	desktopIcon = (JDesktopIcon) c;
+	desktopIcon.setLayout(new BorderLayout());
+	frame = desktopIcon.getInternalFrame();
+
+	installDefaults();
+	installComponents();
+	installListeners();
+
+	desktopIcon.setOpaque(true);
+      }
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    desktopIcon.setOpaque(false);
+    
+    uninstallListeners();
+    uninstallComponents();
+    uninstallDefaults();
+    
+    frame = null;
+    desktopIcon.setLayout(null);
+    desktopIcon = null;
+  }
+
+  /**
+   * This method installs the necessary sub components for the JDesktopIcon.
+   */
+  protected void installComponents()
+  {
+    // Try to create a button based on what the frame's
+    // state is currently
+    button = new BoundButton(frame.getTitle());
+    button.setHorizontalAlignment(SwingConstants.LEFT);
+    button.setHorizontalTextPosition(SwingConstants.TRAILING);
+
+    Icon use = frame.getFrameIcon();
+    if (use == null)
+      use = defaultIcon;
+    button.setIcon(use);
+
+    desktopIcon.add(button, SwingConstants.CENTER);
+  }
+
+  /**
+   * This method uninstalls the sub components for the JDesktopIcon.
+   */
+  protected void uninstallComponents()
+  {
+    desktopIcon.remove(button);
+    
+    button = null;
+  }
+
+  /**
+   * This method installs the listeners needed by this UI.
+   */
+  protected void installListeners()
+  {
+    mouseHandler = createMouseInputListener();
+
+    desktopIcon.addMouseMotionListener(mouseHandler);
+    desktopIcon.addMouseListener(mouseHandler);
+
+    propertyHandler = new PropertyChangeListener()
+        {
+	  public void propertyChange(PropertyChangeEvent e)
+	  {
+	    if (e.getPropertyName().equals(JInternalFrame.TITLE_PROPERTY))
+	      button.setText(desktopIcon.getInternalFrame().getTitle());
+	    else if (e.getPropertyName().equals(JInternalFrame.FRAME_ICON_PROPERTY))
+	      {
+		Icon use = desktopIcon.getInternalFrame().getFrameIcon();
+		if (use == null)
+		  use = defaultIcon;
+		button.setIcon(use);
+	      }
+	    desktopIcon.revalidate();
+	    desktopIcon.repaint();
+	  }
+        };
+    frame.addPropertyChangeListener(propertyHandler);
+
+    button.addActionListener(new ActionListener()
+        {
+	  public void actionPerformed(ActionEvent e)
+	  {
+	    try
+	      {
+		deiconize();
+	      }
+	    catch (PropertyVetoException pve)
+	      {
+		// do nothing.
+	      }
+	  }
+        });
+  }
+
+  /**
+   * This method uninstalls the listeners needed by the UI.
+   */
+  protected void uninstallListeners()
+  {
+    // button is nulled so no need to remove it.
+    
+    frame.removePropertyChangeListener(propertyHandler);
+    propertyHandler = null;
+    
+    desktopIcon.removeMouseMotionListener(mouseHandler);
+    desktopIcon.removeMouseListener(mouseHandler);
+  }
+
+  /**
+   * This method installs the defaults for the JDesktopIcon.
+   */
+  protected void installDefaults()
+  {
+    // FIXME: Move border to defaults.
+    desktopIcon.setBorder(new DesktopIconBorder());  
+  }
+
+  /**
+   * This method uninstalls the defaults for the JDesktopIcon.
+   */
+  protected void uninstallDefaults()
+  {
+    desktopIcon.setBorder(null);
+  }
+
+  /**
+   * This method creates a new MouseInputListener for the JDesktopIcon.
+   *
+   * @return A new MouseInputListener.
+   */
+  protected MouseInputListener createMouseInputListener()
+  {
+    return new MouseInputHandler();
+  }
+
+  /**
+   * This method returns the preferred size for the given JComponent.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    return new Dimension(iconWidth, iconHeight);
+  }
+
+  /**
+   * This method returns the minimum size for the given JComponent.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the maximum size for the given JComponent.
+   *
+   * @param c The JComponent to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the insets of the given JComponent.
+   *
+   * @param c The JComponent to find insets for.
+   *
+   * @return The insets of the given JComponent.
+   */
+  public Insets getInsets(JComponent c)
+  {
+    return c.getInsets();
+  }
+
+  /**
+   * This method deiconizes the JInternalFrame associated with the JDesktopIcon.
+   */
+  public void deiconize() 
+  {
+    try
+    {
+      frame.setIcon(false);
+    }
+    catch (PropertyVetoException pve)
+    {
+    }
+  }
+}
Index: javax/swing/plaf/basic/BasicDesktopPaneUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicDesktopPaneUI.java
diff -N javax/swing/plaf/basic/BasicDesktopPaneUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicDesktopPaneUI.java	9 Jun 2004 20:47:02 -0000
@@ -0,0 +1,459 @@
+/* BasicDesktopPaneUI.java --
+   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyVetoException;
+import javax.swing.AbstractAction;
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JInternalFrame.JDesktopIcon;
+import javax.swing.KeyStroke;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.DesktopIconUI;
+import javax.swing.plaf.DesktopPaneUI;
+
+
+/**
+ * This class is the UI delegate for JDesktopPane for the Basic look and feel.
+ */
+public class BasicDesktopPaneUI extends DesktopPaneUI
+{
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be closed.
+   */
+  protected class CloseAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setClosed(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isClosable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be maximized.
+   */
+  protected class MaximizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setMaximum(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isMaximizable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that cause JInternalFrames
+   * to be minimized.
+   */
+  protected class MinimizeAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      if (desktop.getSelectedFrame() != null)
+        {
+	  try
+	    {
+	      desktop.getSelectedFrame().setIcon(true);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether the action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      if (desktop.getSelectedFrame() != null)
+	return desktop.getSelectedFrame().isIconifiable();
+      return false;
+    }
+  }
+
+  /**
+   * This helper class is used to handle key events that pass the SELECTED
+   * property to the next JInternalFrame in the JDesktopPane's list of
+   * children.
+   */
+  protected class NavigateAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      // This is supposed to set the next selected frame. 
+      JInternalFrame[] frames = desktop.getAllFrames();
+      if (frames.length == 0)
+	return;
+
+      JInternalFrame sFrame = frames[0];
+      if (desktop.getSelectedFrame() != null)
+	sFrame = desktop.getSelectedFrame();
+
+      int i = 0;
+      for (; i < frames.length; i++)
+	if (frames[i] == sFrame)
+	  break;
+
+      // FIXME: Navigate actions go reverse too.	  
+      if (i == frames.length)
+	i = 0;
+
+      desktop.setSelectedFrame(frames[i]);
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether this action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      // Always true.
+      return true;
+    }
+  }
+
+  /**
+   * This helper class is used to restore the JInternalFrame to its original
+   * size before maximizing or iconifying.
+   */
+  protected class OpenAction extends AbstractAction
+  {
+    /**
+     * This method is called when the action is performed.
+     *
+     * @param e The ActionEvent.
+     */
+    public void actionPerformed(ActionEvent e)
+    {
+      JInternalFrame frame = desktop.getSelectedFrame();
+      if (frame != null)
+        {
+	  try
+	    {
+	      if (frame.isIcon())
+		frame.setIcon(false);
+	      else if (frame.isMaximum())
+		frame.setMaximum(false);
+	    }
+	  catch (PropertyVetoException pve)
+	    {
+	    }
+        }
+    }
+
+    /**
+     * This method returns whether the action is enabled.
+     *
+     * @return Whether this action is enabled.
+     */
+    public boolean isEnabled()
+    {
+      // JInternalFrames are always restorable.
+      return true;
+    }
+  }
+
+  /** The KeyStroke associated with closing JInternalFrames. */
+  protected KeyStroke closeKey;
+
+  /** The KeyStroke associated with maximizing JInternalFrames. */
+  protected KeyStroke maximizeKey;
+
+  /** The KeyStroke associated with minimizing JInternalFrames. */
+  protected KeyStroke minimizeKey;
+
+  /**
+   * The KeyStroke associated with navigating (forward?) through
+   * JInternalFrames.
+   */
+  protected KeyStroke navigateKey;
+
+  /**
+   * The KeyStroke associated with navigating (backward?) through
+   * JInternalFrames.
+   */
+  protected KeyStroke navigateKey2;
+
+  /** The default desktop manager used with JDesktopPane. */
+  protected DesktopManager desktopManager;
+
+  /** The JDesktopPane this UI is used with. */
+  protected JDesktopPane desktop;
+
+  /**
+   * Creates a new BasicDesktopPaneUI object.
+   */
+  public BasicDesktopPaneUI()
+  {
+  }
+
+  /**
+   * This method creates a BasicDesktopPaneUI for the given JComponent.
+   *
+   * @param c The JComponent to create a UI for.
+   *
+   * @return A new BasicDesktopPaneUI.
+   */
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicDesktopPaneUI();
+  }
+
+  /**
+   * This method returns the maximum size for the given JComponent.
+   *
+   * @param c The JComponent to find a maximum size for.
+   *
+   * @return The maximum size for the given JComponent.
+   */
+  public Dimension getMaximumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the minimum size for the given JComponent.
+   *
+   * @param c The JComponent to find a minimum size for.
+   *
+   * @return The minimum size for the given JComponent.
+   */
+  public Dimension getMinimumSize(JComponent c)
+  {
+    return getPreferredSize(c);
+  }
+
+  /**
+   * This method returns the preferred size for the given JComponent.
+   *
+   * @param c The JComponent to find a preferred size for.
+   *
+   * @return The preferred size for the given JComponent.
+   */
+  public Dimension getPreferredSize(JComponent c)
+  {
+    // return null because JDesktopPanes don't have preferred sizes.
+    return null;
+  }
+
+  /**
+   * This method installs the defaults for the JDesktopPane provided by the
+   * current look and feel.
+   */
+  protected void installDefaults()
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    desktop.setBackground(defaults.getColor("Desktop.background"));
+  }
+
+  /**
+   * This method installs the desktop manager for the JDesktopPane.
+   */
+  protected void installDesktopManager()
+  {
+    desktopManager = new DefaultDesktopManager();
+    desktop.setDesktopManager(desktopManager);
+  }
+
+  /**
+   * This method installs the keyboard actions for the JDesktopPane.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: create actions and keystrokes.
+    registerKeyboardAction();
+  }
+
+  /**
+   * This method installs the UI for the given JComponent.
+   *
+   * @param c The JComponent to install this UI for.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JDesktopPane)
+      {
+	desktop = (JDesktopPane) c;
+
+	installDefaults();
+	installDesktopManager();
+	installKeyboardActions();
+      }
+  }
+
+  /**
+   * This method registers the actions to the appropriate Action and Input
+   * maps.
+   */
+  protected void registerKeyboardAction()
+  {
+    // FIXME: Do the binding.
+    // XXX: the gtk windows tend to intercept a lot of the
+    // key events for themselves. must figure a way past that
+    // before binding
+  }
+
+  /**
+   * This method reverses the work done by the installDefaults method.
+   */
+  protected void uninstallDefaults()
+  {
+    desktop.setBackground(null);
+  }
+
+  /**
+   * This method reverses the work done by the installDesktopManager method.
+   */
+  protected void uninstallDesktopManager()
+  {
+    desktopManager = null;
+    desktop.setDesktopManager(null);
+  }
+
+  /**
+   * This method reverses the work done by the installKeyboardActions method.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    unregisterKeyboardActions();
+    // FIXME: null the actions and keystrokes.
+  }
+
+  /**
+   * This method reverses the work done by the registerKeyboardActions method.
+   */
+  protected void unregisterKeyboardActions()
+  {
+    // FIXME: unmap the keystrokes
+  }
+
+  /**
+   * This method uninstalls the UI for the given JComponent. It should reverse
+   * all the work done by the installUI method.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallDesktopManager();
+    uninstallDefaults();
+
+    desktop = null;
+  }
+}
Index: javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
diff -N javax/swing/plaf/basic/BasicInternalFrameTitlePane.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicInternalFrameTitlePane.java	9 Jun 2004 20:47:02 -0000
@@ -0,0 +1,1004 @@
+/* BasicInternalFrameTitlePane.java --
+   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.Polygon;
+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.event.InternalFrameEvent;
+import javax.swing.UIManager;
+import javax.swing.UIDefaults;
+
+
+/**
+ * This class acts as a titlebar for JInternalFrames.
+ */
+public class BasicInternalFrameTitlePane extends JComponent
+{
+  /**
+   * The Action responsible for closing the JInternalFrame.
+   */
+  protected class CloseAction extends AbstractAction
+  {
+    /**
+     * 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)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for iconifying the JInternalFrame.
+   */
+  protected class IconifyAction extends AbstractAction
+  {
+    /**
+     * 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)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for maximizing the JInternalFrame.
+   */
+  protected class MaximizeAction extends AbstractAction
+  {
+    /**
+     * 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);
+	  else if (frame.isMaximum())
+	    frame.setMaximum(false);
+        }
+      catch (PropertyVetoException pve)
+        {
+        }
+    }
+  }
+
+  /**
+   * This Action is responsible for dragging the JInternalFrame.
+   */
+  protected class MoveAction extends AbstractAction
+  {
+    /**
+     * 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.
+   */
+  protected class RestoreAction extends AbstractAction
+  {
+    /**
+     * 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)
+	    {
+	    }
+        }
+    }
+  }
+
+  /**
+   * This action is responsible for sizing the JInternalFrame.
+   */
+  protected class SizeAction extends AbstractAction
+  {
+    /**
+     * 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.
+   */
+  protected 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)
+    {
+      // The title and frameIcon are taken care of during painting time.
+      // The only other thing this will care about are the "is----izable"
+      // properties. So we call enable actions to properly handle the 
+      // buttons and menu items for us.
+      enableActions();
+    }
+  }
+
+  /**
+   * This class acts as the MenuBar for the TitlePane. Clicking on the Frame
+   * Icon in the top left corner will activate it.
+   */
+  protected class SystemMenuBar extends JMenuBar
+  {
+    /**
+     * This method returns true if it can receive focus.
+     *
+     * @return True if this Component can receive focus.
+     */
+    public boolean isFocusTransversable()
+    {
+      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.
+   */
+  protected class TitlePaneLayout implements LayoutManager
+  {
+    /**
+     * 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)
+    {
+      enableActions();
+
+      Insets insets = c.getInsets();
+      int width = c.getBounds().width - insets.left - insets.right;
+      int height = c.getBounds().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;
+
+      Insets i = closeButton.getInsets();
+      Dimension prefs = new Dimension(iconSize + i.left + i.right,
+                                      iconSize + i.top + i.bottom);
+      int top = insets.top + (height - prefs.height) / 2;
+      if (closeAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  closeButton.setVisible(true);
+	  closeButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	closeButton.setVisible(false);
+
+      if (maximizeAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  maxButton.setVisible(true);
+	  maxButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	maxButton.setVisible(false);
+
+      if (iconifyAction.isEnabled())
+        {
+	  loc -= prefs.width;
+	  iconButton.setVisible(true);
+	  iconButton.setBounds(loc, top, prefs.width, prefs.height);
+        }
+      else
+	iconButton.setVisible(false);
+
+      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)
+    {
+      Insets frameInsets = frame.getInsets();
+
+      // Height is the max of the preferredHeights of all components
+      // inside the pane
+      int height = 0;
+      int width = 0;
+      Dimension d;
+
+      Component[] components = BasicInternalFrameTitlePane.this.getComponents();
+      for (int i = 0; i < components.length; i++)
+        {
+	  d = components[i].getPreferredSize();
+	  height = Math.max(height, d.height);
+	  width += d.width;
+        }
+
+      Insets insets = BasicInternalFrameTitlePane.this.getInsets();
+      height += insets.top + insets.bottom;
+
+      return new Dimension(width, height);
+    }
+
+    /**
+     * This method is called when removing a Component from the Container.
+     *
+     * @param c The Component to remove.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+    }
+  }
+
+  /**
+   * 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));
+      setBorder(null);
+    }
+
+    /**
+     * 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 String CLOSE_CMD = "Close";
+
+  /** The action command for the Minimize action. */
+  protected static String ICONIFY_CMD = "Minimize";
+
+  /** The action command for the Maximize action. */
+  protected static String MAXIMIZE_CMD = "Maximize";
+
+  /** The action command for the Move action. */
+  protected static String MOVE_CMD = "Move";
+
+  /** The action command for the Restore action. */
+  protected static String RESTORE_CMD = "Restore";
+
+  /** The action command for the Size action. */
+  protected static String SIZE_CMD = "Size";
+
+  /** 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;
+
+  /** Active background color. */
+  protected Color activeBGColor;
+
+  /** Active foreground color. */
+  protected Color activeFGColor;
+
+  /** Inactive background color. */
+  protected Color inactiveBGColor;
+
+  /** Inactive foreground color. */
+  protected Color inactiveFGColor;
+
+  // FIXME: These icons need to be moved to MetalIconFactory.
+
+  /** The size of the icons in the buttons. */
+  private static final int iconSize = 16;
+
+  /** The icon displayed in the close button. */
+  protected Icon closeIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	int four = iconSize / 4;
+	int six = iconSize * 6 / 16;
+	int ten = iconSize * 10 / 16;
+	int twelve = iconSize * 12 / 16;
+
+	Polygon a = new Polygon(new int[] { four, six, ten, twelve },
+	                        new int[] { six, four, twelve, ten }, 4);
+	Polygon b = new Polygon(new int[] { four, six, ten, twelve },
+	                        new int[] { ten, twelve, four, six }, 4);
+
+	g.fillPolygon(a);
+	g.fillPolygon(b);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  // FIXME: Create new icon.
+
+  /** The icon displayed in the restore button. */
+  protected Icon minIcon;
+
+  /** The icon displayed in the maximize button. */
+  protected Icon maxIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	int four = iconSize / 4;
+	int two = four / 2;
+	int six = iconSize * 6 / 16;
+	int eight = four * 2;
+
+	g.fillRect(four, four, eight, two);
+	g.drawRect(four, six, eight, six);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** The icon displayed in the iconify button. */
+  protected Icon iconIcon = new Icon()
+    {
+      public int getIconHeight()
+      {
+	return iconSize;
+      }
+
+      public int getIconWidth()
+      {
+	return iconSize;
+      }
+
+      public void paintIcon(Component c, Graphics g, int x, int y)
+      {
+	g.translate(x, y);
+	Color saved = g.getColor();
+	g.setColor(Color.BLACK);
+
+	g.fillRect(iconSize / 4, iconSize * 10 / 16, iconSize / 2, iconSize / 8);
+
+	g.setColor(saved);
+	g.translate(-x, -y);
+      }
+    };
+
+  /** 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.
+   */
+  private transient JLabel title;
+
+  /**
+   * 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);
+
+    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 = new PropertyChangeHandler();
+    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()
+  {
+    // FIXME: move icons to defaults.
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+
+    setFont(defaults.getFont("InternalFrame.titleFont"));
+    activeFGColor = defaults.getColor("InternalFrame.activeTitleForeground");
+    activeBGColor = defaults.getColor("InternalFrame.activeTitleBackground");
+    inactiveFGColor = defaults.getColor("InternalFrame.inactiveTitleForeground");
+    inactiveBGColor = defaults.getColor("InternalFrame.inactiveTitleBackground");
+  }
+
+  /**
+   * This method uninstalls the defaults.
+   */
+  protected void uninstallDefaults()
+  {
+    setFont(null);
+    activeFGColor = null;
+    activeBGColor = null;
+    inactiveFGColor = null;
+    inactiveBGColor = null;
+  }
+
+  /**
+   * This method creates the buttons used in the TitlePane.
+   */
+  protected void createButtons()
+  {
+    closeButton = new PaneButton(closeAction);
+    closeButton.setOpaque(false);
+
+    iconButton = new PaneButton(iconifyAction);
+    iconButton.setOpaque(false);
+
+    maxButton = new PaneButton(maximizeAction);
+    maxButton.setOpaque(false);
+  }
+
+  /**
+   * This method sets the icons in the buttons.
+   */
+  protected void setButtonIcons()
+  {
+    closeButton.setIcon(closeIcon);
+    iconButton.setIcon(iconIcon);
+    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);
+    Font f = g.getFont();
+    FontMetrics fm = g.getFontMetrics(f);
+    if (frame.getTitle() != null && title != null)
+      {
+	Color saved = g.getColor();
+	if (frame.isSelected())
+	  g.setColor(activeFGColor);
+	else
+	  g.setColor(inactiveFGColor);
+	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)
+  {
+    Color saved = g.getColor();
+    Dimension dims = getSize();
+
+    Color bg = getBackground();
+    if (frame.isSelected())
+      bg = activeBGColor;
+    else
+      bg = inactiveBGColor;
+    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();
+  }
+}
Index: javax/swing/plaf/basic/BasicInternalFrameUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicInternalFrameUI.java
diff -N javax/swing/plaf/basic/BasicInternalFrameUI.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicInternalFrameUI.java	9 Jun 2004 20:47:03 -0000
@@ -0,0 +1,1488 @@
+/* BasicInternalFrameUI.java --
+   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.KeyStroke;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.border.AbstractBorder;
+import javax.swing.event.InternalFrameEvent;
+import javax.swing.event.InternalFrameListener;
+import javax.swing.event.MouseInputAdapter;
+import javax.swing.event.MouseInputListener;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.InternalFrameUI;
+import javax.swing.plaf.UIResource;
+
+
+/**
+ * This is the UI delegate for the Basic look and feel for JInternalFrames.
+ */
+public class BasicInternalFrameUI extends InternalFrameUI
+{
+  /**
+   * This is a helper class that listens to the JInternalFrame for
+   * InternalFrameEvents.
+   */
+  protected class BasicInternalFrameListener implements InternalFrameListener
+  {
+    /**
+     * This method is called when the JInternalFrame is activated.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameActivated(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is closed.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameClosed(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is closing.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameClosing(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is deactivated.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameDeactivated(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is  deiconified.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameDeiconified(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is  iconified.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameIconified(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+
+    /**
+     * This method is called when the JInternalFrame is opened.
+     *
+     * @param e The InternalFrameEvent.
+     */
+    public void internalFrameOpened(InternalFrameEvent e)
+    {
+      // FIXME: Implement.
+    }
+  }
+
+  /**
+   * This helper class listens to the edges of the JInternalFrame and the
+   * TitlePane for mouse events. It is responsible for dragging  and resizing
+   * the JInternalFrame in response to the MouseEvents.
+   */
+  protected class BorderListener extends MouseInputAdapter
+    implements SwingConstants
+  {
+    /** FIXME: Use for something. */
+    protected int RESIZE_NONE;
+
+    /** The x offset from the top left corner of the JInternalFrame. */
+    private transient int xOffset = 0;
+
+    /** The y offset from the top left corner of the JInternalFrame. */
+    private transient int yOffset = 0;
+
+    /** The direction that the resize is occuring in. */
+    private transient int direction = -1;
+
+    /**
+     * This method is called when the mouse is clicked.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      // There is nothing to do when the mouse is clicked
+      // on the border.
+    }
+
+    /**
+     * This method is called when the mouse is dragged. This method is
+     * responsible for resizing or dragging the JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      // If the frame is maximized, there is nothing that 
+      // can be dragged around.
+      if (frame.isMaximum())
+	return;
+      DesktopManager dm = getDesktopManager();
+      Rectangle b = frame.getBounds();
+      Insets insets = frame.getInsets();
+      int x = e.getX();
+      int y = e.getY();
+      if (e.getSource() == frame && frame.isResizable())
+        {
+	  switch (direction)
+	    {
+	    case NORTH:
+	      dm.resizeFrame(frame, b.x, b.y + y, b.width, b.height - y);
+	      break;
+	    case NORTH_EAST:
+	      dm.resizeFrame(frame, b.x, b.y + y, x, b.height - y);
+	      break;
+	    case EAST:
+	      dm.resizeFrame(frame, b.x, b.y, x, b.height);
+	      break;
+	    case SOUTH_EAST:
+	      dm.resizeFrame(frame, b.x, b.y, x, y);
+	      break;
+	    case SOUTH:
+	      dm.resizeFrame(frame, b.x, b.y, b.width, y);
+	      break;
+	    case SOUTH_WEST:
+	      dm.resizeFrame(frame, b.x + x, b.y, b.width - x, y);
+	      break;
+	    case WEST:
+	      dm.resizeFrame(frame, b.x + x, b.y, b.width - x, b.height);
+	      break;
+	    case NORTH_WEST:
+	      dm.resizeFrame(frame, b.x + x, b.y + y, b.width - x, b.height
+	                     - y);
+	      break;
+	    }
+        }
+      else if (e.getSource() == titlePane)
+        {
+	  Rectangle fBounds = frame.getBounds();
+
+	  dm.dragFrame(frame, e.getX() - xOffset + b.x,
+	               e.getY() - yOffset + b.y);
+        }
+    }
+
+    /**
+     * This method is called when the mouse exits the JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      // There is nothing to do when the mouse exits 
+      // the border area.
+    }
+
+    /**
+     * This method is called when the mouse is moved inside the
+     * JInternalFrame.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      // There is nothing to do when the mouse moves
+      // over the border area.
+    }
+
+    /**
+     * This method is called when the mouse is pressed.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      activateFrame(frame);
+      DesktopManager dm = getDesktopManager();
+      int x = e.getX();
+      int y = e.getY();
+      Insets insets = frame.getInsets();
+
+      if (e.getSource() == frame && frame.isResizable())
+        {
+	  direction = sectionOfClick(x, y);
+	  dm.beginResizingFrame(frame, direction);
+        }
+      else if (e.getSource() == titlePane)
+        {
+	  Rectangle tBounds = titlePane.getBounds();
+
+	  xOffset = e.getX() - tBounds.x + insets.left;
+	  yOffset = e.getY() - tBounds.y + insets.top;
+
+	  dm.beginDraggingFrame(frame);
+        }
+    }
+
+    /**
+     * This method is called when the mouse is released.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      DesktopManager dm = getDesktopManager();
+      xOffset = 0;
+      yOffset = 0;
+      if (e.getSource() == frame && frame.isResizable())
+	dm.endResizingFrame(frame);
+      else if (e.getSource() == titlePane)
+	dm.endDraggingFrame(frame);
+    }
+
+    /**
+     * This method determines the direction of the resize based on the
+     * coordinates and the size of the JInternalFrame.
+     *
+     * @param x The x coordinate of the MouseEvent.
+     * @param y The y coordinate of the MouseEvent.
+     *
+     * @return The direction of the resize (a SwingConstant direction).
+     */
+    private int sectionOfClick(int x, int y)
+    {
+      Insets insets = frame.getInsets();
+      Rectangle b = frame.getBounds();
+      if (x < insets.left && y < insets.top)
+	return NORTH_WEST;
+      else if (x > b.width - insets.right && y < insets.top)
+	return NORTH_EAST;
+      else if (x > b.width - insets.right && y > b.height - insets.bottom)
+	return SOUTH_EAST;
+      else if (x < insets.left && y > b.height - insets.bottom)
+	return SOUTH_WEST;
+      else if (y < insets.top)
+	return NORTH;
+      else if (x < insets.left)
+	return WEST;
+      else if (y > b.height - insets.bottom)
+	return SOUTH;
+      else if (x > b.width - insets.right)
+	return EAST;
+
+      return -1;
+    }
+  }
+
+  /**
+   * This helper class listens to the JDesktopPane that parents this
+   * JInternalFrame and listens for resize events and resizes the
+   * JInternalFrame appropriately.
+   */
+  protected class ComponentHandler implements ComponentListener
+  {
+    /**
+     * This method is called when the JDesktopPane is hidden.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentHidden(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is moved.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentMoved(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is resized.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentResized(ComponentEvent e)
+    {
+      if (frame.isMaximum())
+        {
+	  JDesktopPane pane = (JDesktopPane) e.getSource();
+	  Insets insets = pane.getInsets();
+	  Rectangle bounds = pane.getBounds();
+
+	  frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
+	                  bounds.width - insets.left - insets.right,
+	                  bounds.height - insets.top - insets.bottom);
+	  frame.revalidate();
+	  frame.repaint();
+        }
+
+      // Sun also resizes the icons. but it doesn't seem to do anything.
+    }
+
+    /**
+     * This method is called when the JDesktopPane is shown.
+     *
+     * @param e The ComponentEvent fired.
+     */
+    public void componentShown(ComponentEvent e)
+    {
+      // Do nothing.
+    }
+  }
+
+  /**
+   * This helper class acts as the LayoutManager for JInternalFrames.
+   */
+  public class InternalFrameLayout implements LayoutManager
+  {
+    /**
+     * This method is called when the given Component is added  to the
+     * JInternalFrame.
+     *
+     * @param name The name of the Component.
+     * @param c The Component added.
+     */
+    public void addLayoutComponent(String name, Component c)
+    {
+    }
+
+    /**
+     * This method is used to set the bounds of the children of the
+     * JInternalFrame.
+     *
+     * @param c The Container to lay out.
+     */
+    public void layoutContainer(Container c)
+    {
+      Dimension dims = frame.getSize();
+      Insets insets = frame.getInsets();
+
+      dims.width -= insets.left + insets.right;
+      dims.height -= insets.top + insets.bottom;
+
+      frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
+                                                   dims.height);
+      int nh = 0;
+      int sh = 0;
+      int ew = 0;
+      int ww = 0;
+
+      if (northPane != null)
+        {
+	  Dimension nDims = northPane.getPreferredSize();
+	  nh = Math.min(nDims.height, dims.height);
+
+	  northPane.setBounds(insets.left, insets.top, dims.width, nh);
+        }
+
+      if (southPane != null)
+        {
+	  Dimension sDims = southPane.getPreferredSize();
+	  sh = Math.min(sDims.height, dims.height - nh);
+
+	  southPane.setBounds(insets.left, insets.top + dims.height - sh,
+	                      dims.width, sh);
+        }
+
+      int remHeight = dims.height - sh - nh;
+
+      if (westPane != null)
+        {
+	  Dimension wDims = westPane.getPreferredSize();
+	  ww = Math.min(dims.width, wDims.width);
+
+	  westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
+        }
+
+      if (eastPane != null)
+        {
+	  Dimension eDims = eastPane.getPreferredSize();
+	  ew = Math.min(eDims.width, dims.width - ww);
+
+	  eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
+	                     ew, remHeight);
+        }
+
+      int remWidth = dims.width - ww - ew;
+
+      frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
+                                    remWidth, remHeight);
+    }
+
+    /**
+     * This method returns the minimum layout size.
+     *
+     * @param c The Container to find a minimum layout size for.
+     *
+     * @return The minimum dimensions for the JInternalFrame.
+     */
+    public Dimension minimumLayoutSize(Container c)
+    {
+      return preferredLayoutSize(c);
+    }
+
+    /**
+     * This method returns the maximum layout size.
+     *
+     * @param c The Container to find a maximum layout size for.
+     *
+     * @return The maximum dimensions for the JInternalFrame.
+     */
+    public Dimension maximumLayoutSize(Container c)
+    {
+      return preferredLayoutSize(c);
+    }
+
+    /**
+     * Th8is method returns the preferred layout size.
+     *
+     * @param c The Container to find a preferred layout size for.
+     *
+     * @return The preferred dimensions for the JInternalFrame.
+     */
+    public Dimension preferredLayoutSize(Container c)
+    {
+      Insets insets = frame.getInsets();
+
+      Dimension contentDims = frame.getContentPane().getPreferredSize();
+      int nWidth = 0;
+      int nHeight = 0;
+      int sWidth = 0;
+      int sHeight = 0;
+      int eWidth = 0;
+      int eHeight = 0;
+      int wWidth = 0;
+      int wHeight = 0;
+      Dimension dims;
+
+      if (northPane != null)
+        {
+	  dims = northPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      nWidth = dims.width;
+	      nHeight = dims.height;
+	    }
+        }
+
+      if (southPane != null)
+        {
+	  dims = southPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      sWidth = dims.width;
+	      sHeight = dims.height;
+	    }
+        }
+
+      if (eastPane != null)
+        {
+	  dims = eastPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      sWidth = dims.width;
+	      sHeight = dims.height;
+	    }
+        }
+
+      if (westPane != null)
+        {
+	  dims = westPane.getPreferredSize();
+	  if (dims != null)
+	    {
+	      wWidth = dims.width;
+	      wHeight = dims.height;
+	    }
+        }
+
+      int width = Math.max(sWidth, nWidth);
+      width = Math.max(width, contentDims.width + eWidth + wWidth);
+
+      int height = Math.max(contentDims.height, eHeight);
+      height = Math.max(height, wHeight);
+      height += nHeight + sHeight;
+
+      width += insets.left + insets.right;
+      height += insets.top + insets.bottom;
+
+      return new Dimension(width, height);
+    }
+
+    /**
+     * This method is called when a Component is removed from the
+     * JInternalFrame.
+     *
+     * @param c The Component that was removed.
+     */
+    public void removeLayoutComponent(Component c)
+    {
+    }
+  }
+
+  /**
+   * This helper class is used to listen to the JDesktopPane's glassPane for
+   * MouseEvents. The JInternalFrame can then be selected if a click is
+   * detected on its children.
+   */
+  protected class GlassPaneDispatcher implements MouseInputListener
+  {
+    /**
+     * This method is called when the mouse enters the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseEntered(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse is clicked on the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseClicked(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse is dragged in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseDragged(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse exits the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseExited(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse is moved in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseMoved(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse is  pressed in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mousePressed(MouseEvent e)
+    {
+      activateFrame(frame);
+      dispatchFor(e);
+    }
+
+    /**
+     * This method is called when the mouse is  released in the glass pane.
+     *
+     * @param e The MouseEvent.
+     */
+    public void mouseReleased(MouseEvent e)
+    {
+      dispatchFor(e);
+    }
+
+    /**
+     * This helper method redispatches the MouseEvent to the  proper sub
+     * component.
+     *
+     * @param e The MouseEvent.
+     */
+    private void dispatchFor(MouseEvent e)
+    {
+      Component candidate = SwingUtilities.getDeepestComponentAt(frame.getRootPane()
+                                                                      .getContentPane(),
+                                                                 e.getX(),
+                                                                 e.getY());
+      if (candidate == null || candidate == frame.getRootPane().getGlassPane())
+	return;
+      MouseEvent newevt = SwingUtilities.convertMouseEvent(frame.getRootPane()
+                                                                .getGlassPane(),
+                                                           e, candidate);
+      candidate.dispatchEvent(newevt);
+    }
+  }
+
+  /**
+   * This helper class listens for PropertyChangeEvents from the
+   * JInternalFrame.
+   */
+  public class InternalFramePropertyChangeListener
+    implements PropertyChangeListener
+  {
+    /**
+     * This method is called when one of the JInternalFrame's properties
+     * change.
+     *
+     * @param evt The PropertyChangeEvent.
+     */
+    public void propertyChange(PropertyChangeEvent evt)
+    {
+      if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
+        {
+	  if (frame.isMaximum())
+	    maximizeFrame(frame);
+	  else
+	    minimizeFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
+	closeFrame(frame);
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
+        {
+	  if (frame.isIcon())
+	    iconifyFrame(frame);
+	  else
+	    deiconifyFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
+        {
+	  if (frame.isSelected())
+	    activateFrame(frame);
+	  else
+	    getDesktopManager().deactivateFrame(frame);
+        }
+      else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
+               || evt.getPropertyName().equals(JInternalFrame.GLASS_PANE_PROPERTY))
+        {
+	  Component old = (Component) evt.getOldValue();
+	  old.removeMouseListener(glassPaneDispatcher);
+	  old.removeMouseMotionListener(glassPaneDispatcher);
+
+	  Component newPane = (Component) evt.getNewValue();
+	  newPane.addMouseListener(glassPaneDispatcher);
+	  newPane.addMouseMotionListener(glassPaneDispatcher);
+
+	  frame.revalidate();
+        }
+      /* FIXME: need to add ancestor properties to JComponents.
+      else if (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY))
+      {
+        if (desktopPane != null)
+          desktopPane.removeComponentListener(componentListener);
+        desktopPane = frame.getDesktopPane();
+        if (desktopPane != null)
+          desktopPane.addComponentListener(componentListener);
+      }
+      */
+    }
+  }
+
+  /**
+   * This helper class is the border for the JInternalFrame.
+   */
+  private class InternalFrameBorder extends AbstractBorder
+    implements UIResource
+  {
+    /** The width of the border. */
+    private static final int bSize = 5;
+
+    /** The size of the corners. */
+    private static final int offset = 10;
+
+    /**
+     * This method returns whether the border is opaque.
+     *
+     * @return Whether the border is opaque.
+     */
+    public boolean isBorderOpaque()
+    {
+      return true;
+    }
+
+    /**
+     * This method returns the insets of the border.
+     *
+     * @param c The Component to find border insets for.
+     *
+     * @return The border insets.
+     */
+    public Insets getBorderInsets(Component c)
+    {
+      return new Insets(bSize, bSize, bSize, bSize);
+    }
+
+    /**
+     * This method paints the border.
+     *
+     * @param c The Component that owns the border.
+     * @param g The Graphics object to paint with.
+     * @param x The x coordinate to paint at.
+     * @param y The y coordinate to paint at.
+     * @param width The width of the Component.
+     * @param height The height of the Component.
+     */
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+      g.translate(x, y);
+      Color saved = g.getColor();
+      Rectangle b = frame.getBounds();
+
+      Color d = c.getBackground();
+      g.setColor(d);
+      g.fillRect(0, 0, bSize, b.height);
+      g.fillRect(0, 0, b.width, bSize);
+      g.fillRect(0, b.height - bSize, b.width, bSize);
+      g.fillRect(b.width - bSize, 0, bSize, b.height);
+
+      int x1 = 0;
+      int x2 = bSize;
+      int x3 = b.width - bSize;
+      int x4 = b.width;
+
+      int y1 = 0;
+      int y2 = bSize;
+      int y3 = b.height - bSize;
+      int y4 = b.height;
+
+      g.setColor(Color.GRAY);
+      g.fillRect(0, 0, bSize, y4);
+      g.fillRect(0, 0, x4, bSize);
+      g.fillRect(0, y3, b.width, bSize);
+      g.fillRect(x3, 0, bSize, b.height);
+
+      g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
+      g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
+      g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
+      g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
+
+      g.translate(-x, -y);
+      g.setColor(saved);
+    }
+  }
+
+  /**
+   * The MouseListener that is responsible for dragging and resizing the
+   * JInternalFrame in response to MouseEvents.
+   */
+  protected MouseInputAdapter borderListener;
+
+  /**
+   * The ComponentListener that is responsible for resizing the JInternalFrame
+   * in response to ComponentEvents from the JDesktopPane.
+   */
+  protected ComponentListener componentListener;
+
+  /**
+   * The MouseListener that is responsible for activating the JInternalFrame
+   * when the mouse press activates one of its descendents.
+   */
+  protected MouseInputListener glassPaneDispatcher;
+
+  /**
+   * The PropertyChangeListener that is responsible for listening to
+   * PropertyChangeEvents from the JInternalFrame.
+   */
+  protected PropertyChangeListener propertyChangeListener;
+
+  /** The InternalFrameListener that listens to the JInternalFrame. */
+  private transient BasicInternalFrameListener internalFrameListener;
+
+  /** The JComponent placed at the east region of the JInternalFrame. */
+  protected JComponent eastPane;
+
+  /** The JComponent placed at the north region of the JInternalFrame. */
+  protected JComponent northPane;
+
+  /** The JComponent placed at the south region of the JInternalFrame. */
+  protected JComponent southPane;
+
+  /** The JComponent placed at the west region of the JInternalFrame. */
+  protected JComponent westPane;
+
+  /** The Keystroke bound to open the menu. */
+  protected KeyStroke openMenuKey;
+
+  /** The TitlePane displayed at the top of the JInternalFrame. */
+  protected BasicInternalFrameTitlePane titlePane;
+
+  /** The JInternalFrame this UI is responsible for. */
+  protected JInternalFrame frame;
+
+  /** The LayoutManager used in the JInternalFrame. */
+  protected LayoutManager internalFrameLayout;
+
+  /** The JDesktopPane that is the parent of the JInternalFrame. */
+  private transient JDesktopPane desktopPane;
+
+  /**
+   * Creates a new BasicInternalFrameUI object.
+   *
+   * @param b The JInternalFrame this UI will represent.
+   */
+  public BasicInternalFrameUI(JInternalFrame b)
+  {
+  }
+
+  /**
+   * This method will create a new BasicInternalFrameUI for the given
+   * JComponent.
+   *
+   * @param b The JComponent to create a BasicInternalFrameUI for.
+   *
+   * @return A new BasicInternalFrameUI.
+   */
+  public static ComponentUI createUI(JComponent b)
+  {
+    return new BasicInternalFrameUI((JInternalFrame) b);
+  }
+
+  /**
+   * This method installs a UI for the JInternalFrame.
+   *
+   * @param c The JComponent to install this UI on.
+   */
+  public void installUI(JComponent c)
+  {
+    if (c instanceof JInternalFrame)
+      {
+	frame = (JInternalFrame) c;
+
+	internalFrameLayout = createLayoutManager();
+	frame.setLayout(internalFrameLayout);
+
+	((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
+	frame.getRootPane().getGlassPane().setVisible(true);
+
+	installDefaults();
+	installListeners();
+	installComponents();	
+	installKeyboardActions();
+
+	frame.setOpaque(true);
+	titlePane.setOpaque(true);
+	frame.invalidate();
+      }
+  }
+
+  /**
+   * This method reverses the work done by installUI.
+   *
+   * @param c The JComponent to uninstall this UI for.
+   */
+  public void uninstallUI(JComponent c)
+  {
+    uninstallKeyboardActions();
+    uninstallComponents();    
+    uninstallListeners();
+    uninstallDefaults();
+
+    frame.setLayout(null);
+    ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
+    frame.getRootPane().getGlassPane().setVisible(false);
+
+    frame = null;
+  }
+
+  /**
+   * This method installs the defaults specified by the look and feel.
+   */
+  protected void installDefaults()
+  {
+    // FIXME: Move border to MetalBorders
+    frame.setBorder(new InternalFrameBorder());
+  }
+
+  /**
+   * This method installs the keyboard actions for the JInternalFrame.
+   */
+  protected void installKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method installs the Components for the JInternalFrame.
+   */
+  protected void installComponents()
+  {
+    setNorthPane(createNorthPane(frame));
+    setSouthPane(createSouthPane(frame));
+    setEastPane(createEastPane(frame));
+    setWestPane(createWestPane(frame));
+  }
+
+  /**
+   * This method installs the listeners for the JInternalFrame.
+   */
+  protected void installListeners()
+  {
+    glassPaneDispatcher = createGlassPaneDispatcher();
+    createInternalFrameListener();
+    borderListener = createBorderListener(frame);
+    componentListener = createComponentListener();
+    propertyChangeListener = createPropertyChangeListener();
+
+    frame.addMouseListener(borderListener);
+    frame.addMouseMotionListener(borderListener);
+    frame.addInternalFrameListener(internalFrameListener);
+    frame.addPropertyChangeListener(propertyChangeListener);
+
+    frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
+    frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
+  }
+
+  /**
+   * This method uninstalls the defaults for the JInternalFrame.
+   */
+  protected void uninstallDefaults()
+  {
+    frame.setBorder(null);
+  }
+
+  /**
+   * This method uninstalls the Components for the JInternalFrame.
+   */
+  protected void uninstallComponents()
+  {
+    setNorthPane(null);
+    setSouthPane(null);
+    setEastPane(null);
+    setWestPane(null);
+  }
+
+  /**
+   * This method uninstalls the listeners for the JInternalFrame.
+   */
+  protected void uninstallListeners()
+  {
+    if (desktopPane != null)
+      desktopPane.removeComponentListener(componentListener);
+
+    frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
+    frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
+
+    frame.removePropertyChangeListener(propertyChangeListener);
+    frame.removeInternalFrameListener(internalFrameListener);
+    frame.removeMouseMotionListener(borderListener);
+    frame.removeMouseListener(borderListener);
+
+    propertyChangeListener = null;
+    componentListener = null;
+    borderListener = null;
+    internalFrameListener = null;
+    glassPaneDispatcher = null;
+  }
+
+  /**
+   * This method uninstalls the keyboard actions for the JInternalFrame.
+   */
+  protected void uninstallKeyboardActions()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method creates a new LayoutManager for the JInternalFrame.
+   *
+   * @return A new LayoutManager for the JInternalFrame.
+   */
+  protected LayoutManager createLayoutManager()
+  {
+    return new InternalFrameLayout();
+  }
+
+  /**
+   * This method creates a new PropertyChangeListener for the JInternalFrame.
+   *
+   * @return A new PropertyChangeListener for the JInternalFrame.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new InternalFramePropertyChangeListener();
+  }
+
+  /**
+   * This method returns the preferred size of the given JComponent.
+   *
+   * @param x The JComponent to find a preferred size for.
+   *
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize(JComponent x)
+  {
+    return internalFrameLayout.preferredLayoutSize(x);
+  }
+
+  /**
+   * This method returns the minimum size of the given JComponent.
+   *
+   * @param x The JComponent to find a minimum size for.
+   *
+   * @return The minimum size.
+   */
+  public Dimension getMinimumSize(JComponent x)
+  {
+    return getPreferredSize(x);
+  }
+
+  /**
+   * This method returns the maximum size of the given JComponent.
+   *
+   * @param x The JComponent to find a maximum size for.
+   *
+   * @return The maximum size.
+   */
+  public Dimension getMaximumSize(JComponent x)
+  {
+    return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+  }
+
+  /**
+   * This method replaces the currentPane with the newPane. When replacing it
+   * also removes the MouseHandlers for the old pane and installs  them on
+   * the new pane.
+   *
+   * @param currentPane The old pane to remove.
+   * @param newPane The new pane to install.
+   */
+  protected void replacePane(JComponent currentPane, JComponent newPane)
+  {
+    if (currentPane != null)
+      {
+	deinstallMouseHandlers(currentPane);
+	frame.remove(currentPane);
+      }
+
+    if (newPane != null)
+      {
+	installMouseHandlers(newPane);
+	frame.add(newPane);
+      }
+  }
+
+  /**
+   * This method removes the necessary MouseListeners from the given
+   * JComponent.
+   *
+   * @param c The JComponent to remove MouseListeners from.
+   */
+  protected void deinstallMouseHandlers(JComponent c)
+  {
+    c.removeMouseListener(borderListener);
+    c.removeMouseMotionListener(borderListener);
+  }
+
+  /**
+   * This method installs the necessary MouseListeners from the given
+   * JComponent.
+   *
+   * @param c The JComponent to install MouseListeners on.
+   */
+  protected void installMouseHandlers(JComponent c)
+  {
+    c.addMouseListener(borderListener);
+    c.addMouseMotionListener(borderListener);
+  }
+
+  /**
+   * This method creates the north pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a north pane for.
+   *
+   * @return The north pane.
+   */
+  protected JComponent createNorthPane(JInternalFrame w)
+  {
+    titlePane = new BasicInternalFrameTitlePane(w);
+    return titlePane;
+  }
+
+  /**
+   * This method creates the west pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a west pane for.
+   *
+   * @return The west pane.
+   */
+  protected JComponent createWestPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method creates the south pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create a south pane for.
+   *
+   * @return The south pane.
+   */
+  protected JComponent createSouthPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method creates the east pane used in the JInternalFrame.
+   *
+   * @param w The JInternalFrame to create an east pane for.
+   *
+   * @return The east pane.
+   */
+  protected JComponent createEastPane(JInternalFrame w)
+  {
+    return null;
+  }
+
+  /**
+   * This method returns a new BorderListener for the given JInternalFrame.
+   *
+   * @param w The JIntenalFrame to create a BorderListener for.
+   *
+   * @return A new BorderListener.
+   */
+  protected MouseInputAdapter createBorderListener(JInternalFrame w)
+  {
+    return new BorderListener();
+  }
+
+  /**
+   * This method creates a new InternalFrameListener for the JInternalFrame.
+   */
+  protected void createInternalFrameListener()
+  {
+    internalFrameListener = new BasicInternalFrameListener();
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  protected final boolean isKeyBindingRegistered()
+  {
+    // FIXME: Implement.
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  protected final void setKeyBindingRegistered(boolean b)
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @return DOCUMENT ME!
+   */
+  public final boolean isKeyBindingActive()
+  {
+    // FIXME: Implement.
+    return false;
+  }
+
+  /**
+   * DOCUMENT ME!
+   *
+   * @param b DOCUMENT ME!
+   */
+  protected final void setKeyBindingActive(boolean b)
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void setupMenuOpenKey()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  protected void setupMenuCloseKey()
+  {
+    // FIXME: Implement.
+  }
+
+  /**
+   * This method returns the north pane.
+   *
+   * @return The north pane.
+   */
+  public JComponent getNorthPane()
+  {
+    return northPane;
+  }
+
+  /**
+   * This method sets the north pane to be the given JComponent.
+   *
+   * @param c The new north pane.
+   */
+  public void setNorthPane(JComponent c)
+  {
+    replacePane(northPane, c);
+    northPane = c;
+  }
+
+  /**
+   * This method returns the south pane.
+   *
+   * @return The south pane.
+   */
+  public JComponent getSouthPane()
+  {
+    return southPane;
+  }
+
+  /**
+   * This method sets the south pane to be the given JComponent.
+   *
+   * @param c The new south pane.
+   */
+  public void setSouthPane(JComponent c)
+  {
+    replacePane(southPane, c);
+    southPane = c;
+  }
+
+  /**
+   * This method sets the east pane to be the given JComponent.
+   *
+   * @param c The new east pane.
+   */
+  public void setEastPane(JComponent c)
+  {
+    replacePane(eastPane, c);
+    eastPane = c;
+  }
+
+  /**
+   * This method returns the east pane.
+   *
+   * @return The east pane.
+   */
+  public JComponent getEastPane()
+  {
+    return eastPane;
+  }
+
+  /**
+   * This method sets the west pane to be the given JComponent.
+   *
+   * @param c The new west pane.
+   */
+  public void setWestPane(JComponent c)
+  {
+    replacePane(westPane, c);
+    westPane = c;
+  }
+
+  /**
+   * This method returns the west pane.
+   *
+   * @return The west pane.
+   */
+  public JComponent getWestPane()
+  {
+    return westPane;
+  }
+
+  /**
+   * This method returns the DesktopManager to use with the JInternalFrame.
+   *
+   * @return The DesktopManager to use with the JInternalFrame.
+   */
+  protected DesktopManager getDesktopManager()
+  {
+    DesktopManager value = frame.getDesktopPane().getDesktopManager();
+    if (value == null)
+      value = createDesktopManager();
+    return value;
+  }
+
+  /**
+   * This method returns a default DesktopManager that can be used with this
+   * JInternalFrame.
+   *
+   * @return A default DesktopManager that can be used with this
+   *         JInternalFrame.
+   */
+  protected DesktopManager createDesktopManager()
+  {
+    return new DefaultDesktopManager();
+  }
+
+  /**
+   * This is a convenience method that closes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to close.
+   */
+  protected void closeFrame(JInternalFrame f)
+  {
+    getDesktopManager().closeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that maximizes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to maximize.
+   */
+  protected void maximizeFrame(JInternalFrame f)
+  {
+    getDesktopManager().maximizeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that minimizes the JInternalFrame.
+   *
+   * @param f The JInternalFrame to minimize.
+   */
+  protected void minimizeFrame(JInternalFrame f)
+  {
+    getDesktopManager().minimizeFrame(f);
+  }
+
+  /**
+   * This is a convenience method that iconifies the JInternalFrame.
+   *
+   * @param f The JInternalFrame to iconify.
+   */
+  protected void iconifyFrame(JInternalFrame f)
+  {
+    getDesktopManager().iconifyFrame(f);
+  }
+
+  /**
+   * This is a convenience method that deiconifies the JInternalFrame.
+   *
+   * @param f The JInternalFrame to deiconify.
+   */
+  protected void deiconifyFrame(JInternalFrame f)
+  {
+    getDesktopManager().deiconifyFrame(f);
+  }
+
+  /**
+   * This is a convenience method that activates the JInternalFrame.
+   *
+   * @param f The JInternalFrame to activate.
+   */
+  protected void activateFrame(JInternalFrame f)
+  {
+    getDesktopManager().activateFrame(f);
+  }
+
+  /**
+   * This method returns a new ComponentListener for the JDesktopPane.
+   *
+   * @return A new ComponentListener.
+   */
+  protected ComponentListener createComponentListener()
+  {
+    return new ComponentHandler();
+  }
+
+  /**
+   * This method returns a new GlassPaneDispatcher.
+   *
+   * @return A new GlassPaneDispatcher.
+   */
+  protected MouseInputListener createGlassPaneDispatcher()
+  {
+    return new GlassPaneDispatcher();
+  }
+}
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.4.2.10
diff -u -r1.4.2.10 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java	8 Jun 2004 20:19:18 -0000	1.4.2.10
+++ javax/swing/plaf/basic/BasicLookAndFeel.java	9 Jun 2004 20:47:03 -0000
@@ -347,7 +347,7 @@
         "ctrl F10", "maximize",
         "ctrl alt shift F6","selectPreviousFrame"
       }),
-      "Desktop.background", new ColorUIResource(0, 92, 92),
+      "Desktop.background", new ColorUIResource(175, 163, 236),
       "DesktopIcon.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                           null),
       "EditorPane.background", new ColorUIResource(Color.white),
@@ -420,7 +420,7 @@
       "FocusManagerClassName", "TODO",
       "FormView.resetButtonText", "Reset",
       "FormView.submitButtonText", "Submit Query",
-      "InternalFrame.activeTitleBackground", new ColorUIResource(lightPurple),
+      "InternalFrame.activeTitleBackground", new ColorUIResource(162, 167, 241),
       "InternalFrame.activeTitleForeground", new ColorUIResource(Color.black),
       "InternalFrame.border", new BorderUIResource.CompoundBorderUIResource(null,
                                                                             null),
@@ -428,8 +428,8 @@
       // XXX Don't use gif
       "InternalFrame.icon", new IconUIResource(new ImageIcon("icons/JavaCup.gif")),
       "InternalFrame.iconifyIcon", BasicIconFactory.createEmptyFrameIcon(),
-      "InternalFrame.inactiveTitleBackground", new ColorUIResource(Color.gray),
-      "InternalFrame.inactiveTitleForeground", new ColorUIResource(Color.lightGray),
+      "InternalFrame.inactiveTitleBackground", new ColorUIResource(Color.lightGray),
+      "InternalFrame.inactiveTitleForeground", new ColorUIResource(Color.black),
       "InternalFrame.maximizeIcon", BasicIconFactory.createEmptyFrameIcon(),
       "InternalFrame.minimizeIcon", BasicIconFactory.createEmptyFrameIcon(),
       "InternalFrame.titleFont", new FontUIResource("Dialog", Font.PLAIN, 12),

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]