classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: gcj gui branch merge of Swing text related changes


From: Mark Wielaard
Subject: [cp-patches] FYI: gcj gui branch merge of Swing text related changes
Date: Sat, 04 Sep 2004 19:09:37 +0200

Hi,

This patch adds all the Swing text changes of the last month on the gcj
gui branch by Roman, Graydon and Michael to GNU Classpath CVS. With this
the new JTextField Demo that Michael just added can actually be edited
(including moving caret!).

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/JTextArea.java
        (lineWrap): Renamed from "wrapping".
        (wrapStyleWord): NEw field.
        (getLineWrap): Re-edited javadoc comment.
        (setLineWrap): Likewise.
        (getWrapStyleWord): New method.
        (setWrapStyleWord): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextAreaUI.java
        (create): New method.
        * javax/swing/text/DefaultHighlighter.java
        (DefaultHighlightPainter.debugRect): Removed.
        * javax/swing/text/StyleContext.java
        (DEFAULT_STYLE): New field.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicLookAndFeel.java
        (initComponentDefaults): Add keybindings for selection.backward and
        selection-forward for text components.
        * javax/swing/plaf/basic/BasicTextUI.java
        (paintSafely): Paint highlight only when something is actually
        selected.
        * javax/swing/text/DefaultCaret.java
        (handleHighlight): New method.
        (setSelectionVisible): Don't do anything when nothing changes.
        Handle highlight.
        (moveDot): Reimplemented. Handle highlight.
        (setDot): Set mark too. Handle highlight.
        (getSelectionPainter): New method.
        * javax/swing/text/DefaultEditorKit.java
        (defaultActions): Added new actions for text selection.
        * javax/swing/text/DefaultHighlighter.java
        (DefaultHighlightPainter): New inner class.
        (DefaultPainter): New field.
        (paint): Implemented.
        * javax/swing/text/PlainView.java
        (paint): Don't draw background here again.
        * javax/swing/text/Utilities.java
        (getTabbedTextWidth): Use width of ' ' instead of 'm' for tabsize.
        (drawTabbedText): Likewise.

2004-09-04  Graydon Hoare  <address@hidden>

        * java/awt/Component.java
        (isFocusTraversable): Predicate on isLightweight()
        (setFocusable): Set isFocusTraversableOverridden.
        (requestFocus): Predicate peer dispatch on !isLightweight()
        (requestFocusInWindow): Likewise.
        (dispatchEventImpl): Coordinate with KeyboardFocusManager.
        * java/awt/Container.java
        (dispatchEventImpl): Predicate on event mask.
        (LightweightDispatcher): Remove focus machinery.
        * java/awt/DefaultFocusTraversalPolicy.java
        (accept): Expand predicate to include isFocusable().
        * java/awt/DefaultKeyboardFocusManager.java:
        Globally change c.dispatchEvent(e) to redispatchEvent(c,e)
        * java/awt/KeyboardFocusManager.java
        (redispatchEvent): Synchronize on event to prevent feedback.
        * javax/swing/AbstractButton.java
        (ButtonFocusListener): Remove class.
        (init): Set focusPainted, focusable.
        * javax/swing/ActionMap.java (get): Check parent for null.
        * javax/swing/InputMap.java (get): Likewise.
        * javax/swing/JComponent.java
        (inputMap_whenFocused): New InputMap.
        (inputMap_whenAncestorOfFocused): Likewise.
        (inputMap_whenInFocusedWindow): Likewise.
        (getActionForKeyStroke): Rewrite.
        (getConditionForKeystroke): Likewise.
        (ActionListenerProxy): New private class.
        (setInputMap): Implement.
        (getInputMap): Likewise.
        (setActionMap): Likewise.
        (getActionMap): Likewise.
        (processComponentKeyEvent): New empty method.
        (processKeyEvent): Implement.
        (processKeyBinding): Likewise.
        (resetKeyboardActions): Rewrite.
        * javax/swing/KeyStroke.java: Rewrite.
        * javax/swing/SwingUtilities.java
        (notifyAction): Implement.
        (replaceUIActionMap): Likewise.
        (replaceUIInputMap): Likewise.
        * javax/swing/plaf/basic/BasicButtonListener.java
        (focusGained): Implement.
        (focusLost): Repaint if focusPainted().
        (installKeyboardActions): Install pressed / released actions.
        (uninstallKeyboardActions): Implement.
        * javax/swing/plaf/basic/BasicButtonUI.java
        (focusColor): New field.
        (installDefaults): Load focus color, install input map.
        (installKeyboardActions): Implement.
        (uninstallKeyboardActions): Likewise.
        (paintFocus): Rewrite.
        * javax/swing/plaf/basic/BasicLookAndFeel.java
        (Button.focus): New default, midPurple.
        * javax/swing/plaf/basic/BasicTextUI.java
        (kit): Make static.
        (installUI): Get doc from kit, load defaults.
        (getKeymapName): Implement.
        (createKeymap): Likewise.
        (installKeyboardActions): Likewise.
        (getInputMap): Likewise.
        (getActionMap): Likewise.
        (createActionMap): Likewise.
        * javax/swing/text/AbstractDocument.java
        (getStartPosition): Implement.
        (getEndPosition): Likewise.
        * javax/swing/text/DefaultEditorKit.java
        (CopyAction): New class.
        (CutAction): Likewise.
        (DefaultKeyTypedAction): Likewise.
        (InsertBreakAction): Likewise.
        (InsertContentAction): Likewise.
        (InsertTabAction): Likewise.
        (PasteAction): Likewise.
        (defaultActions): New static table.
        (createCaret): Implement.
        (getActions): Likewise.
        * javax/swing/text/JTextComponent.java
        (KeymapWrapper): New private class.
        (KeymapActionMap): Likewise.
        (DefaultKeymap): New class.
        (keymaps): New static table.
        (keymap): New field.
        (getKeymap): Implement.
        (removeKeymap): Likewise.
        (addKeymap): Likewise.
        (setKeymap): Likewise.
        (loadKeymap): Likewise.
        (getActions): Likewise.
        (margin): New field.
        (JTextComponent): Build and install default keymap.
        * javax/swing/text/TextAction.java
        (textAction): Call super properly.
        (getTextComponent): Implement.
        * javax/swing/text/Utilities.java
        (drawTabbedText): Adjust position by ascent.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextUI.java
        (RottView.modelToView): New method.
        (UpdateHandler): Renamed from EventHandler.
        (updateHandler): Renamed from eventHandler.
        (modelToView): Implemented.
        * javax/swing/text/AbstractDocument.java
        (BranchElement.getElement): Return null for non-existing indeces.
        (BranchElement.getElementIndex): Return 0 in some corner cases.
        * javax/swing/text/FieldView.java
        (modelToView): New method.
        * javax/swing/text/PlainView.java
        (modelToView): Made public.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/AbstractDocument.java
        (createBranchElement): Use new constructor of BranchElement.
        (createLeafElement): Renamed arguments.
        (getRootElements): Implemented.
        (BranchElement.start): Removed.
        (BranchElement.end): Likewise.
        (BranchElement.BranchElement): Fixed arguments.
        (BranchElement.getEndOffset): Reimplemented.
        (BranchElement.getStartOffset): Likewis.
        * javax/swing/text/DefaultCaret.java
        (paint): Draw simple vertical line as caret instead of a rectangle.
        * javax/swing/text/JTextComponent.java
        (setText): Use doc directly.
        * javax/swing/text/PlainView.java
        (nextTabStop): Implemented.
        * javax/swing/text/Utilities.java
        (drawTabbedText): nextTabStop() returns an absolute x position.
        (getTabbedTextWidth): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/PlainView.java
        (selectedColor): New field.
        (unselectedColor): Likewise.
        (font): Likewise.
        (updateMetrics): New method.
        (lineToRect): Likewise.
        (modelToView): Likewise.
        (drawSelectedText): Use color from JTextComponent ad draw with
        Utilities class.
        (drawUnselectedText): Likewise.
        (paint): Initialize helper fields.
        * javax/swing/text/View.java
        (getChildAllocation): New method.
        (getViewIndex): Likewise.
        (getToolTipText): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/Utilities.java
        (drawTabbedText): Reimplemented.
        (getTabbedTextWidth): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextUI.java
        (installDefaults): Install caret and highlighter.
        (modelToView): Use Bias.Forward when calling sibling.
        * javax/swing/text/AbstractDocument.java
        (ElementEdit): Implements DocumentEvent.ElementChange.
        (ElementEdit.ElementEdit): New method.
        (ElementEdit.getChildrenAdded): Likewise.
        (ElementEdit.getChildrenRemoved): Likewise.
        (ElementEdit.getElement): Likewise.
        (ElementEdit.getIndex): Likewise.
        * javax/swing/text/DefaultCaret.java
        (color): Removed.
        (textComponent): Renamed from parent, made private.
        (selectionVisible): Renamed from vis_sel, made private.
        (blinkRate): Renamed from blink, made private.
        (magicCaretPosition): Renamed from magic, made private.
        (visible): Renamed from vis, made private.
        (dot): Made private.
        (mark): Likewise.
        (deinstall): Remove as MouseMotionListener.
        (install): Initialize textComponent first. Add as
        MouseMotionListener.
        (paint): Reimplemented.
        * javax/swing/text/JTextComponent.java
        (setCaret): Deinstall old caret, install new one and fire property
        change after setting property.
        (setHighlighter): Deinstall old highlighter, install new one and fire
        property change after setting property.
        (setCaretColor): Fire property change after setting property.
        (setDisabledTextColor): Likewise.
        (setSelectedTextColor): Likewise.
        (setSelectionColor): Likewise.
        (modelToView): New method.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/AbstractDocument.java
        (getText): Simplified.
        * javax/swing/text/Segment.java
        (current): New field.
        (current): Reimplemented.
        (first): Likewise.
        (getIndex): Likewise.
        (last): Likewise.
        (next): Likewise.
        (previous): Likewise.
        (setIndex): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicButtonUI.java
        (defaultTextIconGap): Made protected.
        (defaultTextShiftOffset): Likewise.
        (textShiftOffset): New field.
        (clearTextShiftOffset): New method.
        (getTextShiftOffset): Likewise.
        (setTextShiftOffset): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextUI.java
        (installUI): Add eventHandler as property listener.
        (uninstallUI): remove eventHandler as propert listener.
        (installDefaults): Added comment.
        (installListeners): Likewise.
        (installKeyboardActions): Likewise.
        (uninstallDefaults): Likewise.
        (uninstallListeners): Likewise.
        (uninstallKeyboardActions): Likewise.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/AbstractDocument.java:
        Fixed some typos in comments.
        (insertString): Reimplemented.
        (remove): Likewise.
        (replace): New method.
        (children): Dont use fully qualified class name.
        (DefaultDocumentEvent.offset): Renamed from off.
        (DefaultDocumentEvent.length): Renamed from len.
        (DefaultDocumentEvent.type): New field.
        (DefaultDocumentEvent.DefaultDocumentEvent): New constructor.
        (DefaultDocumentEvent.getType): Implemented.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextUI.java
        (RootView.textComponent): Removed.
        (RootView.RootView): Don't initialize textComponent.
        (RootView.getViewFactory): New method.
        (EventHandler): New inner class.
        (rootView): Initialize at instance creation.
        (eventHandler): New field.
        (installUI): Don't create view hierarchy directly,
        call modelChanged() instead.
        (modelChanged): New method.
        * javax/swing/text/JTextComponent.java
        (setDocument): Fire property change event.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicTextUI.java
        (RootView.paint): Removed debug output.
        (paintSafely): Draw highlighter before text.
        (paintBackground): Use background color of text component.
        * javax/swing/plaf/basic/BasicToggleButtonUI.java:
        Reformatted.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicToolBarUI.java
        (BasicToolBarUI): Fixed arguments for constructor.
        (createUI): Fixed creation of object.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/text/TabSet.java
        (TabSet): Implements java.io.Serializable.
        * javax/swing/text/TabStop.java
        (TabStop): Implements java.io.Serializable.
        (TabStop): Made public.

2004-09-04  Graydon Hoare  <address@hidden>

        * javax/swing/text/SimpleAttributeSet.java: New file.
        * javax/swing/text/StyleConstants.java: New file.
        * javax/swing/text/StyleContext.java: New file.
        * javax/swing/text/TabSet.java: New file.
        * javax/swing/text/TabStop.java: New file.
        * javax/swing/text/AbstactDocument.java:
        (AbstractElement): Implement attribute support.
        * javax/swing/text/AttributeSet.java
        (NameAttribute): New static field.
        (ResolveAttribute): New static field.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/JComponent.java
        (setUI): Fire PropertyChange.
        * javax/swing/JLabel.java
        (text): Renamed from labelText.
        (horizontalAlignment): New default vlaue.
        (icon): Renamed from activeIcon.
        (displayedMnemonic): Renamed from mnemonicKey, added default value.
        (displayedMnemonicIndex): Renamed from underlineChar.
        (setDisplayedMnemonic): Reimplemented.
        * javax/swing/JRadioButton.java
        (JRadioButton): New constructors.
        * javax/swing/JTextField.java
        (JTextField): Throw exception if colums < 0, initialitialz
        this.columns directly and initialize document with text
        conditionally.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/plaf/basic/BasicFormattedTextFieldUI.java,
        javax/swing/plaf/basic/BasicPasswordFieldUI.java,
        javax/swing/plaf/basic/BasicTextAreaUI.java: New files.
        * javax/swing/text/FieldView.java
        (paint): Just call super method for now.

2004-09-04  Michael Koch  <address@hidden>

        * javax/swing/TransferHandler.java,
        javax/swing/plaf/basic/ComboPopup.java: New files

2004-09-04  Roman Kennke  <address@hidden>

        * javax/swing/text/Utilities.java: New file.

In the future I will try to merge patches sooner and in smaller chunks.

Cheers,

Mark
Index: java/awt/Component.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Component.java,v
retrieving revision 1.39
diff -u -r1.39 Component.java
--- java/awt/Component.java     8 Aug 2004 13:01:35 -0000       1.39
+++ java/awt/Component.java     4 Sep 2004 17:00:11 -0000
@@ -58,6 +58,7 @@
 import java.awt.event.MouseWheelListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.PaintEvent;
+import java.awt.event.WindowEvent;
 import java.awt.im.InputContext;
 import java.awt.im.InputMethodRequests;
 import java.awt.image.BufferStrategy;
@@ -3432,7 +3433,7 @@
    */
   public boolean isFocusTraversable()
   {
-    return enabled && visible && (peer == null || peer.isFocusTraversable());
+    return enabled && visible && (peer == null || isLightweight() || 
peer.isFocusTraversable());
   }
 
   /**
@@ -3447,7 +3448,11 @@
   }
 
   /**
-   * Specify whether this component can receive focus.
+   * Specify whether this component can receive focus. This method also
+   * sets the address@hidden #isFocusTraversableOverridden} field to 1, which
+   * appears to be the undocumented way address@hidden
+   * DefaultFocusTraversalPolicy#accept()} determines whether to respect
+   * the address@hidden #isFocusable()} method of the component.
    *
    * @param focusable the new focusable status
    * @since 1.4
@@ -3456,6 +3461,7 @@
   {
     firePropertyChange("focusable", this.focusable, focusable);
     this.focusable = focusable;
+    this.isFocusTraversableOverridden = 1;
   }
 
   /**
@@ -3714,7 +3720,7 @@
             Window toplevel = (Window) parent;
             if (toplevel.isFocusableWindow ())
               {
-                if (peer != null)
+                if (peer != null && !isLightweight())
                   // This call will cause a FOCUS_GAINED event to be
                   // posted to the system event queue if the native
                   // windowing system grants the focus request.
@@ -3800,7 +3806,7 @@
             Window toplevel = (Window) parent;
             if (toplevel.isFocusableWindow ())
               {
-                if (peer != null)
+                if (peer != null && !isLightweight())
                   // This call will cause a FOCUS_GAINED event to be
                   // posted to the system event queue if the native
                   // windowing system grants the focus request.
@@ -3921,6 +3927,7 @@
                 if (focusedWindow == toplevel)
                   {
                     if (peer != null
+                        && !isLightweight()
                         && !(this instanceof Window))
                       // This call will cause a FOCUS_GAINED event to be
                       // posted to the system event queue if the native
@@ -4690,6 +4697,7 @@
    *
    * @param e the event to dispatch
    */
+
   void dispatchEventImpl (AWTEvent e)
   {
     Event oldEvent = translateEvent (e);
@@ -4698,8 +4706,31 @@
       postEvent (oldEvent);
 
     if (eventTypeEnabled (e.id))
+      {
+        // the trick we use to communicate between dispatch and redispatch
+        // is to have KeyboardFocusManager.redispatch synchronize on the
+        // object itself. we then do not redispatch to KeyboardFocusManager
+        // if we are already holding the lock.
+        if (! Thread.holdsLock(e))
+          {
+            switch (e.id)
+              {
+              case WindowEvent.WINDOW_GAINED_FOCUS:
+              case WindowEvent.WINDOW_LOST_FOCUS:
+              case KeyEvent.KEY_PRESSED:
+              case KeyEvent.KEY_RELEASED:
+              case KeyEvent.KEY_TYPED:
+              case FocusEvent.FOCUS_GAINED:
+              case FocusEvent.FOCUS_LOST:
+                if (KeyboardFocusManager
+                    .getCurrentKeyboardFocusManager()
+                    .dispatchEvent(e))
+                    return;
+              }
+          }
       processEvent (e);
   }
+  }
 
   /**
    * Tells whether or not an event type is enabled.
Index: java/awt/Container.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/Container.java,v
retrieving revision 1.38
diff -u -r1.38 Container.java
--- java/awt/Container.java     8 Aug 2004 13:01:35 -0000       1.38
+++ java/awt/Container.java     4 Sep 2004 17:00:12 -0000
@@ -1505,7 +1505,8 @@
   void dispatchEventImpl(AWTEvent e)
   {
     // Give lightweight dispatcher a chance to handle it.
-    if (dispatcher != null 
+    if (eventTypeEnabled (e.id)
+        && dispatcher != null 
         && dispatcher.handleEvent (e))
       return;
 
@@ -1586,7 +1587,6 @@
                   {
                     if (dispatcher == null)
                       dispatcher = new LightweightDispatcher (this);
-                    dispatcher.enableEvents (component[i].eventMask);
                   }    
          
 
@@ -1831,7 +1831,6 @@
 {
   private static final long serialVersionUID = 5184291520170872969L;
   private Container nativeContainer;
-  private Component focus;
   private Cursor nativeCursor;
   private long eventMask;
   
@@ -1845,11 +1844,6 @@
     nativeContainer = c;
   }
 
-  void enableEvents(long l)
-  {
-    eventMask |= l;
-  }
-
   void acquireComponentForMouseEvent(MouseEvent me)
   {
     int x = me.getX ();
@@ -1949,9 +1943,6 @@
 
   boolean handleEvent(AWTEvent e)
   {
-    if ((eventMask & e.getID()) == 0)
-      return false;
-
     if (e instanceof MouseEvent)
       {
         MouseEvent me = (MouseEvent) e;
@@ -1989,10 +1980,6 @@
                 e.consume();
           }
       }
-    else if (e instanceof KeyEvent && focus != null)
-      {
-        focus.processKeyEvent((KeyEvent) e);
-      }
     
     return e.isConsumed();
   }
Index: java/awt/DefaultFocusTraversalPolicy.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/awt/DefaultFocusTraversalPolicy.java,v
retrieving revision 1.2
diff -u -r1.2 DefaultFocusTraversalPolicy.java
--- java/awt/DefaultFocusTraversalPolicy.java   31 May 2004 21:11:46 -0000      
1.2
+++ java/awt/DefaultFocusTraversalPolicy.java   4 Sep 2004 17:00:12 -0000
@@ -92,10 +92,9 @@
        && comp.enabled)
       {
        if (comp.isFocusTraversableOverridden != 0
-           && comp.isFocusTraversable ())
+           && (comp.isFocusTraversable () || comp.isFocusable()))
          return true;
-       else
-         {
+        
            if (!(comp instanceof Canvas
                  || comp instanceof Panel
                  || comp instanceof Label
@@ -105,7 +104,6 @@
                  || comp.isLightweight ()))
              return true;
          }
-      }
     return false;
   }
 }
Index: java/awt/DefaultKeyboardFocusManager.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/awt/DefaultKeyboardFocusManager.java,v
retrieving revision 1.6
diff -u -r1.6 DefaultKeyboardFocusManager.java
--- java/awt/DefaultKeyboardFocusManager.java   31 Jul 2004 17:15:13 -0000      
1.6
+++ java/awt/DefaultKeyboardFocusManager.java   4 Sep 2004 17:00:12 -0000
@@ -155,7 +155,7 @@
                  && e.id != WindowEvent.WINDOW_DEACTIVATED)
           return false;
 
-        target.dispatchEvent (e);
+        redispatchEvent(target, e);
         return true;
       }
     else if (e instanceof FocusEvent)
@@ -197,7 +197,7 @@
               setGlobalPermanentFocusOwner (null);
           }
 
-        target.dispatchEvent (e);
+        redispatchEvent(target, e);
 
         return true;
       }
@@ -258,7 +258,7 @@
     Component focusOwner = getGlobalPermanentFocusOwner ();
 
     if (focusOwner != null)
-      focusOwner.dispatchEvent (e);
+      redispatchEvent(focusOwner, e);
 
     // Loop through all registered KeyEventPostProcessors, giving
     // each a chance to process this event.
@@ -443,6 +443,7 @@
     FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
 
     Component previous = policy.getComponentBefore (focusCycleRoot, focusComp);
+    if (previous != null)
     previous.requestFocusInWindow ();
   }
 
@@ -453,6 +454,7 @@
     FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy ();
 
     Component next = policy.getComponentAfter (focusCycleRoot, focusComp);
+    if (next != null)
     next.requestFocusInWindow ();
   }
 
@@ -465,6 +467,7 @@
       {
         FocusTraversalPolicy policy = focusCycleRoot.getFocusTraversalPolicy 
();
         Component defaultComponent = policy.getDefaultComponent 
(focusCycleRoot);
+        if (defaultComponent != null)
         defaultComponent.requestFocusInWindow ();
       }
     else
@@ -485,6 +488,7 @@
       {
         FocusTraversalPolicy policy = cont.getFocusTraversalPolicy ();
         Component defaultComponent = policy.getDefaultComponent (cont);
+        if (defaultComponent != null)
         defaultComponent.requestFocusInWindow ();
         setGlobalCurrentFocusCycleRoot (cont);
       }
Index: java/awt/KeyboardFocusManager.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/awt/KeyboardFocusManager.java,v
retrieving revision 1.6
diff -u -r1.6 KeyboardFocusManager.java
--- java/awt/KeyboardFocusManager.java  24 Aug 2004 18:38:01 -0000      1.6
+++ java/awt/KeyboardFocusManager.java  4 Sep 2004 17:00:12 -0000
@@ -1098,8 +1098,11 @@
    */
   public final void redispatchEvent (Component target, AWTEvent e)
   {
+    synchronized (e)
+      {
     e.setSource (target);
-    dispatchEvent (e);
+        target.dispatchEvent (e);
+      }
   }
 
   /**
Index: javax/swing/AbstractButton.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/AbstractButton.java,v
retrieving revision 1.18
diff -u -r1.18 AbstractButton.java
--- javax/swing/AbstractButton.java     9 Aug 2004 22:29:15 -0000       1.18
+++ javax/swing/AbstractButton.java     4 Sep 2004 17:00:12 -0000
@@ -444,34 +444,6 @@
     }
 
   /**
-   * Helper class used to subscribe to FocusEvents received by the button.
-   */
-  private class ButtonFocusListener implements FocusListener
-    {
-    /**
-     * Possibly repaint the model in response to loss of focus.
-     *
-     * @param event The loss-of-focus event
-     */
-    public void focusLost(FocusEvent event)
-        {
-      if (AbstractButton.this.isFocusPainted())
-        AbstractButton.this.repaint();
-    }
-
-    /**
-     * Possibly repaint the button in response to acquisition of focus.
-     *
-     * @param event The gained-focus event
-     */
-    public void focusGained(FocusEvent event)
-    {
-      if (AbstractButton.this.isFocusPainted())
-        AbstractButton.this.repaint();
-    }
-  }
-
-  /**
    * Creates a new AbstractButton object.
    */
   public AbstractButton()
@@ -552,12 +524,12 @@
     borderPainted = true;
     contentAreaFilled = true;
 
-    iconTextGap = 4;
+    focusPainted = true;
+    setFocusable(true);
 
     setAlignmentX(LEFT_ALIGNMENT);
     setAlignmentY(CENTER_ALIGNMENT);
 
-    addFocusListener(new ButtonFocusListener());
     setDisplayedMnemonicIndex(-1);    
  }
  
Index: javax/swing/ActionMap.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/ActionMap.java,v
retrieving revision 1.6
diff -u -r1.6 ActionMap.java
--- javax/swing/ActionMap.java  30 Jul 2004 20:21:19 -0000      1.6
+++ javax/swing/ActionMap.java  4 Sep 2004 17:00:13 -0000
@@ -86,7 +86,7 @@
   {
     Object result = actionMap.get(key);
 
-    if (result == null)
+    if (result == null && parent != null)
       result = parent.get(key);
 
     return (Action) result;
Index: javax/swing/InputMap.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/InputMap.java,v
retrieving revision 1.7
diff -u -r1.7 InputMap.java
--- javax/swing/InputMap.java   30 Jul 2004 20:21:19 -0000      1.7
+++ javax/swing/InputMap.java   4 Sep 2004 17:00:13 -0000
@@ -89,7 +89,7 @@
   {
     Object result = inputMap.get(keystroke);
 
-    if (result == null)
+    if (result == null && parent != null)
       result = parent.get(keystroke);
     return result;
   }
Index: javax/swing/JComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JComponent.java,v
retrieving revision 1.20
diff -u -r1.20 JComponent.java
--- javax/swing/JComponent.java 31 Jul 2004 15:24:02 -0000      1.20
+++ javax/swing/JComponent.java 4 Sep 2004 17:00:13 -0000
@@ -37,6 +37,7 @@
 
 package javax.swing;
 
+import java.awt.AWTEvent;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
@@ -48,11 +49,13 @@
 import java.awt.Insets;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ContainerEvent;
 import java.awt.event.ContainerListener;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
+import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.ImageObserver;
@@ -316,6 +319,11 @@
    */
   private Hashtable clientProperties;
 
+  private InputMap inputMap_whenFocused;
+  private InputMap inputMap_whenAncestorOfFocused;
+  private InputMap inputMap_whenInFocusedWindow;
+  private ActionMap actionMap;
+
   /** 
    * A lock held during recursive painting; this is used to serialize
    * access to the double buffer, and also to select the "top level" 
@@ -747,18 +755,6 @@
     return null;
   }
 
-  /**
-   * Get the ActionListener (typically an address@hidden Action} object) which 
is
-   * associated with a particular keystroke. 
-   *
-   * @param aKeyStroke The keystroke to retrieve the action of
-   *
-   * @return The action associated with the specified keystroke
-   */
-  public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke)
-  {
-    return null;
-  }
 
   /**
    * Get the value of the address@hidden #alignmentX} property.
@@ -865,24 +861,6 @@
     return g;
   }
 
-  /**
-   * Return the condition that determines whether a registered action
-   * occurs in response to the specified keystroke.
-   *
-   * @param aKeyStroke The keystroke to return the condition of
-   *
-   * @return One of the values address@hidden #UNDEFINED_CONDITION}, 
address@hidden
-   * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, address@hidden #WHEN_FOCUSED}, or 
address@hidden
-   * #WHEN_IN_FOCUSED_WINDOW}
-   *
-   * @see #registerKeyboardAction   
-   * @see #unregisterKeyboardAction   
-   * @see #resetKeyboardActiond
-   */
-  public int getConditionForKeyStroke(KeyStroke aKeyStroke)
-  {
-    return UNDEFINED_CONDITION;
-  }
 
   /**
    * Get the value of the address@hidden #debugGraphicsOptions} property.
@@ -1522,6 +1500,51 @@
     registerKeyboardAction(act, null, stroke, cond);
   }
 
+  /* 
+   * There is some charmingly undocumented behavior sun seems to be using
+   * to simulate the old register/unregister keyboard binding API. It's not
+   * clear to me why this matters, but we shall endeavour to follow suit.
+   *
+   * Two main thing seem to be happening when you do registerKeyboardAction():
+   * 
+   *  - no actionMap() entry gets created, just an entry in inputMap()
+   *
+   *  - the inputMap() entry is a proxy class which invokes the the
+   *  binding's actionListener as a target, and which clobbers the command
+   *  name sent in the ActionEvent, providing the binding command name
+   *  instead.
+   *
+   * This much you can work out just by asking the input and action maps
+   * what they contain after making bindings, and watching the event which
+   * gets delivered to the recipient. Beyond that, it seems to be a
+   * sun-private solution so I will only immitate it as much as it matters
+   * to external observers.
+   */
+
+  private static class ActionListenerProxy
+    extends AbstractAction
+  {
+    ActionListener target;
+    String bindingCommandName;
+
+    public ActionListenerProxy(ActionListener li, 
+                               String cmd)
+    {
+      target = li;
+      bindingCommandName = cmd;
+    }
+
+    public void actionPerformed(ActionEvent e)
+    {
+      ActionEvent derivedEvent = new ActionEvent(e.getSource(),
+                                                 e.getID(),
+                                                 bindingCommandName,
+                                                 e.getModifiers());
+      target.actionPerformed(derivedEvent);
+    }
+  }
+
+  
   /**
    * An obsolete method to register a keyboard action on this component.
    * You should use <code>getInputMap</code> and <code>getActionMap</code>
@@ -1546,6 +1569,183 @@
                                      KeyStroke stroke, 
                                      int cond)
   {
+    getInputMap(cond).put(stroke, new ActionListenerProxy(act, cmd));
+  }
+
+
+
+  public final void setInputMap(int condition, InputMap map)
+  {
+    enableEvents(AWTEvent.KEY_EVENT_MASK);
+    switch (condition)
+      {
+      case WHEN_FOCUSED:
+        inputMap_whenFocused = map;
+        break;
+
+      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        inputMap_whenAncestorOfFocused = map;
+        break;
+
+      case WHEN_IN_FOCUSED_WINDOW:
+        inputMap_whenInFocusedWindow = map;
+        break;
+        
+      case UNDEFINED_CONDITION:
+      default:
+        throw new IllegalArgumentException();
+      }
+  }
+
+  public final InputMap getInputMap(int condition)
+  {
+    enableEvents(AWTEvent.KEY_EVENT_MASK);
+    switch (condition)
+      {
+      case WHEN_FOCUSED:
+        if (inputMap_whenFocused == null)
+          inputMap_whenFocused = new InputMap();
+        return inputMap_whenFocused;
+
+      case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        if (inputMap_whenAncestorOfFocused == null)
+          inputMap_whenAncestorOfFocused = new InputMap();
+        return inputMap_whenAncestorOfFocused;
+
+      case WHEN_IN_FOCUSED_WINDOW:
+        if (inputMap_whenInFocusedWindow == null)
+          inputMap_whenInFocusedWindow = new InputMap();
+        return inputMap_whenInFocusedWindow;
+
+      case UNDEFINED_CONDITION:
+      default:
+        return null;
+      }
+  }
+
+  public final InputMap getInputMap()
+  {
+    return getInputMap(WHEN_FOCUSED);
+  }
+
+  public final ActionMap getActionMap()
+  {
+    if (actionMap == null)
+      actionMap = new ActionMap();
+    return actionMap;
+  }
+
+  public final void setActionMap(ActionMap map)
+  {
+    actionMap = map;
+  }
+
+  /**
+   * @deprecated As of 1.3 KeyStrokes can be registered with multiple
+   * simultaneous conditions.
+   *
+   * Return the condition that determines whether a registered action
+   * occurs in response to the specified keystroke.
+   *
+   * @param aKeyStroke The keystroke to return the condition of
+   *
+   * @return One of the values address@hidden #UNDEFINED_CONDITION}, 
address@hidden
+   * #WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}, address@hidden #WHEN_FOCUSED}, or 
address@hidden
+   * #WHEN_IN_FOCUSED_WINDOW}
+   *
+   * @see #registerKeyboardAction   
+   * @see #unregisterKeyboardAction   
+   * @see #resetKeyboardActiond
+   */
+  public int getConditionForKeyStroke(KeyStroke ks)
+  {
+    if (inputMap_whenFocused != null 
+        && inputMap_whenFocused.get(ks) != null)
+      return WHEN_FOCUSED;
+    else if (inputMap_whenAncestorOfFocused != null 
+             && inputMap_whenAncestorOfFocused.get(ks) != null)
+      return WHEN_ANCESTOR_OF_FOCUSED_COMPONENT;
+    else if (inputMap_whenInFocusedWindow != null 
+             && inputMap_whenInFocusedWindow.get(ks) != null)
+      return WHEN_IN_FOCUSED_WINDOW;
+    else
+      return UNDEFINED_CONDITION;
+  }
+
+  /**
+   * @deprecated Use address@hidden #getActionMap()}
+   *
+   * Get the ActionListener (typically an address@hidden Action} object) which 
is
+   * associated with a particular keystroke. 
+   *
+   * @param aKeyStroke The keystroke to retrieve the action of
+   *
+   * @return The action associated with the specified keystroke
+   */
+  public ActionListener getActionForKeyStroke(KeyStroke ks)
+  {
+    Object cmd = getInputMap().get(ks);
+    if (cmd != null)
+      {
+        if (cmd instanceof ActionListenerProxy)
+          return (ActionListenerProxy) cmd;
+        else if (cmd instanceof String)
+          return getActionMap().get(cmd);
+      }
+    return null;
+  }
+
+  /**
+   * A hook for subclasses which want to customize event processing.
+   */
+  protected void processComponentKeyEvent(KeyEvent e)
+  {
+  }
+
+  /**
+   * Override the default key dispatch system from Component to hook into
+   * the swing address@hidden InputMap} / address@hidden ActionMap} system.
+   *
+   * See <a
+   * 
href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html";>this
+   * report</a> for more details, it's somewhat complex.
+   */
+  protected void processKeyEvent(KeyEvent e)
+  {
+    processComponentKeyEvent(e);
+
+    // FIXME: this needs to be elaborated significantly, to do all the
+    // focus / ancestor / window searching for the various binding modes.
+    if (! e.isConsumed() &&
+        processKeyBinding(KeyStroke.getKeyStrokeForEvent(e), 
+                          e, WHEN_FOCUSED, e.getID() == KeyEvent.KEY_PRESSED))
+      e.consume();
+  }
+
+  protected boolean processKeyBinding(KeyStroke ks,
+                                      KeyEvent e,
+                                      int condition,
+                                      boolean pressed)
+  { 
+    if (isEnabled())
+      {
+        Action act = null;
+        InputMap map = getInputMap(condition);
+        if (map != null)
+          {
+            Object cmd = map.get(ks);
+            if (cmd != null)
+              {
+                if (cmd instanceof ActionListenerProxy)
+                  act = (Action) cmd;
+                else 
+                  act = (Action) getActionMap().get(cmd);
+              }
+          }
+        if (act != null && act.isEnabled())
+          return SwingUtilities.notifyAction(act, ks, e, this, 
e.getModifiers());
+      }
+    return false;
   }
 
   /**
@@ -1571,6 +1771,10 @@
    */
   public void resetKeyboardActions()
   {
+    inputMap_whenFocused.clear();
+    inputMap_whenAncestorOfFocused.clear();
+    inputMap_whenInFocusedWindow.clear();
+    actionMap.clear();
   }
 
 
@@ -1878,11 +2082,14 @@
     if (ui != null)
       ui.uninstallUI(this);
 
+    ComponentUI oldUI = ui;
     ui = newUI;
 
     if (ui != null)
       ui.installUI(this);
 
+    firePropertyChange("UI", oldUI, newUI);
+    
     revalidate();
     repaint();
   }
Index: javax/swing/JLabel.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JLabel.java,v
retrieving revision 1.12
diff -u -r1.12 JLabel.java
--- javax/swing/JLabel.java     26 Jun 2004 16:07:00 -0000      1.12
+++ javax/swing/JLabel.java     4 Sep 2004 17:00:13 -0000
@@ -40,6 +40,7 @@
 import java.awt.Component;
 import java.awt.Image;
 import java.awt.Font;
+import java.awt.event.KeyEvent;
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.swing.Icon;
@@ -63,10 +64,10 @@
   protected Component labelFor;
 
   /** The label's text. */
-  private transient String labelText;
+  private transient String text;
 
   /** Where the label will be positioned horizontally. */
-  private transient int horizontalAlignment = CENTER;
+  private transient int horizontalAlignment = LEADING;
 
   /** Where the label text will be placed horizontally relative to the icon. */
   private transient int horizontalTextPosition = TRAILING;
@@ -78,16 +79,16 @@
   private transient int verticalTextPosition = CENTER;
 
   /** The icon painted when the label is enabled. */
-  private transient Icon activeIcon;
+  private transient Icon icon;
 
   /** The icon painted when the label is disabled. */
   private transient Icon disabledIcon;
 
   /** The label's mnemnonic key. */
-  private transient char mnemonicKey;
+  private transient int displayedMnemonic = KeyEvent.VK_UNDEFINED;
 
   /** The index of the menemonic character in the text. */
-  private transient int underlinedChar = -1;
+  private transient int displayedMnemonicIndex = -1;
 
   /** The gap between the icon and the text. */
   private transient int iconTextGap = 4;
@@ -209,8 +210,8 @@
    */
   public JLabel(String text, Icon icon, int horizontalAlignment)
   {
-    labelText = text;
-    activeIcon = icon;
+    this.text = text;
+    this.icon = icon;
     this.horizontalAlignment = horizontalAlignment;
     updateUI();
   }
@@ -273,24 +274,26 @@
    */
   public String getText()
   {
-    return labelText;
+    return text;
   }
 
   /**
    * This method changes the "text" property. The given text will be painted
    * in the label.
    *
-   * @param text The label's text.
+   * @param newText The label's text.
    */
-  public void setText(String text)
+  public void setText(String newText)
   {
-    if (text != labelText)
+    if (text != newText)
       {
-       String oldText = labelText;
-       labelText = text;
-       firePropertyChange(TEXT_CHANGED_PROPERTY, oldText, labelText);
-       if (labelText != null && labelText.length() <= underlinedChar)
-         setDisplayedMnemonicIndex(labelText.length() - 1);
+       String oldText = text;
+       text = newText;
+       firePropertyChange(TEXT_CHANGED_PROPERTY, oldText, newText);
+        
+       if (text != null
+            && text.length() <= displayedMnemonicIndex)
+         setDisplayedMnemonicIndex(text.length() - 1);
       }
   }
 
@@ -302,22 +305,22 @@
    */
   public Icon getIcon()
   {
-    return activeIcon;
+    return icon;
   }
 
   /**
    * This method changes the "icon" property. This icon (the active icon) will
    * be the one displayed when the label is enabled.
    *
-   * @param icon The active icon.
+   * @param newIcon The active icon.
    */
-  public void setIcon(Icon icon)
+  public void setIcon(Icon newIcon)
   {
-    if (icon != activeIcon)
+    if (icon != newIcon)
       {
-       Icon oldIcon = activeIcon;
-       activeIcon = icon;
-       firePropertyChange(ICON_CHANGED_PROPERTY, oldIcon, activeIcon);
+       Icon oldIcon = icon;
+       icon = newIcon;
+       firePropertyChange(ICON_CHANGED_PROPERTY, oldIcon, newIcon);
       }
   }
 
@@ -331,8 +334,9 @@
    */
   public Icon getDisabledIcon()
   {
-    if (disabledIcon == null && activeIcon instanceof ImageIcon)
-      disabledIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) 
activeIcon).getImage()));
+    if (disabledIcon == null && icon instanceof ImageIcon)
+      disabledIcon = new ImageIcon(GrayFilter.createDisabledImage(((ImageIcon) 
icon).getImage()));
+    
     return disabledIcon;
   }
 
@@ -340,16 +344,15 @@
    * This method changes the "disabledIcon" property. This icon (the disabled
    * icon) will be the one displayed when the label is disabled.
    *
-   * @param disabledIcon The disabled icon.
+   * @param newIcon The disabled icon.
    */
-  public void setDisabledIcon(Icon disabledIcon)
+  public void setDisabledIcon(Icon newIcon)
   {
-    if (disabledIcon != this.disabledIcon)
+    if (disabledIcon != newIcon)
       {
-       Icon oldDisabledIcon = this.disabledIcon;
-       this.disabledIcon = disabledIcon;
-       firePropertyChange(DISABLED_ICON_CHANGED_PROPERTY, oldDisabledIcon,
-                          this.disabledIcon);
+       Icon oldIcon = disabledIcon;
+       disabledIcon = newIcon;
+       firePropertyChange(DISABLED_ICON_CHANGED_PROPERTY, oldIcon, newIcon);
       }
   }
 
@@ -358,31 +361,32 @@
    * label is used as a label for another component, the label will give
    * focus to that component when the mnemonic is activated.
    *
-   * @param key The keycode to use for the mnemonic.
+   * @param mnemonic The keycode to use for the mnemonic.
    */
-  public void setDisplayedMnemonic(int key)
+  public void setDisplayedMnemonic(int mnemonic)
   {
-    setDisplayedMnemonic((char) key);
+    if (displayedMnemonic != mnemonic)
+  {
+       firePropertyChange(DISPLAYED_MNEMONIC_CHANGED_PROPERTY,
+                           displayedMnemonic, mnemonic);
+       displayedMnemonic = mnemonic;
+        
+       if (text != null)
+         setDisplayedMnemonicIndex(text.indexOf(mnemonic));
+      }
   }
 
+
   /**
    * This method sets the character that will be the mnemonic used. If the
    * label is used as a label for another component, the label will give
    * focus to that component when the mnemonic is activated.
    *
-   * @param aChar The character to use for the mnemonic.
+   * @param menmonic The character to use for the mnemonic.
    */
-  public void setDisplayedMnemonic(char aChar)
-  {
-    if (aChar != mnemonicKey)
+  public void setDisplayedMnemonic(char mnemonic)
       {
-       char oldKey = mnemonicKey;
-       mnemonicKey = aChar;
-       firePropertyChange(DISPLAYED_MNEMONIC_CHANGED_PROPERTY, oldKey,
-                          mnemonicKey);
-       if (labelText != null)
-         setDisplayedMnemonicIndex(labelText.indexOf(mnemonicKey));
-      }
+    setDisplayedMnemonic((int) mnemonic);
   }
 
   /**
@@ -392,7 +396,7 @@
    */
   public int getDisplayedMnemonic()
   {
-    return (int) mnemonicKey;
+    return (int) displayedMnemonic;
   }
 
   /**
@@ -401,26 +405,25 @@
    * no mnemonic. If the index is less than -1 or if the index is equal to
    * the length, this method will throw an IllegalArgumentException.
    *
-   * @param index The index of the character to underline.
+   * @param newIndex The index of the character to underline.
    *
    * @throws IllegalArgumentException If index less than -1 or index equals
    *         length.
    */
-  public void setDisplayedMnemonicIndex(int index)
+  public void setDisplayedMnemonicIndex(int newIndex)
                                  throws IllegalArgumentException
   {
-    if (index < -1 || labelText != null && index >= labelText.length())
+    if (newIndex < -1 || (text != null && newIndex >= text.length()))
       throw new IllegalArgumentException();
       
-    if (labelText == null || labelText.charAt(index) != mnemonicKey)
-      index = -1;
+    if (text == null || text.charAt(newIndex) != displayedMnemonic)
+      newIndex = -1;
       
-    if (index != underlinedChar)
+    if (newIndex != displayedMnemonicIndex)
     {
-      int oldIndex = underlinedChar;  
-      underlinedChar = index;
       firePropertyChange(DISPLAYED_MNEMONIC_INDEX_CHANGED_PROPERTY,
-                         oldIndex, underlinedChar);
+                           displayedMnemonicIndex, newIndex);
+        displayedMnemonicIndex = newIndex;
     }
   }
 
@@ -432,7 +435,7 @@
    */
   public int getDisplayedMnemonicIndex()
   {
-    return underlinedChar;
+    return displayedMnemonicIndex;
   }
 
   /**
@@ -490,16 +493,15 @@
    * This method changes the "iconTextGap" property. The iconTextGap
    * determines how much space there is between the icon and the text.
    *
-   * @param iconTextGap The gap between the icon and the text.
+   * @param newGap The gap between the icon and the text.
    */
-  public void setIconTextGap(int iconTextGap)
+  public void setIconTextGap(int newGap)
   {
-    if (iconTextGap != this.iconTextGap)
+    if (iconTextGap != newGap)
       {
-       int oldIconTextGap = this.iconTextGap;
-       this.iconTextGap = iconTextGap;
-       firePropertyChange(ICON_TEXT_GAP_CHANGED_PROPERTY, oldIconTextGap,
-                          iconTextGap);
+       firePropertyChange(ICON_TEXT_GAP_CHANGED_PROPERTY, iconTextGap,
+                          newGap);
+       iconTextGap = newGap;
       }
   }
 
@@ -632,11 +634,12 @@
   public boolean imageUpdate(Image img, int infoflags, int x, int y, int w,
                              int h)
   {
-    Icon currIcon = (isEnabled()) ? activeIcon : disabledIcon;
+    Icon currIcon = isEnabled() ? icon : disabledIcon;
 
-    //Is this the correct way to check for image equality?
+    // XXX: Is this the correct way to check for image equality?
     if (currIcon != null && currIcon instanceof ImageIcon)
       return (((ImageIcon) currIcon).getImage() == img);
+    
     return false;
   }
 
@@ -664,9 +667,8 @@
   {
     if (c != labelFor)
       {
-       Component oldLabelFor = labelFor;
+       firePropertyChange(LABEL_FOR_CHANGED_PROPERTY, labelFor, c);
        labelFor = c;
-       firePropertyChange(LABEL_FOR_CHANGED_PROPERTY, oldLabelFor, labelFor);
       }
   }
   
Index: javax/swing/JRadioButton.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JRadioButton.java,v
retrieving revision 1.9
diff -u -r1.9 JRadioButton.java
--- javax/swing/JRadioButton.java       22 Jul 2004 19:45:39 -0000      1.9
+++ javax/swing/JRadioButton.java       4 Sep 2004 17:00:13 -0000
@@ -48,6 +48,7 @@
     {
        this(null, null);
     }
+    
     public JRadioButton(Action a)
     {
        this();
@@ -59,11 +60,21 @@
        this(null, icon);
     }    
   
+  public JRadioButton(Icon icon, boolean selected)
+  { 
+    this(null, icon, selected);
+  }    
+  
     public JRadioButton(String text)
     {
        this(text, null);
     }
       
+  public JRadioButton(String text, boolean selected)
+  {
+    this(text, null, selected);
+  }
+      
     public JRadioButton(String text, Icon icon)
     {
        super(text, icon);
@@ -71,6 +82,9 @@
         contentAreaFilled = false;
     }
 
+  public JRadioButton(String text, Icon icon, boolean selected)
+  {
+  }
     
     public AccessibleContext getAccessibleContext()
     {
Index: javax/swing/JTextArea.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JTextArea.java,v
retrieving revision 1.3
diff -u -r1.3 JTextArea.java
--- javax/swing/JTextArea.java  18 Aug 2004 23:05:59 -0000      1.3
+++ javax/swing/JTextArea.java  4 Sep 2004 17:00:13 -0000
@@ -103,13 +103,15 @@
   /**
    * Whether line wrapping is enabled or not.
    */
-  private boolean wrapping;
+  private boolean lineWrap;
 
   /**
    * The number of characters equal to a tab within the text.
    */
   private int tabSize = 8;
 
+  private boolean wrapStyleWord;
+
   /**
    * Creates a new <code>JTextArea</code> object.
    */
@@ -221,7 +223,7 @@
    */
   public boolean getScrollableTracksViewportWidth()
   {
-    return wrapping ? true : super.getScrollableTracksViewportWidth();
+    return lineWrap ? true : super.getScrollableTracksViewportWidth();
   }
 
   /**
@@ -287,29 +289,58 @@
   /**
    * Checks whether line wrapping is enabled.
    *
-   * @return true if line wrapping is enabled, false otherwise
+   * @return <code>true</code> if line wrapping is enabled,
+   * <code>false</code> otherwise
    */
   public boolean getLineWrap()
   {
-    return wrapping;
+    return lineWrap;
   }
 
   /**
    * Enables/disables line wrapping.
    *
-   * @param wrapping true to enable line wrapping, false otherwise
+   * @param wrapping <code>true</code> to enable line wrapping,
+   * <code>false</code> otherwise
    */
   public void setLineWrap(boolean flag)
   {
-    if (wrapping == flag)
+    if (lineWrap == flag)
       return;
 
-    boolean oldValue = wrapping;
-    wrapping = flag;
-    firePropertyChange("lineWrap", oldValue, wrapping);
+    boolean oldValue = lineWrap;
+    lineWrap = flag;
+    firePropertyChange("lineWrap", oldValue, lineWrap);
   }
 
   /**
+   * Checks whether word style wrapping is enabled.
+   *
+   * @return <code>true</code> if word style wrapping is enabled,
+   * <code>false</code> otherwise
+   */
+  public boolean getWrapStyleWord()
+  {
+    return wrapStyleWord;
+  }
+  
+  /**
+   * Enables/Disables word style wrapping.
+   *
+   * @param flag <code>true</code> to enable word style wrapping,
+   * <code>false</code> otherwise
+   */
+  public void setWrapStyleWord(boolean flag)
+  {
+    if (wrapStyleWord == flag)
+      return;
+    
+    boolean oldValue = wrapStyleWord;
+    wrapStyleWord = flag;
+    firePropertyChange("wrapStyleWord", oldValue, wrapStyleWord);
+  }
+  
+  /**
    * Returns the number of characters used for a tab.
    * This defaults to 8.
    *
Index: javax/swing/JTextField.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JTextField.java,v
retrieving revision 1.11
diff -u -r1.11 JTextField.java
--- javax/swing/JTextField.java 30 Jul 2004 20:21:19 -0000      1.11
+++ javax/swing/JTextField.java 4 Sep 2004 17:00:13 -0000
@@ -138,9 +138,15 @@
    */
   public JTextField(Document doc, String text, int columns)
   {
+    if (columns < 0)
+      throw new IllegalArgumentException();
+    
+    this.columns = columns;
+    
     setDocument(doc == null ? createDefaultModel() : doc);
+
+    if (text != null)
     setText(text);
-    setColumns(columns);
   }
 
   /**
Index: javax/swing/KeyStroke.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/KeyStroke.java,v
retrieving revision 1.9
diff -u -r1.9 KeyStroke.java
--- javax/swing/KeyStroke.java  31 Jul 2004 16:39:15 -0000      1.9
+++ javax/swing/KeyStroke.java  4 Sep 2004 17:00:13 -0000
@@ -37,235 +37,69 @@
 
 package javax.swing;
 
+import java.awt.AWTKeyStroke;
 import java.awt.event.KeyEvent;
 import java.io.Serializable;
 
-/**
- * KeyStroke
- * @author     Andrew Selkirk
- * @version    1.0
- */
-public class KeyStroke implements Serializable
+public class KeyStroke 
+  extends AWTKeyStroke
+  implements Serializable
 {
   static final long serialVersionUID = -9060180771037902530L;
-
-       //-------------------------------------------------------------
-       // Variables --------------------------------------------------
-       //-------------------------------------------------------------
-
-       /**
-        * keyChar
-        */
-       private char    keyChar                 = 0;
-
-       /**
-        * keyCode
-        */
-       private int             keyCode                 = 0;
-
-       /**
-        * modifiers
-        */
-       private int             modifiers               = 0;
-
-       /**
-        * onKeyRelease
-        */
-       private boolean onKeyRelease    = false;
-
-
-       //-------------------------------------------------------------
-       // Initialization ---------------------------------------------
-       //-------------------------------------------------------------
-
-       /**
-        * Constructor KeyStroke
-        */
        private KeyStroke() {
-       } // KeyStroke()
-
-
-       //-------------------------------------------------------------
-       // Methods ----------------------------------------------------
-       //-------------------------------------------------------------
-
-       /**
-        * hashCode
-        * @returns int
-        */
-       public int hashCode() {
-               return 0; // TODO
-       } // hashCode()
-
-       /**
-        * equals
-        * @param object TODO
-        * @returns boolean
-        */
-       public boolean equals(Object object) {
-
-               // Variables
-               KeyStroke       key;
-
-               if (object instanceof KeyStroke) {
-                       key = (KeyStroke) object;
-                       if (key.keyChar == keyChar &&
-                               key.keyCode == keyCode &&
-                               key.modifiers == modifiers &&
-                               key.onKeyRelease == onKeyRelease) {
-                               return true;
-                       } // if
-               } // if
-               return false;
-
-       } // equals()
-
-       /**
-        * toString
-        * @returns String
-        */
-       public String toString() {
-               return null; // TODO
-       } // toString()
-
-       /**
-        * getKeyStroke
-        * @param keyChar TODO
-        * @returns KeyStroke
-        */
-       public static KeyStroke getKeyStroke(char keyChar) {
-
-               // Variables
-               KeyStroke       key;
+  }
 
-               key = new KeyStroke();
-               key.keyChar = keyChar;
-               return key;
+  protected KeyStroke(char keyChar, int keyCode, int modifiers,
+                      boolean onKeyRelease)
+  {
+    super(keyChar, keyCode, modifiers, onKeyRelease);
+  }
+
+  static
+  {
+    AWTKeyStroke.registerSubclass(KeyStroke.class);
+  }
+
+  public static KeyStroke getKeyStroke(char keyChar) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyChar);
+  }
+
+       /**
+   * @deprecated Use address@hidden #getKeyStroke(char)}
+   *
+   * This method, unlike all the other factory methods on this object,
+   * returns a non-cached, non-shared object. New code should not use it.
+        */
+  public static KeyStroke getKeyStroke(char keyChar, boolean onKeyRelease) 
+  {
+    return new KeyStroke(keyChar, KeyEvent.VK_UNDEFINED, 0, onKeyRelease);
+  }
+
+  public static KeyStroke getKeyStroke(Character keyChar, int modifiers) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyChar, modifiers);
+  }
 
-       } // getKeyStroke()
-
-       /**
-        * getKeyStroke - deprecated
-        * @param keyChar TODO
-        * @param onKeyRelease TODO
-        * @returns KeyStroke
-        * @deprecated Use getKeyStroke(char)
-        */
-       public static KeyStroke getKeyStroke(char keyChar, boolean 
onKeyRelease) {
-               KeyStroke key = getKeyStroke(keyChar);
-               key.onKeyRelease = onKeyRelease;
-               return key;
-       } // getKeyStroke()
-
-       /**
-        * getKeyStroke
-        * @param keyChar TODO
-        * @param modifiers TODO
-        * @returns KeyStroke
-        */
-       public static KeyStroke getKeyStroke(Character keyChar, int modifiers) {
-               KeyStroke key = getKeyStroke(keyChar.charValue());
-               key.modifiers = modifiers;
-               return key;
-       } // getKeyStroke()
-
-       /**
-        * getKeyStroke
-        * @param keyCode TODO
-        * @param modifiers TODO
-        * @param onKeyRelease TODO
-        * @returns KeyStroke
-        */
        public static KeyStroke getKeyStroke(int keyCode, int modifiers, 
-                               boolean onKeyRelease) {
-
-               // Variables
-               KeyStroke       key;
-
-               key = new KeyStroke();
-               key.keyCode = keyCode;
-               key.modifiers = modifiers;
-               key.onKeyRelease = onKeyRelease;
-               return key;
-
-       } // getKeyStroke()
-
-       /**
-        * getKeyStroke
-        * @param keyCode TODO
-        * @param modifiers TODO
-        * @returns KeyStroke
-        */
-       public static KeyStroke getKeyStroke(int keyCode, int modifiers) {
-               return getKeyStroke(keyCode, modifiers, false);
-       } // getKeyStroke()
-
-       /**
-        * getKeyStroke
-        * @param string TODO
-        * @returns KeyStroke
-        */
-       public static KeyStroke getKeyStroke(String string) {
-               return null; // TODO
-       } // getKeyStroke()
-
-       /**
-        * getKeyStrokeForEvent
-        * @param event TODO
-        * @returns KeyStroke
-        */
-       public static KeyStroke getKeyStrokeForEvent(KeyEvent event) {
-
-               // Variables
-               int     eventID;
-               int     eventMod;
-
-               // Get Event ID
-               eventID = event.getID();
-               eventMod = event.getModifiersEx();
-
-               // Check for KEY_TYPED event
-               if (eventID == KeyEvent.KEY_TYPED) {
-                       return getKeyStroke(event.getKeyChar(), eventMod);
-
-               // KEY_PRESSED or KEY_RELEASED event
-               } else {
-                       return getKeyStroke(event.getKeyCode(), eventMod);
-               } // if
-
-       } // getKeyStrokeForEvent()
-
-       /**
-        * getKeyChar
-        * @returns char
-        */
-       public char getKeyChar() {
-               return keyChar;
-       } // getKeyChar()
-
-       /**
-        * getKeyCode
-        * @returns int
-        */
-       public int getKeyCode() {
-               return keyCode;
-       } // getKeyCode()
-
-       /**
-        * getModifiers
-        * @returns int
-        */
-       public int getModifiers() {
-               return modifiers; // TODO
-       } // getModifiers()
-
-       /**
-        * isOnKeyRelease
-        * @returns boolean
-        */
-       public boolean isOnKeyRelease() {
-               return onKeyRelease;
-       } // isOnKeyRelease()
-
+                                       boolean onKeyRelease) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyCode, modifiers, onKeyRelease);
+  }
+
+  public static KeyStroke getKeyStroke(int keyCode, int modifiers) 
+  {
+    return (KeyStroke) getAWTKeyStroke(keyCode, modifiers);
+  }
+
+  public static KeyStroke getKeyStroke(String str) 
+  {
+    return (KeyStroke) getAWTKeyStroke(str);
+  }
+
+  public static KeyStroke getKeyStrokeForEvent(KeyEvent event) 
+  {
+    return (KeyStroke) getAWTKeyStrokeForEvent(event);
+  }
 
-} // KeyStroke
+}
Index: javax/swing/SwingUtilities.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/SwingUtilities.java,v
retrieving revision 1.15
diff -u -r1.15 SwingUtilities.java
--- javax/swing/SwingUtilities.java     31 Jul 2004 16:39:15 -0000      1.15
+++ javax/swing/SwingUtilities.java     4 Sep 2004 17:00:13 -0000
@@ -51,9 +51,13 @@
 import java.awt.Shape;
 import java.awt.Toolkit;
 import java.awt.Window;
+import java.awt.event.ActionEvent;
 import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
 import java.awt.event.MouseEvent;
 import java.lang.reflect.InvocationTargetException;
+import javax.swing.plaf.ActionMapUIResource;
+import javax.swing.plaf.InputMapUIResource;
 
 
 /**
@@ -911,4 +915,103 @@
       return true;
     }
   }
+
+  public static boolean notifyAction(Action action,
+                                     KeyStroke ks,
+                                     KeyEvent event,
+                                     Object sender,
+                                     int modifiers)
+  {
+    if (action != null && action.isEnabled())
+      {
+        String name = (String) action.getValue(Action.ACTION_COMMAND_KEY);
+        if (name == null
+            && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED)
+          name = new String(new char[] {event.getKeyChar()});
+        action.actionPerformed(new ActionEvent(sender,
+                                               ActionEvent.ACTION_PERFORMED,
+                                               name, modifiers));
+        return true;
+      }
+    return false;
+  }
+
+  /**
+   * <p>Change the shared, UI-managed address@hidden ActionMap} for a given
+   * component. ActionMaps are arranged in a hierarchy, in order to
+   * encourage sharing of common actions between components. The hierarchy
+   * unfortunately places UI-managed ActionMaps at the <em>end</em> of the
+   * parent-pointer chain, as illustrated:</p>
+   *
+   * <pre>
+   *  address@hidden javax.swing.JComponent#getActionMap()}] 
+   *          --&gt; address@hidden javax.swing.ActionMap}] 
+   *     parent --&gt; address@hidden javax.swing.text.KeymapActionMap}] 
+   *       parent --&gt; address@hidden javax.swing.plaf.ActionMapUIResource}]
+   * </pre>
+   *
+   * <p>Our goal with this method is to replace the first ActionMap along
+   * this chain which is an instance of address@hidden ActionMapUIResource}, 
since
+   * these are the ActionMaps which are supposed to be shared between
+   * components.</p>
+   *
+   * <p>If the provided ActionMap is <code>null</code>, we interpret the
+   * call as a request to remove the UI-managed ActionMap from the
+   * component's ActionMap parent chain.</p>
+   */
+  public static void replaceUIActionMap(JComponent component, 
+                                        ActionMap uiActionMap)
+  {
+    ActionMap child = component.getActionMap();
+    if (child == null)
+      component.setActionMap(uiActionMap);
+    else
+      {
+        while(child.getParent() != null
+              && !(child.getParent() instanceof ActionMapUIResource))
+          child = child.getParent();
+        if (child != null)
+          child.setParent(uiActionMap);
+      }
+  }
+
+  /**
+   * <p>Change the shared, UI-managed address@hidden InputMap} for a given
+   * component. InputMaps are arranged in a hierarchy, in order to
+   * encourage sharing of common input mappings between components. The
+   * hierarchy unfortunately places UI-managed InputMaps at the
+   * <em>end</em> of the parent-pointer chain, as illustrated:</p>
+   *
+   * <pre>
+   *  address@hidden javax.swing.JComponent#getInputMap()}] 
+   *          --&gt; address@hidden javax.swing.InputMap}] 
+   *     parent --&gt; address@hidden javax.swing.text.KeymapWrapper}] 
+   *       parent --&gt; address@hidden javax.swing.plaf.InputMapUIResource}]
+   * </pre>
+   *
+   * <p>Our goal with this method is to replace the first InputMap along
+   * this chain which is an instance of address@hidden InputMapUIResource}, 
since
+   * these are the InputMaps which are supposed to be shared between
+   * components.</p>
+   *
+   * <p>If the provided InputMap is <code>null</code>, we interpret the
+   * call as a request to remove the UI-managed InputMap from the
+   * component's InputMap parent chain.</p>
+   */
+  public static void replaceUIInputMap(JComponent component, 
+                                       int condition, 
+                                       InputMap uiInputMap)
+  {
+    InputMap child = component.getInputMap(condition);
+    if (child == null)
+      component.setInputMap(condition, uiInputMap);
+    else
+      {
+        while(child.getParent() != null
+              && !(child.getParent() instanceof InputMapUIResource))
+          child = child.getParent();
+        if (child != null)
+          child.setParent(uiInputMap);
+      }
+  }
 }
Index: javax/swing/TransferHandler.java
===================================================================
RCS file: javax/swing/TransferHandler.java
diff -N javax/swing/TransferHandler.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/TransferHandler.java    4 Sep 2004 17:00:13 -0000
@@ -0,0 +1,55 @@
+/* TransferHandler.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;
+
+import java.io.Serializable;
+
+public class TransferHandler implements Serializable
+{
+  private static final long serialVersionUID = -7908749299918704233L;
+
+  public static final int NONE = 0;
+  public static final int COPY = 1;
+  public static final int MOVE = 2;
+  public static final int COPY_OR_MOVE = 3;
+
+  protected TransferHandler()
+  {
+    // Do nothing here.
+  }
+}
Index: javax/swing/plaf/basic/BasicButtonListener.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicButtonListener.java,v
retrieving revision 1.4
diff -u -r1.4 BasicButtonListener.java
--- javax/swing/plaf/basic/BasicButtonListener.java     31 Jul 2004 16:39:15 
-0000      1.4
+++ javax/swing/plaf/basic/BasicButtonListener.java     4 Sep 2004 17:00:13 
-0000
@@ -37,6 +37,7 @@
 
 package javax.swing.plaf.basic;
 
+import java.awt.event.ActionEvent;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.awt.event.InputEvent;
@@ -46,6 +47,7 @@
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 
+import javax.swing.AbstractAction;
 import javax.swing.AbstractButton;
 import javax.swing.ButtonModel;
 import javax.swing.JComponent;
@@ -64,6 +66,12 @@
   }
   public void focusGained(FocusEvent e) 
   {    
+    if (e.getSource() instanceof AbstractButton)
+      {
+        AbstractButton button = (AbstractButton) e.getSource();
+        if (button.isFocusPainted())
+          button.repaint();   
+      }
   }
 
   public void focusLost(FocusEvent e)
@@ -73,13 +81,43 @@
         AbstractButton button = (AbstractButton) e.getSource();
         ButtonModel model = button.getModel();
         model.setArmed(false);
+
+        if (button.isFocusPainted())
+          button.repaint();   
       }
   }
   public void installKeyboardActions(JComponent c)
   {
+    c.getActionMap().put("pressed", 
+                         new AbstractAction() 
+                         {
+                           public void actionPerformed(ActionEvent e)          
+                           {
+                             AbstractButton button = (AbstractButton) 
e.getSource();
+                             ButtonModel model = button.getModel();
+                             // It is important that these transitions happen 
in this order.
+                             model.setArmed(true);
+                             model.setPressed(true);
+                           }
+                         });
+    
+    c.getActionMap().put("released", 
+                         new AbstractAction() 
+                         {
+                           public void actionPerformed(ActionEvent e)          
+                           {
+                             AbstractButton button = (AbstractButton) 
e.getSource();
+                             ButtonModel model = button.getModel();
+                             // It is important that these transitions happen 
in this order.
+                             model.setPressed(false);
+                             model.setArmed(false);
+                           }
+                       });    
   }
   public void uninstallKeyboardActions(JComponent c)
   {
+    c.getActionMap().put("pressed", null);
+    c.getActionMap().put("released", null);
   }
   public void stateChanged(ChangeEvent e)
   {
Index: javax/swing/plaf/basic/BasicButtonUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicButtonUI.java,v
retrieving revision 1.12
diff -u -r1.12 BasicButtonUI.java
--- javax/swing/plaf/basic/BasicButtonUI.java   22 Jul 2004 19:45:39 -0000      
1.12
+++ javax/swing/plaf/basic/BasicButtonUI.java   4 Sep 2004 17:00:13 -0000
@@ -50,6 +50,7 @@
 import javax.swing.AbstractButton;
 import javax.swing.ButtonModel;
 import javax.swing.Icon;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.SwingUtilities;
 import javax.swing.UIDefaults;
@@ -59,13 +60,21 @@
 
 public class BasicButtonUI extends ButtonUI
 {
-  /** A constant used to pad out elements in the button's layout and
-      preferred size calculations. */
-  int defaultTextIconGap = 4;
-
-  /** A constant added to the defaultTextIconGap to adjust the text
-      within this particular button. */
-  int defaultTextShiftOffset = 0;
+  /**
+   * A constant used to pad out elements in the button's layout and
+   * preferred size calculations.
+   */
+  protected int defaultTextIconGap = 4;
+
+  /**
+   * A constant added to the defaultTextIconGap to adjust the text
+   * within this particular button.
+   */
+  protected int defaultTextShiftOffset = 0;
+
+  private int textShiftOffset;
+
+  private Color focusColor;
 
   /**
    * Factory method to create an instance of BasicButtonUI for a given
@@ -85,14 +94,32 @@
     return defaultTextIconGap;
   }
 
+  protected void clearTextShiftOffset()
+  {
+    textShiftOffset = 0;
+  }
+  
+  protected int getTextShiftOffset()
+  {
+    return textShiftOffset;
+  }
+
+  protected void setTextShiftOffset()
+  {
+    textShiftOffset = defaultTextShiftOffset;
+  }
+
   protected void installDefaults(AbstractButton b)
   {
     UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    focusColor = defaults.getColor("Button.focus");
     b.setForeground(defaults.getColor("Button.foreground"));
     b.setBackground(defaults.getColor("Button.background"));
     b.setMargin(defaults.getInsets("Button.margin"));
     b.setBorder(defaults.getBorder("Button.border"));
     b.setIconTextGap(defaults.getInt("Button.textIconGap"));
+    b.setInputMap(JComponent.WHEN_FOCUSED, 
+                  (InputMap) defaults.get("Button.focusInputMap"));
     b.setOpaque(true);
   }
 
@@ -133,10 +160,12 @@
 
   protected void installKeyboardActions(AbstractButton b)
   {
+    listener.installKeyboardActions(b);
   }
 
   protected void uninstallKeyboardActions(AbstractButton b)
   {
+    listener.uninstallKeyboardActions(b);
   }
 
   /**
@@ -271,22 +300,12 @@
   {
     if (b.hasFocus() && b.isFocusPainted())
       {
-        Graphics2D g2 = (Graphics2D) g;
-        Stroke saved_stroke = g2.getStroke();
-        Color saved_color = g2.getColor();
-        float dashes[] = new float[] {1.0f, 1.0f};        
-        BasicStroke s = new BasicStroke(1.0f, 
-                                        BasicStroke.CAP_SQUARE, 
-                                        BasicStroke.JOIN_MITER,
-                                        10, dashes, 0.0f);
-        g2.setStroke(s);
-        g2.setColor(Color.BLACK);
-        g2.drawRect(vr.x + 2, 
-                    vr.y + 2, 
-                    vr.width - 4,
-                    vr.height - 4);
-        g2.setStroke(saved_stroke);
-        g2.setColor(saved_color);
+        Color saved_color = g.getColor();
+        g.setColor(focusColor);
+        Rectangle focusRect = ir.union(tr);
+        g.drawRect(focusRect.x, focusRect.y,
+                   focusRect.width, focusRect.height);
+        g.setColor(saved_color);
       }
   }
 
Index: javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
diff -N javax/swing/plaf/basic/BasicFormattedTextFieldUI.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicFormattedTextFieldUI.java       4 Sep 2004 
17:00:14 -0000
@@ -0,0 +1,62 @@
+/* BasicFormattedTextFieldUI.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 javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+
+/**
+ * @since 1.4
+ */
+public class BasicFormattedTextFieldUI extends BasicTextFieldUI
+{
+  public BasicFormattedTextFieldUI()
+  {
+  }
+
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicFormattedTextFieldUI();
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "FormattedTextField";
+  }
+}
\ No newline at end of file
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.14
diff -u -r1.14 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java        14 Aug 2004 22:17:49 
-0000      1.14
+++ javax/swing/plaf/basic/BasicLookAndFeel.java        4 Sep 2004 17:00:14 
-0000
@@ -41,6 +41,7 @@
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Font;
+import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.io.Serializable;
 import java.util.Enumeration;
@@ -247,6 +248,7 @@
         "SPACE",  "pressed",
         "released SPACE", "released"
       }),
+      "Button.focus", midPurple,
       "Button.font", new FontUIResource("Dialog", Font.PLAIN, 12),
       "Button.foreground", new ColorUIResource(Color.black),
       "Button.highlight", new ColorUIResource(Color.white),
@@ -821,7 +823,14 @@
       "TextField.keyBindings", new JTextComponent.KeyBinding[] {
         new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
                                                              0),
-                                      "notify-field-accept")},
+                                      "notify-field-accept"),
+        new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT,
+                                                            
InputEvent.SHIFT_DOWN_MASK),
+                                                            
"selection-backward"),
+        new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
+                                                            
InputEvent.SHIFT_DOWN_MASK),
+                                                            
"selection-forward"),
+          },
       "TextField.margin", new InsetsUIResource(0, 0, 0, 0),
       "TextField.selectionBackground", new ColorUIResource(lightPurple),
       "TextField.selectionForeground", new ColorUIResource(Color.black),
Index: javax/swing/plaf/basic/BasicPasswordFieldUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicPasswordFieldUI.java
diff -N javax/swing/plaf/basic/BasicPasswordFieldUI.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicPasswordFieldUI.java    4 Sep 2004 17:00:14 
-0000
@@ -0,0 +1,61 @@
+/* BasicPasswordFieldUI.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 javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.text.Element;
+import javax.swing.text.View;
+
+public class BasicPasswordFieldUI extends BasicTextFieldUI
+{
+  public BasicPasswordFieldUI()
+  {
+  }
+
+  public static ComponentUI createUI(JComponent c)
+  {
+    return new BasicPasswordFieldUI();
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "PasswordField";
+  }
+}
Index: javax/swing/plaf/basic/BasicTextAreaUI.java
===================================================================
RCS file: javax/swing/plaf/basic/BasicTextAreaUI.java
diff -N javax/swing/plaf/basic/BasicTextAreaUI.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/BasicTextAreaUI.java 4 Sep 2004 17:00:14 -0000
@@ -0,0 +1,69 @@
+/* BasicTextAreaUI.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.beans.PropertyChangeEvent;
+
+import javax.swing.JComponent;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.text.Element;
+import javax.swing.text.PlainView;
+import javax.swing.text.View;
+
+public class BasicTextAreaUI extends BasicTextUI
+{
+  public static ComponentUI createUI(JComponent comp)
+  {
+    return new BasicTextAreaUI();
+  }
+
+  public BasicTextAreaUI()
+  {
+  }
+
+  public View create(Element elem)
+  {
+    return new PlainView(elem);
+  }
+
+  protected String getPropertyPrefix()
+  {
+    return "TextArea";
+  }
+}
Index: javax/swing/plaf/basic/BasicTextUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTextUI.java,v
retrieving revision 1.10
diff -u -r1.10 BasicTextUI.java
--- javax/swing/plaf/basic/BasicTextUI.java     31 Jul 2004 22:56:54 -0000      
1.10
+++ javax/swing/plaf/basic/BasicTextUI.java     4 Sep 2004 17:00:14 -0000
@@ -46,8 +46,16 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Shape;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.TextUI;
 import javax.swing.plaf.UIResource;
@@ -61,7 +69,9 @@
 import javax.swing.text.Element;
 import javax.swing.text.Highlighter;
 import javax.swing.text.JTextComponent;
+import javax.swing.text.Keymap;
 import javax.swing.text.PlainDocument;
+import javax.swing.text.PlainView;
 import javax.swing.text.Position;
 import javax.swing.text.View;
 import javax.swing.text.ViewFactory;
@@ -88,13 +98,17 @@
   
   private class RootView extends View
   {
-    private JTextComponent textComponent;
     private View view;
     
-    public RootView(JTextComponent parent)
+    public RootView()
     {
       super(null);
-      textComponent = parent;
+    }
+
+    public ViewFactory getViewFactory()
+    {
+      // FIXME: Handle EditorKit somehow.
+      return BasicTextUI.this;
     }
 
     public void setView(View v)
@@ -123,17 +137,34 @@
 
     public void paint(Graphics g, Shape s)
     {
-      System.out.println("Michael: BasicTextUI.RootView.paint");
-      
       if (view != null)
        view.paint(g, s);
     }
+
+    protected Rectangle modelToView(int position, Shape a, Position.Bias bias)
+      throws BadLocationException
+    {
+      return ((PlainView) view).modelToView(position, a, bias).getBounds();
+    }
   }
-  
-  RootView rootView;
+
+  class UpdateHandler implements PropertyChangeListener
+  {
+    public void propertyChange(PropertyChangeEvent event)
+    {
+      if (event.getPropertyName().equals("document"))
+       {
+          // Document changed.
+         modelChanged();
+       }
+    }
+  }
+
+  static EditorKit kit = new DefaultEditorKit();
+
+  RootView rootView = new RootView();
   JTextComponent textComponent;
-  int gap = 3;
-  EditorKit kit = new DefaultEditorKit();
+  UpdateHandler updateHandler = new UpdateHandler();
 
   public BasicTextUI()
   {
@@ -164,12 +195,12 @@
     Document doc = textComponent.getDocument();
     if (doc == null)
       {
-       doc = new PlainDocument();
+       doc = getEditorKit(textComponent).createDefaultDocument();
        textComponent.setDocument(doc);
       }
     
-    rootView = new RootView(textComponent);
-    setView(create(doc.getDefaultRootElement()));
+    textComponent.addPropertyChangeListener(updateHandler);
+    modelChanged();
     
     installDefaults();
     installListeners();
@@ -178,20 +209,115 @@
 
   protected void installDefaults()
   {
+    Caret caret = textComponent.getCaret();
+    if (caret == null)
+      {
+        caret = createCaret();
+        textComponent.setCaret(caret);
+      }
+
+    Highlighter highlighter = textComponent.getHighlighter();
+    if (highlighter == null)
+      textComponent.setHighlighter(createHighlighter());
+
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    textComponent.setBackground(defaults.getColor(prefix + ".background"));
+    textComponent.setForeground(defaults.getColor(prefix + ".foreground"));
+    textComponent.setMargin(defaults.getInsets(prefix + ".margin"));
+    textComponent.setBorder(defaults.getBorder(prefix + ".border"));
+    textComponent.setFont(defaults.getFont(prefix + ".font"));
+
+    caret.setBlinkRate(defaults.getInt(prefix + ".caretBlinkRate"));
   }
 
   protected void installListeners()
   {
+    // Do nothing here.
+  }
+
+  protected String getKeymapName()
+  {
+    return "BasicTextUI";
+  }
+
+  protected Keymap createKeymap()
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    JTextComponent.KeyBinding[] bindings = 
+      (JTextComponent.KeyBinding[]) defaults.get(prefix + ".keyBindings");
+    Keymap km = JTextComponent.addKeymap(getKeymapName(), 
+                                         
JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP));    
+    JTextComponent.loadKeymap(km, bindings, textComponent.getActions());
+    return km;    
   }
 
   protected void installKeyboardActions()
   {
+    // load any bindings for the older Keymap interface
+    Keymap km = JTextComponent.getKeymap(getKeymapName());
+    if (km == null)
+      km = createKeymap();
+    textComponent.setKeymap(km);
+
+    // load any bindings for the newer InputMap / ActionMap interface
+    SwingUtilities.replaceUIInputMap(textComponent, 
+                                     JComponent.WHEN_FOCUSED,
+                                     getInputMap(JComponent.WHEN_FOCUSED));
+    SwingUtilities.replaceUIActionMap(textComponent, getActionMap());
+  }
+
+  InputMap getInputMap(int condition)
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    switch (condition)
+      {
+      case JComponent.WHEN_IN_FOCUSED_WINDOW:
+        // FIXME: is this the right string? nobody seems to use it.
+        return (InputMap) defaults.get(prefix + ".windowInputMap"); 
+      case JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
+        return (InputMap) defaults.get(prefix + ".ancestorInputMap");
+      default:
+      case JComponent.WHEN_FOCUSED:
+        return (InputMap) defaults.get(prefix + ".focusInputMap");
+      }
+  }
+
+  ActionMap getActionMap()
+  {
+    String prefix = getPropertyPrefix();
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();    
+    ActionMap am = (ActionMap) defaults.get(prefix + ".actionMap");
+    if (am == null)
+      {
+        am = createActionMap();
+        defaults.put(prefix + ".actionMap", am);
+      }
+    return am;
+  }
+
+  ActionMap createActionMap()
+  {
+    Action[] actions = textComponent.getActions();
+    ActionMap am = new ActionMap();
+    for (int i = 0; i < actions.length; ++i)
+      {
+        String name = (String) actions[i].getValue(Action.NAME);
+        if (name != null)
+          am.put(name, actions[i]);
+      }
+    return am;
   }
   
-  public void uninstallUI(final JComponent c)
+  public void uninstallUI(final JComponent component)
   {
-    super.uninstallUI(c);
-    rootView = null;
+    super.uninstallUI(component);
+    rootView.setView(null);
+
+    textComponent.removePropertyChangeListener(updateHandler);
+    textComponent = null;
 
     uninstallDefaults();
     uninstallListeners();
@@ -200,14 +326,17 @@
 
   protected void uninstallDefaults()
   {
+    // Do nothing here.
   }
 
   protected void uninstallListeners()
   {
+    // Do nothing here.
   }
 
   protected void uninstallKeyboardActions()
   {
+    // Do nothing here.
   }
   
   protected abstract String getPropertyPrefix();
@@ -235,18 +364,19 @@
     if (textComponent.isOpaque())
       paintBackground(g);
     
-    rootView.paint(g, getVisibleEditorRect());
-
-    if (highlighter != null)
+    if (highlighter != null
+       && textComponent.getSelectionStart() != textComponent.getSelectionEnd())
       highlighter.paint(g);
 
+    rootView.paint(g, getVisibleEditorRect());
+
     if (caret != null)
       caret.paint(g);
   }
 
   protected void paintBackground(Graphics g)
   {
-    g.setColor(Color.WHITE); // FIXME: set background color
+    g.setColor(textComponent.getBackground());
     g.fillRect(0, 0, textComponent.getWidth(), textComponent.getHeight());
   }
 
@@ -281,13 +411,13 @@
   public Rectangle modelToView(JTextComponent t, int pos)
     throws BadLocationException
   {
-    return modelToView(t, pos, null);
+    return modelToView(t, pos, Position.Bias.Forward);
   }
 
   public Rectangle modelToView(JTextComponent t, int pos, Position.Bias bias)
     throws BadLocationException
   {
-    return null;
+    return rootView.modelToView(pos, getVisibleEditorRect(), bias).getBounds();
   }
 
   public int viewToModel(JTextComponent t, Point pt)
@@ -331,4 +461,11 @@
     rootView.setView(view);
     view.setParent(rootView);
   }
+
+  protected void modelChanged()
+  {
+    ViewFactory factory = rootView.getViewFactory();
+    Element elem = textComponent.getDocument().getDefaultRootElement();
+    setView(factory.create(elem));
+  }
 }
Index: javax/swing/plaf/basic/BasicToggleButtonUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java,v
retrieving revision 1.7
diff -u -r1.7 BasicToggleButtonUI.java
--- javax/swing/plaf/basic/BasicToggleButtonUI.java     29 Apr 2004 07:00:34 
-0000      1.7
+++ javax/swing/plaf/basic/BasicToggleButtonUI.java     4 Sep 2004 17:00:14 
-0000
@@ -43,12 +43,10 @@
 
 public class BasicToggleButtonUI extends BasicButtonUI
 {
-  
-    public static ComponentUI createUI(final JComponent c)  {
-       return new BasicToggleButtonUI();
-    }    
-}
-
-
+  public static ComponentUI createUI(final JComponent component)
+  {
+    return new BasicToggleButtonUI();
+  }    
 
+}
 
Index: javax/swing/plaf/basic/BasicToolBarUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicToolBarUI.java,v
retrieving revision 1.3
diff -u -r1.3 BasicToolBarUI.java
--- javax/swing/plaf/basic/BasicToolBarUI.java  31 Jul 2004 22:56:54 -0000      
1.3
+++ javax/swing/plaf/basic/BasicToolBarUI.java  4 Sep 2004 17:00:14 -0000
@@ -157,10 +157,8 @@
 
   /**
    * This method creates a new BasicToolBarUI object for the given JToolBar.
-   *
-   * @param b The JToolBar to represent with this UI.
    */
-  public BasicToolBarUI(JToolBar b)
+  public BasicToolBarUI()
   {
     super();
   }
@@ -353,7 +351,7 @@
    */
   public static ComponentUI createUI(JComponent c)
   {
-    return new BasicToolBarUI((JToolBar) c);
+    return new BasicToolBarUI();
   }
 
   /**
Index: javax/swing/plaf/basic/ComboPopup.java
===================================================================
RCS file: javax/swing/plaf/basic/ComboPopup.java
diff -N javax/swing/plaf/basic/ComboPopup.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/basic/ComboPopup.java      4 Sep 2004 17:00:14 -0000
@@ -0,0 +1,46 @@
+/* ComboPopup.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;
+
+public interface ComboPopup
+{
+  void hide();
+  void show();
+  boolean isVisible();
+}
Index: javax/swing/text/AbstractDocument.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AbstractDocument.java,v
retrieving revision 1.9
diff -u -r1.9 AbstractDocument.java
--- javax/swing/text/AbstractDocument.java      31 Jul 2004 23:24:23 -0000      
1.9
+++ javax/swing/text/AbstractDocument.java      4 Sep 2004 17:00:14 -0000
@@ -38,6 +38,7 @@
 package javax.swing.text;
 
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.EventListener;
@@ -63,33 +64,37 @@
   public static final String ParagraphElementName = "paragraph";
   public static final String SectionElementName = "section";
   public static final String ElementNameAttribute = "$ename";
+
   Content content;
+  AttributeContext context;
   protected EventListenerList listenerList = new EventListenerList();
 
   protected AbstractDocument(Content doc)
   {
-    this(doc, null);
+    this(doc, StyleContext.getDefaultStyleContext());
   }
 
-  protected AbstractDocument(Content doc, AttributeContext context)
+  protected AbstractDocument(Content doc, AttributeContext ctx)
   {
     content = doc;
+    context = ctx;
   }
 
-  // these still need to be implemented by a derived class:
+  // These still need to be implemented by a derived class:
   public abstract Element getParagraphElement(int pos);
 
   public abstract Element getDefaultRootElement();
 
-  protected Element createBranchElement(Element parent, AttributeSet a)
+  protected Element createBranchElement(Element parent,
+                                       AttributeSet attributes)
   {
-    return new BranchElement(parent, a, 0, 0);
+    return new BranchElement(parent, attributes);
   }
 
-  protected Element createLeafElement(Element parent, AttributeSet a, int p0,
-                                      int p1)
+  protected Element createLeafElement(Element parent, AttributeSet attributes,
+                                     int start, int end)
   {
-    return new LeafElement(parent, a, p0, p1 - p0);
+    return new LeafElement(parent, attributes, start, end);
   }
 
   public Position createPosition(final int offset) throws BadLocationException
@@ -145,7 +150,7 @@
 
   protected AttributeContext getAttributeContext()
   {
-    return null;
+    return context;
   }
 
   public Element getBidiRootElement()
@@ -170,7 +175,13 @@
 
   public Position getEndPosition()
   {
-    return null;
+    return new Position() 
+      {        
+        public int getOffset() 
+        { 
+          return getLength(); 
+        } 
+      };
   }
 
   public int getLength()
@@ -190,12 +201,20 @@
 
   public Element[] getRootElements()
   {
-    return null;
+    Element[] elements = new Element[1];
+    elements[0] = getDefaultRootElement();
+    return elements;
   }
 
   public Position getStartPosition()
   {
-    return null;
+    return new Position() 
+      {        
+        public int getOffset() 
+        { 
+          return 0; 
+        } 
+      };
   }
 
   public String getText(int offset, int length) throws BadLocationException
@@ -203,34 +222,25 @@
     return content.getString(offset, length);
   }
 
-  public void getText(int offset, int length, Segment txt)
+  public void getText(int offset, int length, Segment segment)
     throws BadLocationException
   {
-    String a = getText(offset, length);
-
-    if (a == null)
-      {
-       txt.offset = 0;
-       txt.count = 0;
-       txt.array = new char[0];
-
-       return;
-      }
-
-    txt.offset = offset;
-    txt.count = length;
-
-    char[] chars = new char[a.length()];
-
-    a.getChars(0, a.length(), chars, 0);
-
-    txt.array = chars;
+    content.getChars(offset, length, segment);
   }
 
-  public void insertString(int offs, String str, AttributeSet a)
+  public void insertString(int offset, String text, AttributeSet attributes)
     throws BadLocationException
   {
-    content.insertString(offs, str);
+    // Just return when no text to insert was given.
+    if (text == null || text.length() == 0)
+      return;
+    
+    DefaultDocumentEvent event =
+      new DefaultDocumentEvent(offset, text.length(),
+                              DocumentEvent.EventType.INSERT);
+    content.insertString(offset, text);
+    insertUpdate(event, attributes);
+    fireInsertUpdate(event);
   }
 
   protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
@@ -255,6 +265,26 @@
 
   public void remove(int offset, int length) throws BadLocationException
   {
+    DefaultDocumentEvent event =
+      new DefaultDocumentEvent(offset, length,
+                              DocumentEvent.EventType.REMOVE);
+    removeUpdate(event);
+    content.remove(offset, length);
+    postRemoveUpdate(event);
+    fireRemoveUpdate(event);
+  }
+
+  /**
+   * Replaces some text in the document.
+   *
+   * @since 1.4
+   */
+  public void replace(int offset, int length, String text,
+                     AttributeSet attributes)
+    throws BadLocationException
+  {
+    remove(offset, length);
+    insertString(offset, text, attributes);
   }
 
   /**
@@ -375,27 +405,31 @@
   }
 
   public abstract class AbstractElement
-    implements Element, TreeNode, Serializable
+    implements Element, MutableAttributeSet, TreeNode, Serializable
   {
     private static final long serialVersionUID = 1265312733007397733L;
     int count;
     int offset;
-    AttributeSet attr;
-    Vector elts = new Vector();
-    String name;
-    Element parent;
-    Vector kids = new Vector();
+
+    AttributeSet attributes;
+
+    Element element_parent;
+    Vector element_children;
+
     TreeNode tree_parent;
+    Vector tree_children;
 
     public AbstractElement(Element p, AttributeSet s)
     {
-      parent = p;
-      attr = s;
+      element_parent = p;
+      attributes = s;
     }
 
+    // TreeNode implementation
+
     public Enumeration children()
     {
-      return kids.elements();
+      return Collections.enumeration(tree_children);
     }
 
     public boolean getAllowsChildren()
@@ -405,17 +439,17 @@
 
     public TreeNode getChildAt(int index)
     {
-      return (TreeNode) kids.elementAt(index);
+      return (TreeNode) tree_children.get(index);
     }
 
     public int getChildCount()
     {
-      return kids.size();
+      return tree_children.size();
     }
 
     public int getIndex(TreeNode node)
     {
-      return kids.indexOf(node);
+      return tree_children.indexOf(node);
     }
 
     public TreeNode getParent()
@@ -423,9 +457,94 @@
       return tree_parent;
     }
 
+    public abstract boolean isLeaf();
+
+
+    // MutableAttributeSet support
+
+    public void addAttribute(Object name, Object value)
+    {
+      attributes = getAttributeContext().addAttribute(attributes, name, value);
+    }
+
+    public void addAttributes(AttributeSet attrs)
+    {
+      attributes = getAttributeContext().addAttributes(attributes, attrs);
+    }
+
+    public void removeAttribute(Object name)
+    {
+      attributes = getAttributeContext().removeAttribute(attributes, name);
+    }
+
+    public void removeAttributes(AttributeSet attrs)
+    {
+      attributes = getAttributeContext().removeAttributes(attributes, attrs);
+    }
+
+    public void removeAttributes(Enumeration names)
+    {
+      attributes = getAttributeContext().removeAttributes(attributes, names);
+    }
+
+    public void setResolveParent(AttributeSet parent)
+    {
+      attributes = getAttributeContext().addAttribute(attributes, 
ResolveAttribute, parent);
+    }
+
+
+    // AttributeSet interface support
+
+    public boolean containsAttribute(Object name, Object value)
+    {
+      return attributes.containsAttribute(name, value);
+    }
+
+    public boolean containsAttributes(AttributeSet attrs)
+    {
+      return attributes.containsAttributes(attrs);
+    }
+
+    public AttributeSet copyAttributes()
+    {
+      return attributes.copyAttributes();
+    }
+
+    public Object getAttribute(Object key)
+    {
+      return attributes.getAttribute(key);
+    }
+
+    public int getAttributeCount()
+    {
+      return attributes.getAttributeCount();
+    }
+      
+    public Enumeration getAttributeNames()
+    {
+      return attributes.getAttributeNames();
+    }
+      
+    public AttributeSet getResolveParent()
+    {
+      return attributes.getResolveParent();
+    }
+
+    public boolean isDefined(Object attrName)
+    {
+      return attributes.isDefined(attrName);
+    }
+      
+    public boolean isEqual(AttributeSet attrs) 
+    {
+      return attributes.isEqual(attrs);
+    }
+
+    // Element interface support
+
     public AttributeSet getAttributes()
     {
-      return attr;
+      return attributes;
     }
 
     public Document getDocument()
@@ -435,21 +554,19 @@
 
     public Element getElement(int index)
     {
-      return (Element) elts.elementAt(index);
+      return (Element) element_children.get(index);
     }
 
     public String getName()
     {
-      return name;
+      return (String) getAttribute(NameAttribute);
     }
 
     public Element getParentElement()
     {
-      return parent;
+      return element_parent;
     }
 
-    public abstract boolean isLeaf();
-
     public abstract int getEndOffset();
 
     public abstract int getElementCount();
@@ -462,16 +579,12 @@
   public class BranchElement extends AbstractElement
   {
     private static final long serialVersionUID = -8595176318868717313L;
-    private int start;
-    private int end;
+    
     private Vector children = new Vector();
 
-    public BranchElement(Element parent, AttributeSet attributes, int start,
-                         int end)
+    public BranchElement(Element parent, AttributeSet attributes)
     {
       super(parent, attributes);
-      this.start = start;
-      this.end = end;
     }
 
     public Enumeration children()
@@ -486,6 +599,9 @@
 
     public Element getElement(int index)
     {
+      if (index < 0 || index >= children.size())
+       return null;
+
       return (Element) children.get(index);
     }
 
@@ -496,12 +612,20 @@
 
     public int getElementIndex(int offset)
     {
-      return children.indexOf(positionToElement(offset));
+      if (children.size() == 0)
+       return 0;
+      
+      Element element = positionToElement(offset);
+
+      if (element == null)
+       return 0;
+      
+      return children.indexOf(element);
     }
 
     public int getEndOffset()
     {
-      return end;
+      return ((Element) children.lastElement()).getEndOffset();
     }
 
     public String getName()
@@ -511,7 +635,7 @@
 
     public int getStartOffset()
     {
-      return start;
+      return ((Element) children.firstElement()).getStartOffset();
     }
 
     public boolean isLeaf()
@@ -554,8 +678,18 @@
     implements DocumentEvent
   {
     private static final long serialVersionUID = -7406103236022413522L;
-    public int len;
-    public int off;
+    
+    private int offset;
+    private int length;
+    private DocumentEvent.EventType type;
+
+    public DefaultDocumentEvent(int offset, int length,
+                               DocumentEvent.EventType type)
+    {
+      this.offset = offset;
+      this.length = length;
+      this.type = type;
+    }
 
     public Document getDocument()
     {
@@ -564,17 +698,17 @@
 
     public int getLength()
     {
-      return len;
+      return length;
     }
 
     public int getOffset()
     {
-      return off;
+      return offset;
     }
 
     public DocumentEvent.EventType getType()
     {
-      return null;
+      return type;
     }
 
     public DocumentEvent.ElementChange getChange(Element elem)
@@ -584,8 +718,43 @@
   }
 
   public static class ElementEdit extends AbstractUndoableEdit
+    implements DocumentEvent.ElementChange
   {
     private static final long serialVersionUID = -1216620962142928304L;
+
+    private Element elem;
+    private int index;
+    private Element[] removed;
+    private Element[] added;
+    
+    public ElementEdit(Element elem, int index,
+                      Element[] removed, Element[] added)
+    {
+      this.elem = elem;
+      this.index = index;
+      this.removed = removed;
+      this.added = added;
+    }
+
+    public Element[] getChildrenAdded()
+    {
+      return added;
+    }
+    
+    public Element[] getChildrenRemoved()
+    {
+      return removed;
+    }
+
+    public Element getElement()
+    {
+      return elem;
+    }
+
+    public int getIndex()
+    {
+      return index;
+    }
   }
 
   public class LeafElement extends AbstractElement
Index: javax/swing/text/AttributeSet.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/AttributeSet.java,v
retrieving revision 1.5
diff -u -r1.5 AttributeSet.java
--- javax/swing/text/AttributeSet.java  31 Jul 2004 23:24:23 -0000      1.5
+++ javax/swing/text/AttributeSet.java  4 Sep 2004 17:00:14 -0000
@@ -57,6 +57,9 @@
   {
   }
   
+  static Object NameAttribute = StyleConstants.NameAttribute;
+  static Object ResolveAttribute = StyleConstants.ResolveAttribute;
+
   boolean containsAttribute(Object name, Object value);
   boolean containsAttributes(AttributeSet attributes);
   AttributeSet copyAttributes();
Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.7
diff -u -r1.7 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java  22 Jul 2004 19:45:39 -0000      1.7
+++ javax/swing/text/DefaultCaret.java  4 Sep 2004 17:00:14 -0000
@@ -61,15 +61,15 @@
   protected ChangeEvent changeEvent = new ChangeEvent(this);
   protected EventListenerList listenerList = new EventListenerList();
   
-  Color color = new Color(0, 0, 0);
-  JTextComponent parent;
-  Point magic = null;
-  int mark = 0;
-  boolean vis_sel = true;
-  int blink = 500;
-  int dot = 0;
-  boolean vis = true;
-
+  private JTextComponent textComponent;
+  
+  private boolean selectionVisible = true;
+  private int blinkRate = 0;
+  private int dot = 0;
+  private int mark = 0;
+  private Point magicCaretPosition = null;
+  private boolean visible = true;
+  private Object highlightEntry;
 
   public void mouseDragged(MouseEvent event)
   {
@@ -117,27 +117,29 @@
 
   public void deinstall(JTextComponent c)
   {
-    parent.removeFocusListener(this);
-    parent.removeMouseListener(this);
-    parent = null;
+    textComponent.removeFocusListener(this);
+    textComponent.removeMouseListener(this);
+    textComponent.removeMouseMotionListener(this);
+    textComponent = null;
   }
 
   public void install(JTextComponent c)
   {
-    parent.addFocusListener(this);
-    parent.addMouseListener(this);
-    parent = c;
+    textComponent = c;
+    textComponent.addFocusListener(this);
+    textComponent.addMouseListener(this);
+    textComponent.addMouseMotionListener(this);
     repaint();
   }
 
   public void setMagicCaretPosition(Point p)
   {
-    magic = p;
+    magicCaretPosition = p;
   }
 
   public Point getMagicCaretPosition()
   {
-    return magic;
+    return magicCaretPosition;
   }
 
   public int getMark()
@@ -145,27 +147,92 @@
     return mark;
   }
 
+  private void handleHighlight()
+  {
+    Highlighter highlighter = textComponent.getHighlighter();
+    
+    if (highlighter == null)
+      return;
+    
+    int p0 = Math.min(dot, mark);
+    int p1 = Math.max(dot, mark);
+    
+    if (selectionVisible && p0 != p1)
+      {
+       try
+         {
+           if (highlightEntry == null)
+             highlightEntry = highlighter.addHighlight(p0, p1, 
getSelectionPainter());
+           else
+             highlighter.changeHighlight(highlightEntry, p0, p1);
+         }
+       catch (BadLocationException e)
+         {
+           // This should never happen.
+           throw new InternalError();
+         }
+      }
+    else
+      {
+       if (highlightEntry != null)
+         {
+           highlighter.removeHighlight(highlightEntry);
+           highlightEntry = null;
+         }
+      }
+  }
+
   public void setSelectionVisible(boolean v)
   {
-    vis_sel = v;
+    if (selectionVisible == v)
+      return;
+    
+    selectionVisible = v;
+    handleHighlight();
     repaint();
   }
 
   public boolean isSelectionVisible()
   {
-    return vis_sel;
+    return selectionVisible;
   }
 
   protected final void repaint()
   {
-    if (parent != null)
-      parent.repaint();
+    if (textComponent != null)
+      textComponent.repaint();
   }
 
   public void paint(Graphics g)
   {
-    g.setColor(color);
-    g.drawLine(x, y, x, y + height);
+    if (textComponent == null)
+      return;
+
+    int dot = getDot();
+    Rectangle rect = null;
+
+    try
+      {
+       rect = textComponent.modelToView(dot);
+      }
+    catch (BadLocationException e)
+      {
+       // This should never happen as dot should be always valid.
+       return;
+      }
+
+    if (rect == null)
+      return;
+    
+    // First we need to delete the old caret.
+    // FIXME: Implement deleting of old caret.
+    
+    // Now draw the caret on the new position if visible.
+    if (visible)
+      {
+       g.setColor(textComponent.getCaretColor());
+       g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height);
+      }
   }
 
   public EventListener[] getListeners(Class listenerType)
@@ -198,17 +265,17 @@
 
   protected final JTextComponent getComponent()
   {
-    return parent;
+    return textComponent;
   }
   
   public int getBlinkRate()
   {
-    return blink;
+    return blinkRate;
   }
 
   public void setBlinkRate(int rate)
   {
-    blink = rate;
+    blinkRate = rate;
   }
 
   public int getDot()
@@ -218,23 +285,32 @@
 
   public void moveDot(int dot)
   {
-    setDot(dot);
+    this.dot = dot;
+    handleHighlight();
+    repaint();
   }
 
   public void setDot(int dot)
   {
     this.dot = dot;
+    this.mark = dot;
+    handleHighlight();
     repaint();
   }
 
   public boolean isVisible()
   {
-    return vis;
+    return visible;
   }
 
   public void setVisible(boolean v)
   {
-    vis = v;
+    visible = v;
     repaint();
   }
+
+  protected Highlighter.HighlightPainter getSelectionPainter()
+  {
+    return DefaultHighlighter.DefaultPainter;
+  }
 }
Index: javax/swing/text/DefaultEditorKit.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultEditorKit.java,v
retrieving revision 1.7
diff -u -r1.7 DefaultEditorKit.java
--- javax/swing/text/DefaultEditorKit.java      31 Jul 2004 23:24:23 -0000      
1.7
+++ javax/swing/text/DefaultEditorKit.java      4 Sep 2004 17:00:15 -0000
@@ -64,6 +64,105 @@
     }
   }
 
+  public static class CopyAction 
+    extends TextAction
+  {
+    public CopyAction()
+    {
+      super(copyAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class CutAction 
+    extends TextAction
+  {
+    public CutAction()
+    {
+      super(cutAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class DefaultKeyTypedAction 
+    extends TextAction
+  {
+    public DefaultKeyTypedAction()
+    {
+      super(defaultKeyTypedAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+      JTextComponent t = getTextComponent(event);
+      if (t != null)
+        {
+          try
+            {
+              t.getDocument().insertString(t.getCaret().getDot(), 
event.getActionCommand(), null);
+              t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+                                           
t.getDocument().getEndPosition().getOffset()));
+              t.repaint();
+            }
+          catch (BadLocationException be)
+            {
+              // FIXME: we're not authorized to throw this.. swallow it?
+            }
+        }
+    }
+  }
+
+  public static class InsertBreakAction 
+    extends TextAction
+  {
+    public InsertBreakAction()
+    {
+      super(insertBreakAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class InsertContentAction 
+    extends TextAction
+  {
+    public InsertContentAction()
+    {
+      super(insertContentAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class InsertTabAction 
+    extends TextAction
+  {
+    public InsertTabAction()
+    {
+      super(insertTabAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
+  public static class PasteAction 
+    extends TextAction
+  {
+    public PasteAction()
+    {
+      super(pasteAction);
+    }
+    public void actionPerformed(ActionEvent event)
+    {
+    }
+  }
+
   private static final long serialVersionUID = 9017245433028523428L;
   
   public static final String backwardAction = "caret-backward";
@@ -121,6 +220,113 @@
   {
   }
 
+  private static Action[] defaultActions = 
+  new Action[] {
+    new BeepAction(),
+    new CopyAction(),
+    new CutAction(),
+    new DefaultKeyTypedAction(),
+    new InsertBreakAction(),
+    new InsertContentAction(),
+    new InsertTabAction(),
+    new PasteAction(),
+    new TextAction(deleteNextCharAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            try
+              {
+                int pos = t.getCaret().getDot();
+                if (pos < t.getDocument().getEndPosition().getOffset())
+                  {
+                    t.getDocument().remove(t.getCaret().getDot(), 1);
+                    t.repaint();
+                  }
+              }
+            catch (BadLocationException e)
+              {
+                // FIXME: we're not authorized to throw this.. swallow it?
+              }
+          }
+      }
+    },
+    new TextAction(deletePrevCharAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            try
+              {
+                int pos = t.getCaret().getDot();
+                if (pos > t.getDocument().getStartPosition().getOffset())
+                  {
+                    t.getDocument().remove(pos - 1, 1);
+                    t.getCaret().setDot(pos - 1);
+                    t.repaint();
+                  }
+              }
+            catch (BadLocationException e)
+              {
+                // FIXME: we're not authorized to throw this.. swallow it?
+              }
+          }
+      }
+    },
+    new TextAction(backwardAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().setDot(Math.max(t.getCaret().getDot() - 1,
+                                         
t.getDocument().getStartPosition().getOffset()));
+          }
+      }
+    },
+    new TextAction(forwardAction) 
+    { 
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().setDot(Math.min(t.getCaret().getDot() + 1,
+                                         
t.getDocument().getEndPosition().getOffset()));
+          }
+      }
+    },
+    new TextAction(selectionBackwardAction)
+    {
+      public void actionPerformed(ActionEvent event)
+      {
+       JTextComponent t = getTextComponent(event);
+       if (t != null)
+         {
+           t.getCaret().moveDot(Math.max(t.getCaret().getDot() - 1,
+                                         
t.getDocument().getStartPosition().getOffset()));
+         }
+      }
+    },
+    new TextAction(selectionForwardAction)
+    {
+      public void actionPerformed(ActionEvent event)
+      {
+        JTextComponent t = getTextComponent(event);
+        if (t != null)
+          {
+            t.getCaret().moveDot(Math.min(t.getCaret().getDot() + 1,
+                                          
t.getDocument().getEndPosition().getOffset()));
+          }
+      }
+    },
+  };
+
   /**
    * Called when the kit is being removed from the JEditorPane.
    */
@@ -134,7 +340,7 @@
 
   public Caret createCaret()
   {
-    return null;
+    return new DefaultCaret();
   }
 
   public Document createDefaultDocument()
@@ -144,7 +350,7 @@
 
   public Action[] getActions()
   {
-    return null;
+    return defaultActions;
   }
 
   public String getContentType()
Index: javax/swing/text/DefaultHighlighter.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/text/DefaultHighlighter.java,v
retrieving revision 1.1
diff -u -r1.1 DefaultHighlighter.java
--- javax/swing/text/DefaultHighlighter.java    22 Jul 2004 19:45:39 -0000      
1.1
+++ javax/swing/text/DefaultHighlighter.java    4 Sep 2004 17:00:15 -0000
@@ -38,7 +38,9 @@
 
 package javax.swing.text;
 
+import java.awt.Color;
 import java.awt.Graphics;
+import java.awt.Rectangle;
 import java.awt.Shape;
 import java.util.Vector;
 
@@ -48,6 +50,87 @@
 
 public class DefaultHighlighter extends LayeredHighlighter
 {
+  public static class DefaultHighlightPainter
+    extends LayerPainter
+  {
+    private Color color;
+    
+    public DefaultHighlightPainter(Color c)
+    {
+      super();
+      color = c;
+    }
+
+    public Color getColor()
+    {
+      return color;
+    }
+
+    private void paintHighlight(Graphics g, Rectangle rect)
+    {
+      g.fillRect(rect.x, rect.y, rect.width, rect.height);
+    }
+    
+    public void paint(Graphics g, int p0, int p1, Shape bounds,
+                     JTextComponent c)
+    {
+      Rectangle r0 = null;
+      Rectangle r1 = null;
+      Rectangle rect = bounds.getBounds();
+      
+      try
+       {
+         r0 = c.modelToView(p0);
+         r1 = c.modelToView(p1);
+       }
+      catch (BadLocationException e)
+        {
+         // This should never occur.
+          return;
+       }
+
+      if (r0 == null || r1 == null)
+       return;
+
+      if (color == null)
+       g.setColor(c.getSelectionColor());
+      else
+       g.setColor(color);
+
+      // Check if only one line to highlight.
+      if (r0.y == r1.y)
+       {
+         r0.width = r1.x - r0.x;
+         paintHighlight(g, r0);
+         return;
+       }
+
+      // First line, from p0 to end-of-line.
+      r0.width = rect.x + rect.width - r0.x;
+      paintHighlight(g, r0);
+      
+      // FIXME: All the full lines in between, if any (assumes that all lines
+      // have the same height -- not a good assumption with 
JEditorPane/JTextPane).
+      r0.y += r0.height;
+      r0.x = rect.x;
+
+      while (r0.y < r1.y)
+       {
+         paintHighlight(g, r0);
+         r0.y += r0.height;
+       }
+
+      // Last line, from beginnin-of-line to p1.
+      paintHighlight(g, r1);
+    }
+
+    public Shape paintLayer(Graphics g, int p0, int p1, Shape bounds,
+                           JTextComponent c, View view)
+    {
+      throw new InternalError();
+    }
+  }
+  
   private class HighlightEntry
   {
     int p0;
@@ -77,6 +160,12 @@
     }
   }
 
+  /**
+   * @specnote final as of 1.4
+   */
+  public static final LayeredHighlighter.LayerPainter DefaultPainter =
+    new DefaultHighlightPainter(null);
+  
   private JTextComponent textComponent;
   private Vector highlights = new Vector();
   
@@ -146,5 +235,16 @@
 
   public void paint(Graphics g)
   {
+    // Check if there are any highlights.
+    if (highlights.size() == 0)
+      return;
+    
+    Shape bounds = textComponent.getBounds();
+    
+    for (int index = 0; index < highlights.size(); ++index)
+      {
+       HighlightEntry entry = (HighlightEntry) highlights.get(index);
+       entry.painter.paint(g, entry.p0, entry.p1, bounds, textComponent);
+      }
   }
 }
Index: javax/swing/text/FieldView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/FieldView.java,v
retrieving revision 1.1
diff -u -r1.1 FieldView.java
--- javax/swing/text/FieldView.java     22 Jul 2004 19:45:39 -0000      1.1
+++ javax/swing/text/FieldView.java     4 Sep 2004 17:00:15 -0000
@@ -90,8 +90,14 @@
     return axis = axis == X_AXIS ? 1 : 0;
   }
   
+  public Shape modelToView(int pos, Shape a, Position.Bias bias)
+    throws BadLocationException
+  {
+    return super.modelToView(pos, a, bias);
+  }
+  
   public void paint(Graphics g, Shape s)
   {
-    drawLine(0, g, 0, 0);
+    super.paint(g, s);
   }
 }
Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v
retrieving revision 1.13
diff -u -r1.13 JTextComponent.java
--- javax/swing/text/JTextComponent.java        22 Jul 2004 19:45:39 -0000      
1.13
+++ javax/swing/text/JTextComponent.java        4 Sep 2004 17:00:15 -0000
@@ -46,13 +46,20 @@
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.event.InputMethodListener;
+import java.awt.event.KeyEvent;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
 
 import javax.accessibility.Accessible;
 import javax.accessibility.AccessibleContext;
 import javax.accessibility.AccessibleRole;
 import javax.accessibility.AccessibleStateSet;
 import javax.accessibility.AccessibleText;
+import javax.swing.Action;
+import javax.swing.ActionMap;
 import javax.swing.Icon;
+import javax.swing.InputMap;
 import javax.swing.JComponent;
 import javax.swing.JViewport;
 import javax.swing.KeyStroke;
@@ -62,6 +69,8 @@
 import javax.swing.event.CaretListener;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
+import javax.swing.plaf.ActionMapUIResource;
+import javax.swing.plaf.InputMapUIResource;
 import javax.swing.plaf.TextUI;
 
 
@@ -283,11 +292,505 @@
     }
   }
 
+  /**
+   * According to <a
+   * 
href="http://java.sun.com/products/jfc/tsc/special_report/kestrel/keybindings.html";>this
+   * report</a>, a pair of private classes wraps a address@hidden
+   * javax.swing.text.Keymap} in the new address@hidden InputMap} / 
address@hidden
+   * ActionMap} interfaces, such that old Keymap-using code can make use of
+   * the new framework.</p>
+   *
+   * <p>A little bit of experimentation with these classes reveals the 
following
+   * structure:
+   *
+   * <ul>
+   *
+   * <li>KeymapWrapper extends address@hidden InputMap} and holds a reference 
to
+   * the underlying address@hidden Keymap}.</li>
+   *
+   * <li>KeymapWrapper maps address@hidden KeyStroke} objects to 
address@hidden Action}
+   * objects, by delegation to the underlying address@hidden Keymap}.</li>
+   *
+   * <li>KeymapActionMap extends address@hidden ActionMap} also holds a 
reference to
+   * the underlying address@hidden Keymap} but only appears to use it for 
listing 
+   * its keys. </li>
+   *
+   * <li>KeymapActionMap maps all address@hidden Action} objects to
+   * <em>themselves</em>, whether they exist in the underlying address@hidden
+   * Keymap} or not, and passes other objects to the parent address@hidden
+   * ActionMap} for resolving.
+   *
+   * </ul>
+   */
+
+  private class KeymapWrapper extends InputMap
+  {
+    Keymap map;
+
+    public KeymapWrapper(Keymap k)
+    {
+      map = k;
+    }
+
+    public int size()
+    {
+      return map.getBoundKeyStrokes().length + super.size();
+    }
+
+    public Object get(KeyStroke ks)
+    {
+      Action mapped = null;
+      Keymap m = map;
+      while(mapped == null && m != null)
+        {
+          mapped = m.getAction(ks);
+          if (mapped == null && ks.getKeyEventType() == KeyEvent.KEY_TYPED)
+            mapped = m.getDefaultAction();
+          if (mapped == null)
+            m = m.getResolveParent();
+        }
+
+      if (mapped == null)
+        return super.get(ks);
+      else
+        return mapped;
+    }
+
+    public KeyStroke[] keys()
+    {
+      KeyStroke[] superKeys = super.keys();
+      KeyStroke[] mapKeys = map.getBoundKeyStrokes(); 
+      KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
+    }
+
+    public KeyStroke[] allKeys()
+    {
+      KeyStroke[] superKeys = super.allKeys();
+      KeyStroke[] mapKeys = map.getBoundKeyStrokes(); 
+      KeyStroke[] bothKeys = new KeyStroke[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
+    }
+  }
+
+  private class KeymapActionMap extends ActionMap
+  {
+    Keymap map;
+
+    public KeymapActionMap(Keymap k)
+    {
+      map = k;
+    }
+
+    public Action get(Object cmd)
+    {
+      if (cmd instanceof Action)
+        return (Action) cmd;
+      else
+        return super.get(cmd);
+    }
+
+    public int size()
+    {
+      return map.getBoundKeyStrokes().length + super.size();
+    }
+
+    public Object[] keys() 
+    {
+      Object[] superKeys = super.keys();
+      Object[] mapKeys = map.getBoundKeyStrokes(); 
+      Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;      
+    }
+
+    public Object[] allKeys()
+    {
+      Object[] superKeys = super.allKeys();
+      Object[] mapKeys = map.getBoundKeyStrokes(); 
+      Object[] bothKeys = new Object[superKeys.length + mapKeys.length];
+      for (int i = 0; i < superKeys.length; ++i)
+        bothKeys[i] = superKeys[i];
+      for (int i = 0; i < mapKeys.length; ++i)
+        bothKeys[i + superKeys.length] = mapKeys[i];
+      return bothKeys;
+    }
+
+  }
+
+  static class DefaultKeymap implements Keymap
+  {
+    String name;
+    Keymap parent;
+    Hashtable map;
+    Action defaultAction;
+
+    public DefaultKeymap(String name)
+    {
+      this.name = name;
+      this.map = new Hashtable();
+    }
+
+    public void addActionForKeyStroke(KeyStroke key, Action a)
+    {
+      map.put(key, a);
+    }
+
+    /**
+     * Looks up a KeyStroke either in the current map or the parent Keymap;
+     * does <em>not</em> return the default action if lookup fails.
+     *
+     * @param key The KeyStroke to look up an Action for.
+     *
+     * @return The mapping for <code>key</code>, or <code>null</code>
+     * if no mapping exists in this Keymap or any of its parents.
+     */
+    public Action getAction(KeyStroke key)
+    {
+      if (map.containsKey(key))
+        return (Action) map.get(key);
+      else if (parent != null)
+        return parent.getAction(key);
+      else
+        return null;
+    }
+
+    public Action[] getBoundActions()
+    {
+      Action [] ret = new Action[map.size()];
+      Enumeration e = map.elements();
+      int i = 0;
+      while (e.hasMoreElements())
+        {
+          ret[i++] = (Action) e.nextElement();
+        }
+      return ret;
+    }
+
+    public KeyStroke[] getBoundKeyStrokes()
+    {
+      KeyStroke [] ret = new KeyStroke[map.size()];
+      Enumeration e = map.keys();
+      int i = 0;
+      while (e.hasMoreElements())
+        {
+          ret[i++] = (KeyStroke) e.nextElement();
+        }
+      return ret;
+    }
+
+    public Action getDefaultAction()
+    {
+      return defaultAction;
+    }
+
+    public KeyStroke[] getKeyStrokesForAction(Action a)
+    {
+      int i = 0;
+      Enumeration e = map.keys();
+      while (e.hasMoreElements())
+        {
+          if (map.get(e.nextElement()).equals(a))
+            ++i;
+        }
+      KeyStroke [] ret = new KeyStroke[i];
+      i = 0;
+      e = map.keys();
+      while (e.hasMoreElements())
+        {          
+          KeyStroke k = (KeyStroke) e.nextElement();
+          if (map.get(k).equals(a))
+            ret[i++] = k;            
+        }
+      return ret;
+    }
+
+    public String getName()
+    {
+      return name;
+    }
+
+    public Keymap getResolveParent()
+    {
+      return parent;
+    }
+
+    public boolean isLocallyDefined(KeyStroke key)
+    {
+      return map.containsKey(key);
+    }
+
+    public void removeBindings()
+    {
+      map.clear();
+    }
+
+    public void removeKeyStrokeBinding(KeyStroke key)
+    {
+      map.remove(key);
+    }
+
+    public void setDefaultAction(Action a)
+    {
+      defaultAction = a;
+    }
+
+    public void setResolveParent(Keymap p)
+    {
+      parent = p;
+    }
+
+  }
+
   private static final long serialVersionUID = -8796518220218978795L;
   
   public static final String DEFAULT_KEYMAP = "default";
   public static final String FOCUS_ACCELERATOR_KEY = "focusAcceleratorKey";
 
+  private static Hashtable keymaps = new Hashtable();
+  private Keymap keymap;
+  
+  /**
+   * Get a Keymap from the global keymap table, by name.
+   *
+   * @param n The name of the Keymap to look up
+   *
+   * @return A Keymap associated with the provided name, or
+   * <code>null</code> if no such Keymap exists
+   *
+   * @see #addKeymap()
+   * @see #removeKeymap()
+   * @see #keymaps
+   */
+  public static Keymap getKeymap(String n)
+  {
+    return (Keymap) keymaps.get(n);
+  }
+
+  /**
+   * Remove a Keymap from the global Keymap table, by name.
+   *
+   * @param n The name of the Keymap to remove
+   *
+   * @return The keymap removed from the global table
+   *
+   * @see #addKeymap()
+   * @see #getKeymap()
+   * @see #keymaps
+   */  
+  public static Keymap removeKeymap(String n)
+  {
+    Keymap km = (Keymap) keymaps.get(n);
+    keymaps.remove(n);
+    return km;
+  }
+
+  /**
+   * Create a new Keymap with a specific name and parent, and add the new
+   * Keymap to the global keymap table. The name may be <code>null</code>,
+   * in which case the new Keymap will <em>not</em> be added to the global
+   * Keymap table. The parent may also be <code>null</code>, which is
+   * harmless.
+   * 
+   * @param n The name of the new Keymap, or <code>null</code>
+   * @param parent The parent of the new Keymap, or <code>null</code>
+   *
+   * @return The newly created Keymap
+   *
+   * @see #removeKeymap()
+   * @see #getKeymap()
+   * @see #keymaps
+   */
+  public static Keymap addKeymap(String n, Keymap parent)
+  {
+    Keymap k = new DefaultKeymap(n);
+    k.setResolveParent(parent);
+    if (n != null)
+      keymaps.put(n, k);
+    return k;
+  }
+
+  /**
+   * Get the current Keymap of this component.
+   *
+   * @return The component's current Keymap
+   *
+   * @see #setKeymap()
+   * @see #keymap
+   */
+  Keymap getKeymap() 
+  {
+    return keymap;
+  }
+
+  /**
+   * Set the current Keymap of this component, installing appropriate
+   * address@hidden KeymapWrapper} and address@hidden KeymapActionMap} objects 
in the
+   * address@hidden InputMap} and address@hidden ActionMap} parent chains, 
respectively,
+   * and fire a property change event with name <code>"keymap"</code>.
+   *
+   * @see #getKeymap()
+   * @see #keymap
+   */
+  public void setKeymap(Keymap k) 
+  {
+
+    // phase 1: replace the KeymapWrapper entry in the InputMap chain.
+    // the goal here is to always maintain the following ordering:
+    //
+    //   [InputMap]? -> [KeymapWrapper]? -> [InputMapUIResource]*
+    // 
+    // that is to say, component-specific InputMaps need to remain children
+    // of Keymaps, and Keymaps need to remain children of UI-installed
+    // InputMaps (and the order of each group needs to be preserved, of
+    // course).
+    
+    KeymapWrapper kw = (k == null ? null : new KeymapWrapper(k));
+    InputMap childInputMap = getInputMap(JComponent.WHEN_FOCUSED);
+    if (childInputMap == null)
+      setInputMap(JComponent.WHEN_FOCUSED, kw);
+    else
+      {
+        while (childInputMap.getParent() != null 
+               && !(childInputMap.getParent() instanceof KeymapWrapper)
+               && !(childInputMap.getParent() instanceof InputMapUIResource))
+          childInputMap = childInputMap.getParent();
+
+        // option 1: there is nobody to replace at the end of the chain
+        if (childInputMap.getParent() == null)
+          childInputMap.setParent(kw);
+        
+        // option 2: there is already a KeymapWrapper in the chain which
+        // needs replacing (possibly with its own parents, possibly without)
+        else if (childInputMap.getParent() instanceof KeymapWrapper)
+          {
+            if (kw == null)
+              childInputMap.setParent(childInputMap.getParent().getParent());
+            else
+              {
+                kw.setParent(childInputMap.getParent().getParent());
+                childInputMap.setParent(kw);
+              }
+          }
+
+        // option 3: there is an InputMapUIResource in the chain, which marks
+        // the place where we need to stop and insert ourselves
+        else if (childInputMap.getParent() instanceof InputMapUIResource)
+          {
+            if (kw != null)
+              {
+                kw.setParent(childInputMap.getParent());
+                childInputMap.setParent(kw);
+              }
+          }
+      }
+
+    // phase 2: replace the KeymapActionMap entry in the ActionMap chain
+
+    KeymapActionMap kam = (k == null ? null : new KeymapActionMap(k));
+    ActionMap childActionMap = getActionMap();
+    if (childActionMap == null)
+      setActionMap(kam);
+    else
+      {
+        while (childActionMap.getParent() != null 
+               && !(childActionMap.getParent() instanceof KeymapActionMap)
+               && !(childActionMap.getParent() instanceof ActionMapUIResource))
+          childActionMap = childActionMap.getParent();
+
+        // option 1: there is nobody to replace at the end of the chain
+        if (childActionMap.getParent() == null)
+          childActionMap.setParent(kam);
+        
+        // option 2: there is already a KeymapActionMap in the chain which
+        // needs replacing (possibly with its own parents, possibly without)
+        else if (childActionMap.getParent() instanceof KeymapActionMap)
+          {
+            if (kam == null)
+              childActionMap.setParent(childActionMap.getParent().getParent());
+            else
+              {
+                kam.setParent(childActionMap.getParent().getParent());
+                childActionMap.setParent(kam);
+              }
+          }
+
+        // option 3: there is an ActionMapUIResource in the chain, which marks
+        // the place where we need to stop and insert ourselves
+        else if (childActionMap.getParent() instanceof ActionMapUIResource)
+          {
+            if (kam != null)
+              {
+                kam.setParent(childActionMap.getParent());
+                childActionMap.setParent(kam);
+              }
+          }
+      }
+
+    // phase 3: update the explicit keymap field
+
+    Keymap old = keymap;
+    keymap = k;
+    firePropertyChange("keymap", old, k);
+  }
+
+  /**
+   * Resolves a set of bindings against a set of actions and inserts the
+   * results into a address@hidden Keymap}. Specifically, for each provided 
binding
+   * <code>b</code>, if there exists a provided action <code>a</code> such
+   * that <code>a.getValue(Action.NAME) == b.ActionName</code> then an
+   * entry is added to the Keymap mapping <code>b</code> to
+   * </code>a</code>.
+   *
+   * @param map The Keymap to add new mappings to
+   * @param bindings The set of bindings to add to the Keymap
+   * @param actions The set of actions to resolve binding names against
+   *
+   * @see Action#NAME
+   * @see Action#getValue()
+   * @see KeyBinding#ActionName
+   */
+  public static void loadKeymap(Keymap map, 
+                                JTextComponent.KeyBinding[] bindings, 
+                                Action[] actions)
+  {
+    Hashtable acts = new Hashtable(actions.length);
+    for (int i = 0; i < actions.length; ++i)
+      acts.put(actions[i].getValue(Action.NAME), actions[i]);
+    for (int i = 0; i < bindings.length; ++i)
+      if (acts.containsKey(bindings[i].actionName))
+        map.addActionForKeyStroke(bindings[i].key, (Action) 
acts.get(bindings[i].actionName));
+  }
+
+  /**
+   * Returns the set of available Actions this component's associated
+   * editor can run.  Equivalent to calling
+   * <code>getUI().getEditorKit().getActions()</code>. This set of Actions
+   * is a reasonable value to provide as a parameter to address@hidden
+   * #loadKeymap()}, when resolving a set of address@hidden #KeyBinding} 
objects
+   * against this component.
+   *
+   * @return The set of available Actions on this component's address@hidden 
EditorKit}
+   *
+   * @see TextUI#getEditorKit()
+   * @see EditorKit#getActions()
+   */
+  public Action[] getActions()
+  {
+    return getUI().getEditorKit(this).getActions();
+  }
+    
   private Document doc;
   private Caret caret;
   private Highlighter highlighter;
@@ -296,19 +799,47 @@
   private Color selectedTextColor;
   private Color selectionColor;
   private boolean editable;
+  private Insets margin;
 
   /**
    * Creates a new <code>JTextComponent</code> instance.
    */
   public JTextComponent()
   {
+    Keymap defkeymap = getKeymap(DEFAULT_KEYMAP);
+    boolean creatingKeymap = false;
+    if (defkeymap == null)
+      {
+        defkeymap = addKeymap(DEFAULT_KEYMAP, null);
+        defkeymap.setDefaultAction(new 
DefaultEditorKit.DefaultKeyTypedAction());
+        creatingKeymap = true;
+      }
+
+    setFocusable(true);
     enableEvents(AWTEvent.KEY_EVENT_MASK);
     updateUI();
-  }
-
-  public void setDocument(Document s)
-  {
-    doc = s;
+    
+    // need to do this after updateUI()
+    if (creatingKeymap)
+      loadKeymap(defkeymap, 
+                 new KeyBinding[] { 
+                   new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0),
+                                  DefaultEditorKit.backwardAction),
+                   new KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0),
+                                  DefaultEditorKit.forwardAction),
+                   new KeyBinding(KeyStroke.getKeyStroke("typed \b"),
+                                  DefaultEditorKit.deletePrevCharAction),
+                   new KeyBinding(KeyStroke.getKeyStroke("typed \u007f"),
+                                  DefaultEditorKit.deleteNextCharAction)       
            
+                 },
+                 getActions());
+  }
+
+  public void setDocument(Document newDoc)
+  {
+    Document oldDoc = doc;
+    doc = newDoc;
+    firePropertyChange("document", oldDoc, newDoc);
     revalidate();
     repaint();
   }
@@ -328,18 +859,22 @@
     return null;
   }
 
+  public void setMargin(Insets m)
+  {
+    margin = m;
+  }
+
   public Insets getMargin()
   {
-    // FIXME: Not implemented.
-    return null;
+    return margin;
   }
 
   public void setText(String text)
   {
     try
       {
-       getDocument().remove(0, doc.getLength());
-       getDocument().insertString(0, text, null);
+       doc.remove(0, doc.getLength());
+       doc.insertString(0, text, null);
       }
     catch (BadLocationException e)
       {
@@ -488,8 +1023,16 @@
    */
   public void setCaret(Caret newCaret)
   {
-    firePropertyChange("caret", caret, newCaret);
+    if (caret != null)
+      caret.deinstall(this);
+    
+    Caret oldCaret = caret;
     caret = newCaret;
+
+    if (caret != null)
+      caret.install(this);
+    
+    firePropertyChange("caret", oldCaret, newCaret);
   }
 
   public Color getCaretColor()
@@ -499,8 +1042,9 @@
 
   public void setCaretColor(Color newColor)
   {
-    firePropertyChange("caretColor", caretColor, newColor);
+    Color oldCaretColor = caretColor;
     caretColor = newColor;
+    firePropertyChange("caretColor", oldCaretColor, newColor);
   }
 
   public Color getDisabledTextColor()
@@ -510,8 +1054,9 @@
 
   public void setDisabledTextColor(Color newColor)
   {
-    firePropertyChange("disabledTextColor", caretColor, newColor);
+    Color oldColor = disabledTextColor;
     disabledTextColor = newColor;
+    firePropertyChange("disabledTextColor", oldColor, newColor);
   }
 
   public Color getSelectedTextColor()
@@ -521,8 +1066,9 @@
 
   public void setSelectedTextColor(Color newColor)
   {
-    firePropertyChange("selectedTextColor", caretColor, newColor);
+    Color oldColor = selectedTextColor;
     selectedTextColor = newColor;
+    firePropertyChange("selectedTextColor", oldColor, newColor);
   }
 
   public Color getSelectionColor()
@@ -532,8 +1078,9 @@
 
   public void setSelectionColor(Color newColor)
   {
-    firePropertyChange("selectionColor", caretColor, newColor);
+    Color oldColor = selectionColor;
     selectionColor = newColor;
+    firePropertyChange("selectionColor", oldColor, newColor);
   }
 
   /**
@@ -584,8 +1131,16 @@
 
   public void setHighlighter(Highlighter newHighlighter)
   {
-    firePropertyChange("highlighter", highlighter, newHighlighter);
+    if (highlighter != null)
+      highlighter.deinstall(this);
+    
+    Highlighter oldHighlighter = highlighter;
     highlighter = newHighlighter;
+
+    if (highlighter != null)
+      highlighter.install(this);
+    
+    firePropertyChange("highlighter", oldHighlighter, newHighlighter);
   }
 
   /**
@@ -773,4 +1328,9 @@
   {
     return (InputMethodListener[]) getListeners(InputMethodListener.class);
   }
+
+  public Rectangle modelToView(int position) throws BadLocationException
+  {
+    return getUI().modelToView(this, position);
+  }
 }
Index: javax/swing/text/PlainView.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/PlainView.java,v
retrieving revision 1.1
diff -u -r1.1 PlainView.java
--- javax/swing/text/PlainView.java     22 Jul 2004 19:45:39 -0000      1.1
+++ javax/swing/text/PlainView.java     4 Sep 2004 17:00:15 -0000
@@ -39,6 +39,8 @@
 package javax.swing.text;
 
 import java.awt.Color;
+import java.awt.Component;
+import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Rectangle;
@@ -48,12 +50,70 @@
 public class PlainView extends View
   implements TabExpander
 {
+  private Color selectedColor;
+  private Color unselectedColor;
+  private Font font;
+  
   protected FontMetrics metrics;
 
   public PlainView(Element elem)
   {
     super(elem);
   }
+
+  /**
+   * @since 1.4
+   */
+  protected void updateMetrics()
+  {
+    Component component = getContainer();
+    Font font = component.getFont();
+
+    if (this.font != font)
+      {
+       this.font = font;
+       metrics = component.getFontMetrics(font);
+      }
+  }
+  
+  /**
+   * @since 1.4
+   */
+  protected Rectangle lineToRect(Shape a, int line)
+  {
+    // Ensure metrics are up-to-date.
+    updateMetrics();
+    
+    Rectangle rect = a.getBounds();
+    int fontHeight = metrics.getHeight();
+    return new Rectangle(rect.x, rect.y + (line * fontHeight),
+                        rect.width, fontHeight);
+  }
+
+  public Shape modelToView(int position, Shape a, Position.Bias b)
+    throws BadLocationException
+  {
+    Document document = getDocument();
+
+    // Get rectangle of the line containing position.
+    int lineIndex = getElement().getElementIndex(position);
+    Rectangle rect = lineToRect(a, lineIndex);
+
+    // Get the rectangle for position.
+    Element line = getElement().getElement(lineIndex);
+    int lineStart = line.getStartOffset();
+    Segment segment = new Segment();
+    document.getText(lineStart, position - lineStart, segment);
+    int xoffset = Utilities.getTabbedTextWidth(segment, metrics, rect.x,
+                                              this, lineStart);
+
+    // Calc the real rectangle.
+    rect.x += xoffset;
+    rect.width = 1;
+    rect.height = metrics.getHeight();
+
+    return rect;
+  }
   
   public void drawLine(int lineIndex, Graphics g, int x, int y)
   {
@@ -73,30 +133,31 @@
   public int drawSelectedText(Graphics g, int x, int y, int p0, int p1)
     throws BadLocationException
   {
-    String text = getDocument().getText(p0, p1);
-    g.setColor(Color.WHITE);
-    g.drawString(text, x, y);
-    return metrics.stringWidth(text);
+    g.setColor(selectedColor);
+    Segment segment = new Segment();
+    getDocument().getText(p0, p1 - p0, segment);
+    return Utilities.drawTabbedText(segment, x, y, g, this, 0);
   }
 
   public int drawUnselectedText(Graphics g, int x, int y, int p0, int p1)
     throws BadLocationException
   {
-    String text = getDocument().getText(p0, p1);
-    g.setColor(Color.BLACK);
-    g.drawString(text, x, y);
-    return metrics.stringWidth(text);
+    g.setColor(unselectedColor);
+    Segment segment = new Segment();
+    getDocument().getText(p0, p1 - p0, segment);
+    return Utilities.drawTabbedText(segment, x, y, g, this, 0);
   }
 
   public void paint(Graphics g, Shape s)
   {
-    System.out.println("Michael: PlainView.paint");
+    JTextComponent textComponent = (JTextComponent) getContainer();
+
+    g.setFont(textComponent.getFont());
+    selectedColor = textComponent.getSelectedTextColor();
+    unselectedColor = textComponent.getForeground();
     
     Rectangle rect = s.getBounds();
 
-    g.setColor(Color.WHITE);
-    g.fillRect(rect.x, rect.y, rect.width, rect.height);
-    
     // FIXME: Text may be scrolled.
     drawLine(0, g, rect.x, rect.y);
   }
@@ -106,10 +167,18 @@
     return 8;
   }
 
+  /**
+   * Returns the next tab stop position after a given reference position.
+   *
+   * This implementation ignores the <code>tabStop</code> argument.
+   * 
+   * @param x the current x position in pixels
+   * @param tabStop the position within the text stream that the tab occured at
+   */
   public float nextTabStop(float x, int tabStop)
   {
-    System.out.println("Michael: PlainView.nextTabpStop: missing 
implementation");
-    return x;
+    float tabSizePixels = getTabSize() + metrics.charWidth('m');
+    return (float) (Math.floor(x / tabSizePixels) + 1) * tabSizePixels;
   }
 
   public float getPreferredSpan(int axis)
@@ -119,4 +188,5 @@
 
     return 10;
   }
-}
\ No newline at end of file
+}
+
Index: javax/swing/text/Segment.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/Segment.java,v
retrieving revision 1.5
diff -u -r1.5 Segment.java
--- javax/swing/text/Segment.java       31 Jul 2004 23:18:08 -0000      1.5
+++ javax/swing/text/Segment.java       4 Sep 2004 17:00:15 -0000
@@ -39,11 +39,11 @@
 
 import java.text.CharacterIterator;
 
-
 public class Segment
   implements Cloneable, CharacterIterator
 {
   private boolean partialReturn;
+  private int current;
   
   public char[] array;
   public int count;
@@ -74,13 +74,20 @@
 
   public char current()
   {
-    return array[getIndex()];
+    if (count == 0
+       || current >= getEndIndex())
+      return DONE;
+    
+    return array[current];
   }
 
   public char first()
   {
-    offset = getBeginIndex();
-    return array[offset];
+    if (count == 0)
+      return DONE;
+
+    current = getBeginIndex();
+    return array[current];
   }
 
   public int getBeginIndex()
@@ -95,31 +102,55 @@
 
   public int getIndex()
   {
-    return offset;
+    return current;
   }
 
   public char last()
   {
-    offset = getEndIndex() - 1;
-    return array[offset];
+    if (count == 0)
+      return DONE;
+    
+    current = getEndIndex() - 1;
+    return array[current];
   }
 
   public char next()
   {
-    offset++;
-    return array[offset];
+    if (count == 0)
+      return DONE;
+
+    if ((current + 1) >= getEndIndex())
+      {
+       current = getEndIndex();
+       return DONE;
+      }
+    
+    current++;
+    return array[current];
   }
 
   public char previous()
   {
-    offset--;
-    return array[offset];
+    if (count == 0
+       || current == getBeginIndex())
+      return DONE;
+    
+    current--;
+    return array[current];
   }
 
   public char setIndex(int position)
   {
-    offset = position;
-    return array[offset];
+    if (position < getBeginIndex()
+       || position > getEndIndex())
+      throw new IllegalArgumentException();
+
+    current = position;
+
+    if (position == getEndIndex())
+      return DONE;
+    
+    return array[current];
   }
 
   public String toString()
Index: javax/swing/text/SimpleAttributeSet.java
===================================================================
RCS file: javax/swing/text/SimpleAttributeSet.java
diff -N javax/swing/text/SimpleAttributeSet.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/SimpleAttributeSet.java    4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,192 @@
+/* SimpleAttributeSet.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.text;
+
+import java.io.Serializable;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.lang.Cloneable;
+
+public class SimpleAttributeSet
+  implements MutableAttributeSet, Serializable, Cloneable
+{
+  Hashtable tab;
+
+  static AttributeSet EMPTY = new SimpleAttributeSet();
+
+  public SimpleAttributeSet()
+  {
+    this(null);
+  }
+  
+  public SimpleAttributeSet(AttributeSet a)
+  {
+    tab = new Hashtable();
+    addAttributes(a);
+  }
+
+  public void addAttribute(Object name, Object value)
+  {
+    tab.put(name, value);
+  }
+
+  public void addAttributes(AttributeSet attributes)
+  {
+    Enumeration e = attributes.getAttributeNames();
+    while (e.hasMoreElements())
+      {
+        Object name = e.nextElement();
+        Object val = attributes.getAttribute(name);
+        tab.put(name, val);
+      }
+  }
+
+  public Object clone()
+  {
+    SimpleAttributeSet s = new SimpleAttributeSet();
+    s.tab = (Hashtable) tab.clone();
+    return s;
+  }
+
+  public boolean containsAttribute(Object name, Object value)
+  {
+    return tab.containsKey(name) 
+      && tab.get(name).equals(value);
+  }
+    
+  public boolean containsAttributes(AttributeSet attributes)
+  {
+    Enumeration e = attributes.getAttributeNames();
+    while (e.hasMoreElements())
+      {
+        Object name = e.nextElement();
+        Object val = attributes.getAttribute(name);
+        if (! containsAttribute(name, val))
+          return false;                
+      }
+    return true;
+  }
+
+  public AttributeSet copyAttributes()
+  {
+    return (AttributeSet) clone();
+  }
+
+  public boolean equals(Object obj)
+  {
+    return (obj != null) 
+      && (obj instanceof SimpleAttributeSet)
+      && ((SimpleAttributeSet)obj).tab.equals(this.tab);
+  }
+
+  public Object getAttribute(Object name)
+  {
+    Object val = tab.get(name);
+    if (val != null) 
+      return val;
+
+    Object p = getResolveParent();
+    if (p != null && p instanceof AttributeSet)
+      return (((AttributeSet)p).getAttribute(name));
+
+    return null;
+  }
+
+  public int getAttributeCount()
+  {
+    return tab.size();
+  }
+
+  public Enumeration getAttributeNames()
+  {
+    return tab.keys();
+  }
+
+  public AttributeSet getResolveParent()
+  {
+    return (AttributeSet) tab.get(ResolveAttribute);
+  }
+
+  public int hashCode()
+  {
+    return tab.hashCode();
+  }
+
+  public boolean isDefined(Object attrName)
+  {
+    return tab.containsKey(attrName);
+  }
+
+  public boolean isEmpty()
+  {
+    return tab.isEmpty();      
+  }
+        
+  public boolean isEqual(AttributeSet attr)
+  {
+    return this.equals(attr);
+  }
+    
+  public void removeAttribute(Object name)
+  {
+    tab.remove(name);
+  }
+
+  public void removeAttributes(AttributeSet attributes)
+  {
+    removeAttributes(attributes.getAttributeNames());
+  }
+
+  public void removeAttributes(Enumeration names)
+  {
+    while (names.hasMoreElements())
+      {
+        removeAttribute(names.nextElement());
+      }        
+  }
+
+  public void setResolveParent(AttributeSet parent)
+  {
+    addAttribute(ResolveAttribute, parent);
+  }
+    
+  public String toString()
+  {
+    return tab.toString();
+  }    
+}
Index: javax/swing/text/StyleConstants.java
===================================================================
RCS file: javax/swing/text/StyleConstants.java
diff -N javax/swing/text/StyleConstants.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/StyleConstants.java        4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,439 @@
+/* StyleConstants.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.text;
+
+import java.awt.Color;
+import java.awt.Component;
+import javax.swing.Icon;
+
+public class StyleConstants
+{
+
+  String keyname;
+  private StyleConstants(String k) 
+  {
+    keyname = k;
+  }
+
+  public String toString()
+  {
+    return keyname;
+  }
+
+  public static int ALIGN_CENTER;
+  public static int ALIGN_JUSTIFIED;
+  public static int ALIGN_LEFT;
+  public static int ALIGN_RIGHT;
+
+  public static Object Background = CharacterConstants.Background;
+  public static Object BidiLevel = CharacterConstants.BidiLevel;
+  public static Object Bold = CharacterConstants.Bold;
+  public static Object ComponentAttribute = 
CharacterConstants.ComponentAttribute;
+  public static Object FontFamily = CharacterConstants.Family;
+  public static Object FontSize = CharacterConstants.Size;
+  public static Object Foreground = CharacterConstants.Foreground;
+  public static Object IconAttribute = CharacterConstants.IconAttribute;
+  public static Object Italic = CharacterConstants.Italic;
+  public static Object StrikeThrough = CharacterConstants.StrikeThrough;
+  public static Object Subscript = CharacterConstants.Subscript;
+  public static Object Superscript = CharacterConstants.Superscript;
+  public static Object Underline = CharacterConstants.Underline;
+
+  public static Object Alignment = ParagraphConstants.Alignment;
+  public static Object FirstLineIndent = ParagraphConstants.FirstLineIndent;
+  public static Object LeftIndent = ParagraphConstants.LeftIndent;
+  public static Object LineSpacing = ParagraphConstants.LineSpacing;
+  public static Object Orientation = ParagraphConstants.Orientation;
+  public static Object RightIndent = ParagraphConstants.RightIndent;
+  public static Object SpaceAbove = ParagraphConstants.SpaceAbove;
+  public static Object SpaceBelow = ParagraphConstants.SpaceBelow;
+  public static Object TabSet = ParagraphConstants.TabSet;
+
+  public static String ComponentElementName = new String("component");
+  public static String IconElementName = new String("icon");
+
+  public static Object ComposedTextAttribute = new StyleConstants("composed 
text");
+  public static Object ModelAttribute = new StyleConstants("model");
+  public static Object NameAttribute = new StyleConstants("name");
+  public static Object ResolveAttribute = new StyleConstants("resolver");
+
+  public static int getAlignment(AttributeSet a)
+  {
+    if (a.isDefined(Alignment))
+      return ((Integer)a.getAttribute(Alignment)).intValue();
+    else
+      return ALIGN_LEFT;      
+  } 
+
+  public static Color getBackground(AttributeSet a)
+  {
+    if (a.isDefined(Background))
+      return (Color) a.getAttribute(Background);
+    else
+      return Color.BLACK;
+  } 
+  
+  public static int getBidiLevel(AttributeSet a)
+  {
+    if (a.isDefined(BidiLevel))
+      return ((Integer)a.getAttribute(BidiLevel)).intValue();
+    else
+      return 0;
+  } 
+
+  public static Component getComponent(AttributeSet a)
+  {
+    if (a.isDefined(ComponentAttribute))
+      return (Component) a.getAttribute(ComponentAttribute);
+    else
+      return (Component) null;
+  } 
+
+  public static float getFirstLineIndent(AttributeSet a)
+  {
+    if (a.isDefined(FirstLineIndent))
+      return ((Float)a.getAttribute(FirstLineIndent)).floatValue();
+    else
+      return 0.f;
+  } 
+
+  public static String getFontFamily(AttributeSet a)
+  {
+    if (a.isDefined(FontFamily))
+      return (String) a.getAttribute(FontFamily);
+    else
+      return "Monospaced";
+  } 
+
+  public static int getFontSize(AttributeSet a)
+  {
+    if (a.isDefined(FontSize))
+      return ((Integer)a.getAttribute(FontSize)).intValue();
+    else
+      return 12;
+  } 
+
+  public static Color getForeground(AttributeSet a)
+  {
+    if (a.isDefined(Foreground))
+      return (Color) a.getAttribute(Foreground);
+    else
+      return Color.BLACK;
+  } 
+
+  public static Icon getIcon(AttributeSet a)
+  {
+    if (a.isDefined(IconAttribute))
+      return (Icon) a.getAttribute(IconAttribute);
+    else
+      return (Icon) null;
+  } 
+
+  public static float getLeftIndent(AttributeSet a)
+  {
+    if (a.isDefined(LeftIndent))
+      return ((Float)a.getAttribute(LeftIndent)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getLineSpacing(AttributeSet a)
+  {
+    if (a.isDefined(LineSpacing))
+      return ((Float)a.getAttribute(LineSpacing)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getRightIndent(AttributeSet a)
+  {
+    if (a.isDefined(RightIndent))
+      return ((Float)a.getAttribute(RightIndent)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getSpaceAbove(AttributeSet a)
+  {
+    if (a.isDefined(SpaceAbove))
+      return ((Float)a.getAttribute(SpaceAbove)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static float getSpaceBelow(AttributeSet a)
+  {
+    if (a.isDefined(SpaceBelow))
+      return ((Float)a.getAttribute(SpaceBelow)).floatValue();
+    else
+      return 0.f;  
+  } 
+
+  public static javax.swing.text.TabSet getTabSet(AttributeSet a)
+  {
+    if (a.isDefined(StyleConstants.TabSet))
+      return (javax.swing.text.TabSet) a.getAttribute(StyleConstants.TabSet);
+    else
+      return (javax.swing.text.TabSet) null;
+  } 
+
+  public static boolean isBold(AttributeSet a)
+  {
+    if (a.isDefined(Bold))
+      return ((Boolean) a.getAttribute(Bold)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isItalic(AttributeSet a)
+  {
+    if (a.isDefined(Italic))
+      return ((Boolean) a.getAttribute(Italic)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isStrikeThrough(AttributeSet a)
+  {
+    if (a.isDefined(StrikeThrough))
+      return ((Boolean) a.getAttribute(StrikeThrough)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isSubscript(AttributeSet a)
+  {
+    if (a.isDefined(Subscript))
+      return ((Boolean) a.getAttribute(Subscript)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isSuperscript(AttributeSet a)
+  {
+    if (a.isDefined(Superscript))
+      return ((Boolean) a.getAttribute(Superscript)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static boolean isUnderline(AttributeSet a)
+  {
+    if (a.isDefined(Underline))
+      return ((Boolean) a.getAttribute(Underline)).booleanValue();
+    else
+      return false;    
+  } 
+
+  public static void setAlignment(MutableAttributeSet a, int align)
+  {
+    a.addAttribute(Alignment, new Integer(align));
+  } 
+
+  public static void setBackground(MutableAttributeSet a, Color fg)
+  {
+    a.addAttribute(Background, fg);
+  } 
+
+  public static void setBidiLevel(MutableAttributeSet a, int lev)
+  {
+    a.addAttribute(BidiLevel, new Integer(lev));
+  } 
+
+  public static void setBold(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Bold, new Boolean(b));
+  } 
+  
+  public static void setComponent(MutableAttributeSet a, Component c)
+  {
+    a.addAttribute(ComponentAttribute, c);
+  } 
+
+  public static void setFirstLineIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(FirstLineIndent, new Float(i));
+  } 
+
+  public static void setFontFamily(MutableAttributeSet a, String fam)
+  {
+    a.addAttribute(FontFamily, fam);
+  } 
+
+  public static void setFontSize(MutableAttributeSet a, int s)
+  {
+    a.addAttribute(FontSize, new Integer(s));
+  } 
+
+  public static void setForeground(MutableAttributeSet a, Color fg)
+  {
+    a.addAttribute(Foreground, fg);
+  }
+
+  public static void setIcon(MutableAttributeSet a, Icon c)
+  {
+    a.addAttribute(IconAttribute, c);
+  }
+ 
+  public static void setItalic(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Italic, new Boolean(b));
+  }
+ 
+  public static void setLeftIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(LeftIndent, new Float(i));
+  } 
+
+  public static void setLineSpacing(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(LineSpacing, new Float(i));
+  } 
+
+  public static void setRightIndent(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(RightIndent, new Float(i));
+  } 
+
+  public static void setSpaceAbove(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(SpaceAbove, new Float(i));
+  } 
+
+  public static void setSpaceBelow(MutableAttributeSet a, float i)
+  {
+    a.addAttribute(SpaceBelow, new Float(i));
+  } 
+
+  public static void setStrikeThrough(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(StrikeThrough, new Boolean(b));
+  } 
+
+  public static void setSubscript(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Subscript, new Boolean(b));
+  } 
+
+  public static void setSuperscript(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Superscript, new Boolean(b));
+  } 
+
+  public static void setTabSet(MutableAttributeSet a, javax.swing.text.TabSet 
tabs)
+  {
+    a.addAttribute(StyleConstants.TabSet, tabs);
+  } 
+
+  public static void setUnderline(MutableAttributeSet a, boolean b)
+  {
+    a.addAttribute(Underline, new Boolean(b));
+  } 
+
+  // The remainder are so-called "typesafe enumerations" which 
+  // alias subsets of the above constants.
+  public static class CharacterConstants
+    extends StyleConstants
+    implements AttributeSet.CharacterAttribute
+  {
+    private CharacterConstants(String k) 
+    {
+      super(k);
+    }
+    
+    public static Object Background = ColorConstants.Background;
+    public static Object BidiLevel = new CharacterConstants("bidiLevel");
+    public static Object Bold = FontConstants.Bold;
+    public static Object ComponentAttribute = new 
CharacterConstants("component");
+    public static Object Family = FontConstants.Family;
+    public static Object Size = FontConstants.Size;
+    public static Object Foreground = ColorConstants.Foreground;
+    public static Object IconAttribute = new CharacterConstants("icon");
+    public static Object Italic = FontConstants.Italic;
+    public static Object StrikeThrough = new 
CharacterConstants("strikethrough");
+    public static Object Subscript = new CharacterConstants("subscript");
+    public static Object Superscript = new CharacterConstants("superscript");
+    public static Object Underline = new CharacterConstants("underline");
+  }
+
+  public static class ColorConstants
+    extends StyleConstants
+    implements AttributeSet.ColorAttribute, AttributeSet.CharacterAttribute
+  {
+    private ColorConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Foreground = new ColorConstants("foreground");
+    public static Object Background = new ColorConstants("background");
+  }
+
+  public static class FontConstants
+    extends StyleConstants
+    implements AttributeSet.FontAttribute, AttributeSet.CharacterAttribute
+  {
+    private FontConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Bold = new FontConstants("bold");
+    public static Object Family = new FontConstants("family");
+    public static Object Italic = new FontConstants("italic");
+    public static Object Size = new FontConstants("size");
+  }
+
+  public static class ParagraphConstants
+    extends StyleConstants
+    implements AttributeSet.ParagraphAttribute
+  {
+    private ParagraphConstants(String k) 
+    {
+      super(k);
+    }
+    public static Object Alignment = new ParagraphConstants("Alignment");
+    public static Object FirstLineIndent = new 
ParagraphConstants("FirstLineIndent");
+    public static Object LeftIndent = new ParagraphConstants("LeftIndent");
+    public static Object LineSpacing = new ParagraphConstants("LineSpacing");
+    public static Object Orientation = new ParagraphConstants("Orientation");
+    public static Object RightIndent = new ParagraphConstants("RightIndent");
+    public static Object SpaceAbove = new ParagraphConstants("SpaceAbove");
+    public static Object SpaceBelow = new ParagraphConstants("SpaceBelow");
+    public static Object TabSet = new ParagraphConstants("TabSet");
+  }
+
+}
Index: javax/swing/text/StyleContext.java
===================================================================
RCS file: javax/swing/text/StyleContext.java
diff -N javax/swing/text/StyleContext.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/StyleContext.java  4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,697 @@
+/* StyleContext.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.text;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Toolkit;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Hashtable;
+
+public class StyleContext 
+    implements Serializable, AbstractDocument.AttributeContext
+{
+  public class NamedStyle
+    implements Serializable, Style
+  {
+    protected ChangeEvent changeEvent;
+    protected EventListenerList listenerList;
+      
+    AttributeSet attributes;
+    String name;
+
+    public NamedStyle()
+    {
+      this(null, null);
+    }
+
+    public NamedStyle(Style parent)
+    {
+      this(null, parent);
+    }
+
+    public NamedStyle(String name, Style parent)
+    {
+      this.name = name;
+      this.attributes = getEmptySet();
+      this.changeEvent = new ChangeEvent(this);
+      this.listenerList = new EventListenerList();
+      setResolveParent(parent);
+    }
+
+    public String getName()
+    {
+      return name;
+    }
+
+    public void setName(String n)
+    {
+      name = n;
+      fireStateChanged();
+    }
+
+    public void addChangeListener(ChangeListener l)
+    {
+      listenerList.add(ChangeListener.class, l);
+    }
+      
+    public void removeChangeListener(ChangeListener l)
+    {
+      listenerList.remove(ChangeListener.class, l);
+    }
+      
+    public EventListener[] getListeners(Class listenerType)
+    {
+      return listenerList.getListeners(listenerType);
+    }
+
+    public ChangeListener[] getChangeListeners()
+    {
+      return (ChangeListener[]) getListeners(ChangeListener.class);
+    }
+
+    protected  void fireStateChanged()
+    {
+      ChangeListener[] listeners = getChangeListeners();
+      for (int i = 0; i < listeners.length; ++i)
+        {
+          listeners[i].stateChanged(changeEvent);
+        }
+    }
+
+    public void addAttribute(Object name, Object value)
+    {
+      attributes = StyleContext.this.addAttribute(attributes, name, value);
+      fireStateChanged();
+    }
+
+    public void addAttributes(AttributeSet attr)
+    {
+      attributes = StyleContext.this.addAttributes(attributes, attr);
+      fireStateChanged();
+    }
+
+    public boolean containsAttribute(Object name, Object value)
+    {
+      return attributes.containsAttribute(name, value);
+    }
+      
+    public boolean containsAttributes(AttributeSet attrs)
+    {
+      return attributes.containsAttributes(attrs);
+    }
+
+    public AttributeSet copyAttributes()
+    {
+      return attributes.copyAttributes();
+    }
+            
+    public Object getAttribute(Object attrName)
+    {
+      return attributes.getAttribute(attrName);
+    }
+
+    public int getAttributeCount()
+    {
+      return attributes.getAttributeCount();
+    }
+
+    public Enumeration getAttributeNames()
+    {
+      return attributes.getAttributeNames();
+    }
+      
+    public boolean isDefined(Object attrName)
+    {
+      return attributes.isDefined(attrName);        
+    }
+
+    public boolean isEqual(AttributeSet attr)
+    {
+      return attributes.isEqual(attr);
+    }
+
+    public void removeAttribute(Object name)
+    {
+      attributes = StyleContext.this.removeAttribute(attributes, name);
+      fireStateChanged();
+    }
+
+    public void removeAttributes(AttributeSet attrs)
+    {
+      attributes = StyleContext.this.removeAttributes(attributes, attrs);
+      fireStateChanged();
+    }
+
+    public void removeAttributes(Enumeration names)
+    {
+      attributes = StyleContext.this.removeAttributes(attributes, names);
+      fireStateChanged();
+    }
+
+
+    public AttributeSet getResolveParent()
+    {
+      return attributes.getResolveParent();        
+    }
+
+    public void setResolveParent(AttributeSet parent)
+    {
+      attributes = StyleContext.this.addAttribute(attributes, 
ResolveAttribute, parent);
+      fireStateChanged();
+    }
+      
+    public String toString()
+    {
+      return ("[NamedStyle: name=" + name + ", attrs=" + attributes.toString() 
+ "]");
+    }      
+  }
+  
+  public class SmallAttributeSet
+    implements AttributeSet
+  {
+    final Object [] attrs;
+    public SmallAttributeSet(AttributeSet a)
+    {
+      if (a == null)
+        attrs = new Object[0];
+      else
+        {
+          int n = a.getAttributeCount();
+          int i = 0;
+          attrs = new Object[n * 2];
+          Enumeration e = a.getAttributeNames();
+          while (e.hasMoreElements())
+            {
+              Object name = e.nextElement();
+              attrs[i++] = name;
+              attrs[i++] = a.getAttribute(name);
+            }
+        }
+    }
+
+    public SmallAttributeSet(Object [] a)
+    {
+      if (a == null)
+        attrs = new Object[0];
+      else
+        {
+          attrs = new Object[a.length];
+          System.arraycopy(a, 0, attrs, 0, a.length);
+        }
+    }
+
+    public Object clone()
+    {
+      return new SmallAttributeSet(this.attrs);
+    }
+
+    public boolean containsAttribute(Object name, Object value)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(name) &&
+              attrs[i+1].equals(value))
+            return true;
+        }
+      return false;
+    }
+
+    public boolean containsAttributes(AttributeSet a)
+    {
+      Enumeration e = a.getAttributeNames();
+      while (e.hasMoreElements())
+        {
+          Object name = e.nextElement();
+          Object val = a.getAttribute(name);
+          if (!containsAttribute(name, val))
+            return false;
+        }
+      return true;                     
+    }
+
+    public AttributeSet copyAttributes()
+    {
+      return (AttributeSet) clone();
+    }
+
+    public boolean equals(Object obj)
+    {
+      return 
+        (obj instanceof SmallAttributeSet)
+        && this.isEqual((AttributeSet)obj);
+    }
+ 
+    public Object getAttribute(Object key)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(key))
+            return attrs[i+1];
+        }
+            
+      Object p = getResolveParent();
+      if (p != null && p instanceof AttributeSet)
+        return (((AttributeSet)p).getAttribute(key));
+      
+      return null;
+    }
+
+    public int getAttributeCount()
+    {
+      return attrs.length / 2;
+    }
+
+    public Enumeration getAttributeNames()
+    {      
+      return new Enumeration() 
+        {
+          int i = 0;
+          public boolean hasMoreElements() 
+          { 
+            return i < attrs.length; 
+          }
+          public Object nextElement() 
+          { 
+            i += 2; 
+            return attrs[i-2]; 
+          }
+        };
+    }
+
+    public AttributeSet getResolveParent()
+    {
+      return (AttributeSet) getAttribute(ResolveAttribute);
+    }
+
+    public int hashCode()
+    {
+      return java.util.Arrays.asList(attrs).hashCode();
+    }
+
+    public boolean isDefined(Object key)
+    {
+      for (int i = 0; i < attrs.length; i += 2)
+        {
+          if (attrs[i].equals(key))
+            return true;
+        }
+      return false;
+    }
+       
+    public boolean isEqual(AttributeSet attr)
+    {
+      return attr != null 
+        && attr.containsAttributes(this)
+        && this.containsAttributes(attr);
+    }
+       
+    public String toString()
+    {
+      StringBuffer sb = new StringBuffer();
+      sb.append("[StyleContext.SmallattributeSet:");
+      for (int i = 0; i < attrs.length; ++i)
+        {
+          sb.append(" (");
+          sb.append(attrs[i].toString());
+          sb.append("=");
+          sb.append(attrs[i+1].toString());
+          sb.append(")");
+        }
+      sb.append("]");
+      return sb.toString();
+    }
+  }
+
+  // FIXME: official javadocs suggest that these might be more usefully
+  // implemented using a WeakHashMap, but not sure if that works most
+  // places or whether it really matters anyways.
+  //
+  // FIXME: also not sure if these tables ought to be static (singletons),
+  // shared across all StyleContexts. I think so, but it's not clear in
+  // docs. revert to non-shared if you think it matters.
+
+  public static final String DEFAULT_STYLE = "default";
+  
+  static Hashtable sharedAttributeSets = new Hashtable();
+  static Hashtable sharedFonts = new Hashtable();
+
+  static StyleContext defaultStyleContext = new StyleContext();
+  static final int compressionThreshold = 9;
+  
+  EventListenerList listenerList;
+  Hashtable styleTable;
+  
+  public StyleContext()
+  {
+    listenerList = new EventListenerList();
+    styleTable = new Hashtable();
+  }
+
+  protected SmallAttributeSet createSmallAttributeSet(AttributeSet a)
+  {
+    return new SmallAttributeSet(a);
+  }
+  
+  protected MutableAttributeSet createLargeAttributeSet(AttributeSet a)
+  {
+    return new SimpleAttributeSet(a);
+  }
+
+  public void addChangeListener(ChangeListener listener)
+  {
+    listenerList.add(ChangeListener.class, listener);
+  }
+
+  public void removeChangeListener(ChangeListener listener)
+  {
+    listenerList.remove(ChangeListener.class, listener);
+  }
+
+  public ChangeListener[] getChangeListeners()
+  {
+    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+  }
+    
+  public Style addStyle(String name, Style parent)
+  {
+    Style newStyle = new NamedStyle(name, parent);
+    if (name != null)
+      styleTable.put(name, newStyle);
+    return newStyle;
+  }
+
+  public void removeStyle(String name)
+  {
+    styleTable.remove(name);
+  }
+
+  public Style getStyle(String name)
+  {
+    return (Style) styleTable.get(name);
+  }
+
+  public Enumeration getStyleNames()
+  {
+    return styleTable.keys();
+  }
+
+  //
+  // StyleContexts only understand the "simple" model of fonts present in
+  // pre-java2d systems: fonts are a family name, a size (integral number
+  // of points), and a mask of style parameters (plain, bold, italic, or
+  // bold|italic). We have an inner class here called SimpleFontSpec which
+  // holds such triples.
+  //
+  // A SimpleFontSpec can be built for *any* AttributeSet because the size,
+  // family, and style keys in an AttributeSet have default values (defined
+  // over in StyleConstants).
+  //
+  // We keep a static cache mapping SimpleFontSpecs to java.awt.Fonts, so
+  // that we reuse Fonts between styles and style contexts.
+  // 
+
+  private static class SimpleFontSpec
+  {
+    String family;
+    int style;
+    int size;
+    public SimpleFontSpec(String family,
+                          int style,
+                          int size)
+    {
+      this.family = family;
+      this.style = style;
+      this.size = size;
+    }
+    public boolean equals(Object obj)
+    {
+      return (obj != null)
+        && (obj instanceof SimpleFontSpec)
+        && (((SimpleFontSpec)obj).family.equals(this.family))
+        && (((SimpleFontSpec)obj).style == this.style)
+        && (((SimpleFontSpec)obj).size == this.size);
+    }
+    public int hashCode()
+    {
+      return family.hashCode() + style + size;
+    }
+  }
+  
+  public Font getFont(AttributeSet attr)
+  {
+    String family = StyleConstants.getFontFamily(attr);
+    int style = Font.PLAIN;
+    if (StyleConstants.isBold(attr))
+      style += Font.BOLD;
+    if (StyleConstants.isItalic(attr))
+      style += Font.ITALIC;      
+    int size = StyleConstants.getFontSize(attr);
+    return getFont(family, style, size);
+  }
+
+  public Font getFont(String family, int style, int size)
+  {
+    SimpleFontSpec spec = new SimpleFontSpec(family, style, size);
+    if (sharedFonts.containsKey(spec))
+      return (Font) sharedFonts.get(spec);
+    else
+      {
+        Font tmp = new Font(family, style, size);
+        sharedFonts.put(spec, tmp);
+        return tmp;
+      }
+  }
+  
+  public FontMetrics getFontMetrics(Font f)
+  {
+    return Toolkit.getDefaultToolkit().getFontMetrics(f);
+  }
+
+  public Color getForeground(AttributeSet a)
+  {
+    return StyleConstants.getForeground(a);
+  }
+
+  public Color getBackground(AttributeSet a)
+  {
+    return StyleConstants.getBackground(a);
+  }
+
+  protected int getCompressionThreshold() 
+  {
+    return compressionThreshold;
+  }
+
+  public static StyleContext getDefaultStyleContext()
+  {
+    return defaultStyleContext;
+  }
+
+  public AttributeSet addAttribute(AttributeSet old, Object name, Object value)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).addAttribute(name, value);
+        return old;
+      }
+    else 
+      {
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.addAttribute(name, value);
+        if (mutable.getAttributeCount() >= getCompressionThreshold())
+          return mutable;
+        else
+          {
+            SmallAttributeSet small = createSmallAttributeSet(mutable);
+            if (sharedAttributeSets.containsKey(small))
+              small = (SmallAttributeSet) sharedAttributeSets.get(small);
+            else
+              sharedAttributeSets.put(small,small);
+            return small;
+          }
+      }
+  }
+
+  public AttributeSet addAttributes(AttributeSet old, AttributeSet attributes)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).addAttributes(attributes);
+        return old;
+      }
+    else 
+      {
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.addAttributes(attributes);
+        if (mutable.getAttributeCount() >= getCompressionThreshold())
+          return mutable;
+        else
+          {
+            SmallAttributeSet small = createSmallAttributeSet(mutable);
+            if (sharedAttributeSets.containsKey(small))
+              small = (SmallAttributeSet) sharedAttributeSets.get(small);
+            else
+              sharedAttributeSets.put(small,small);
+            return small;
+          }
+      }
+  }
+
+  public AttributeSet getEmptySet()
+  {
+    AttributeSet e = createSmallAttributeSet(null);
+    if (sharedAttributeSets.containsKey(e))
+      e = (AttributeSet) sharedAttributeSets.get(e);
+    else
+      sharedAttributeSets.put(e, e);
+    return e;
+  }
+
+  public void reclaim(AttributeSet attributes)
+  {
+    if (sharedAttributeSets.containsKey(attributes))
+      sharedAttributeSets.remove(attributes);
+  }
+
+  public AttributeSet removeAttribute(AttributeSet old, Object name)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).removeAttribute(name);
+        if (old.getAttributeCount() < getCompressionThreshold())
+          {
+            SmallAttributeSet small = createSmallAttributeSet(old);
+            if (!sharedAttributeSets.containsKey(small))
+              sharedAttributeSets.put(small,small);
+            old = (AttributeSet) sharedAttributeSets.get(small);
+          }
+        return old;
+      }
+    else 
+      {          
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.removeAttribute(name);
+        SmallAttributeSet small = createSmallAttributeSet(mutable);
+        if (sharedAttributeSets.containsKey(small))
+          small = (SmallAttributeSet) sharedAttributeSets.get(small);
+        else
+          sharedAttributeSets.put(small,small);
+        return small;
+      }
+  }
+
+  public AttributeSet removeAttributes(AttributeSet old, AttributeSet 
attributes)
+  {
+    return removeAttributes(old, attributes.getAttributeNames());
+  }
+
+  public AttributeSet removeAttributes(AttributeSet old, Enumeration names)
+  {
+    if (old instanceof MutableAttributeSet)
+      {
+        ((MutableAttributeSet)old).removeAttributes(names);
+        if (old.getAttributeCount() < getCompressionThreshold())
+          {
+            SmallAttributeSet small = createSmallAttributeSet(old);
+            if (!sharedAttributeSets.containsKey(small))
+              sharedAttributeSets.put(small,small);
+            old = (AttributeSet) sharedAttributeSets.get(small);
+          }
+        return old;
+      }
+    else 
+      {          
+        MutableAttributeSet mutable = createLargeAttributeSet(old);
+        mutable.removeAttributes(names);
+        SmallAttributeSet small = createSmallAttributeSet(mutable);
+        if (sharedAttributeSets.containsKey(small))
+          small = (SmallAttributeSet) sharedAttributeSets.get(small);
+        else
+          sharedAttributeSets.put(small,small);
+        return small;
+      }        
+  }
+
+
+  // FIXME: there's some sort of quasi-serialization stuff in here which I
+  // have left incomplete; I'm not sure I understand the intent properly.
+
+  public static Object getStaticAttribute(Object key)
+  {
+    throw new InternalError("not implemented");
+  }
+  
+  public static Object getStaticAttributeKey(Object key)
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public static void readAttributeSet(ObjectInputStream in, 
MutableAttributeSet a)
+    throws ClassNotFoundException, IOException
+  {
+    throw new InternalError("not implemented");
+  }
+  
+  public static void writeAttributeSet(ObjectOutputStream out, AttributeSet a)
+    throws IOException
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public void readAttributes(ObjectInputStream in, MutableAttributeSet a)
+    throws ClassNotFoundException, IOException 
+  {
+    throw new InternalError("not implemented");
+  }
+
+  public void writeAttributes(ObjectOutputStream out, AttributeSet a)
+    throws IOException
+  {
+    throw new InternalError("not implemented");
+  }
+}
Index: javax/swing/text/TabSet.java
===================================================================
RCS file: javax/swing/text/TabSet.java
diff -N javax/swing/text/TabSet.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabSet.java        4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,102 @@
+/* TabSet.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.text;
+
+import java.io.Serializable;
+
+public class TabSet implements Serializable
+{
+  TabStop[] tabs;
+
+  public TabSet(TabStop[] t) 
+  {
+    tabs = t;
+  }
+ 
+  public TabStop getTab(int i) 
+  {
+    return tabs[i];
+  }
+
+  public TabStop getTabAfter(float location) 
+  {
+    int idx = getTabIndexAfter(location);
+    if (idx == -1)
+      return null;
+    else
+      return tabs[idx];        
+  }
+
+  public int getTabCount() 
+  {
+    return tabs.length;
+  }
+
+  public int getTabIndex(TabStop tab) 
+  {
+    for (int i = 0; i < tabs.length; ++i)
+      if (tabs[i] == tab)
+        return i;
+    return -1;
+  }
+
+  public int getTabIndexAfter(float location) 
+  {
+    int idx = -1;
+    for (int i = 0; i < tabs.length; ++i)
+      {
+        if (location < tabs[i].getPosition())
+          idx = i;
+      }
+    return idx;
+  }
+
+  public String toString()
+  {
+    StringBuffer sb = new StringBuffer();
+    sb.append("[");
+    for (int i = 0; i < tabs.length; ++i)
+      {
+        if (i != 0)
+          sb.append(" - ");
+        sb.append(tabs[i].toString());
+      }
+    sb.append("]");
+    return sb.toString();
+  }
+}
Index: javax/swing/text/TabStop.java
===================================================================
RCS file: javax/swing/text/TabStop.java
diff -N javax/swing/text/TabStop.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/TabStop.java       4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,133 @@
+/* TabSet.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.text;
+
+import java.io.Serializable;
+
+public class TabStop implements Serializable
+{
+  public static final int ALIGN_LEFT = 0;
+  public static final int ALIGN_RIGHT = 1;
+  public static final int ALIGN_CENTER = 2;
+  public static final int ALIGN_DECIMAL = 4;
+  public static final int ALIGN_BAR = 5;
+
+  public static final int LEAD_NONE = 0;
+  public static final int LEAD_DOTS = 1;
+  public static final int LEAD_HYPHENS = 2;
+  public static final int LEAD_UNDERLINE = 3;
+  public static final int LEAD_THICKLINE = 4;
+  public static final int LEAD_EQUALS = 5;
+
+  float pos;
+  int align;
+  int leader;
+
+  public TabStop(float pos) 
+  {
+    this(pos, ALIGN_LEFT, LEAD_NONE);
+  }
+  
+  public TabStop(float pos, int align, int leader)
+  {
+    this.pos = pos;
+    this.align = align;
+    this.leader = leader;
+  }
+    
+  public boolean equals(Object other) 
+  {
+    return (other != null)
+      && (other instanceof TabStop)
+      && (((TabStop)other).getPosition() == this.getPosition())
+      && (((TabStop)other).getLeader() == this.getLeader())
+      && (((TabStop)other).getAlignment() == this.getAlignment());
+  }
+
+  public int getAlignment() 
+  {
+    return align;
+  }
+
+  public int getLeader() 
+  {
+    return leader;
+  }
+
+  public float getPosition() 
+  {
+    return pos;
+  }
+
+  public int hashCode() 
+  {
+    return (int) pos + (int) leader + (int) align;
+  }
+
+  public String toString() 
+  {
+    String prefix = "";
+    switch (align)
+      {
+      case ALIGN_LEFT:
+        prefix = "left ";
+        break;
+      case ALIGN_RIGHT:
+        prefix = "right ";
+        break;
+
+      case ALIGN_CENTER:
+        prefix = "center ";
+        break;
+
+      case ALIGN_DECIMAL:
+        prefix = "decimal ";
+        break;
+        
+      case ALIGN_BAR:
+        prefix = "bar ";
+        break;
+
+      default:
+        break;
+      }
+    
+    return (prefix + "tab @" + pos + ((leader == LEAD_NONE) ? "" : 
"(w/leaders)"));
+  }
+
+}
Index: javax/swing/text/TextAction.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/TextAction.java,v
retrieving revision 1.4
diff -u -r1.4 TextAction.java
--- javax/swing/text/TextAction.java    31 Jul 2004 23:24:23 -0000      1.4
+++ javax/swing/text/TextAction.java    4 Sep 2004 17:00:15 -0000
@@ -54,7 +54,7 @@
    */
   public TextAction(String name)
   {
-    // TODO
+    super(name);
   }
 
   /**
@@ -64,7 +64,11 @@
    */
   protected final JTextComponent getTextComponent(ActionEvent event)
   {
-    return null; // TODO
+    if (event.getSource() != null &&
+        event.getSource() instanceof JTextComponent)
+      return (JTextComponent) event.getSource();
+    else
+      return getFocusedComponent();
   }
 
   /**
Index: javax/swing/text/Utilities.java
===================================================================
RCS file: javax/swing/text/Utilities.java
diff -N javax/swing/text/Utilities.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/text/Utilities.java     4 Sep 2004 17:00:15 -0000
@@ -0,0 +1,182 @@
+/* Utilities.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.text;
+
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+
+/**
+ * A set of utilities to deal with text. This is used by several other classes
+ * inside this package.
+ *
+ * @author Roman Kennke <address@hidden>
+ */
+public class Utilities
+{
+  /**
+   * The length of the char buffer that holds the characters to be drawn.
+   */
+  private static final int BUF_LENGTH = 64;
+
+  /**
+   * Creates a new <code>Utilities</code> object.
+   */
+  public Utilities()
+  {
+    // Nothing to be done here.
+  }
+
+  /**
+   * Draws the given text segment. Contained tabs and newline characters
+   * are taken into account. Tabs are expanded using the
+   * specified address@hidden TabExpander}.
+   *
+   * @param s the text fragment to be drawn.
+   * @param x the x position for drawing.
+   * @param y the y position for drawing.
+   * @param g the address@hidden Graphics} context for drawing.
+   * @param e the address@hidden TabExpander} which specifies the Tab-expanding
+   *     technique.
+   * @param startOffset starting offset in the text.
+   * @return the x coordinate at the end of the drawn text.
+   */
+  public static final int drawTabbedText(Segment s, int x, int y, Graphics g,
+                                         TabExpander e, int startOffset)
+  {
+    // This buffers the chars to be drawn.
+    char[] buffer = s.array;
+
+
+    // The current x and y pixel coordinates.
+    int pixelX = x;
+    int pixelY = y;
+
+    // The font metrics of the current selected font.
+    FontMetrics metrics = g.getFontMetrics();
+    int ascent = metrics.getAscent();
+
+    for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+      {
+       switch (buffer[offset])
+         {
+         case '\t':
+           // In case we have a tab, we just 'jump' over the tab.
+           // When we have no tab expander we just use the width of 'm'.
+           if (e != null)
+             pixelX = (int) e.nextTabStop((float) pixelX,
+                                          startOffset + offset - s.offset);
+           else
+             pixelX += metrics.charWidth(' ');
+           break;
+         case '\n':
+           // In case we have a newline, we must draw
+           // the buffer and jump on the next line.
+           g.drawChars(buffer, offset, 1, pixelX, y);
+           pixelY += metrics.getHeight();
+           pixelX = x;
+           break;
+         default:
+           // Here we draw the char.
+           g.drawChars(buffer, offset, 1, pixelX, pixelY + ascent);
+           pixelX += metrics.charWidth(buffer[offset]);
+           break;
+         }
+      }
+
+    return pixelX;
+  }
+
+  /**
+   * Determines the width, that the given text <code>s</code> would take
+   * if it was printed with the given address@hidden java.awt.FontMetrics} on 
the
+   * specified screen position.
+   * @param s the text fragment
+   * @param metrics the font metrics of the font to be used
+   * @param x the x coordinate of the point at which drawing should be done
+   * @param e the address@hidden TabExpander} to be used
+   * @param startOffset the index in <code>s</code> where to start
+   * @returns the width of the given text s. This takes tabs and newlines
+   * into account.
+   */
+  public static final int getTabbedTextWidth(Segment s, FontMetrics metrics,
+                                             int x, TabExpander e,
+                                             int startOffset)
+  {
+    // This buffers the chars to be drawn.
+    char[] buffer = s.array;
+
+    // The current x coordinate.
+    int pixelX = x;
+
+    // The current maximum width.
+    int maxWidth = 0;
+
+    for (int offset = s.offset; offset < (s.offset + s.count); ++offset)
+      {
+       switch (buffer[offset])
+         {
+         case '\t':
+           // In case we have a tab, we just 'jump' over the tab.
+           // When we have no tab expander we just use the width of 'm'.
+           if (e != null)
+             pixelX = (int) e.nextTabStop((float) pixelX,
+                                          startOffset + offset - s.offset);
+           else
+             pixelX += metrics.charWidth(' ');
+           break;
+         case '\n':
+           // In case we have a newline, we must 'draw'
+           // the buffer and jump on the next line.
+           pixelX += metrics.charWidth(buffer[offset]);
+           maxWidth = Math.max(maxWidth, pixelX - x);
+           pixelX = x;
+           break;
+         default:
+           // Here we draw the char.
+           pixelX += metrics.charWidth(buffer[offset]);
+           break;
+         }
+      }
+
+    // Take the last line into account.
+    maxWidth = Math.max(maxWidth, pixelX - x);
+
+    return maxWidth;
+  }
+}
Index: javax/swing/text/View.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/View.java,v
retrieving revision 1.6
diff -u -r1.6 View.java
--- javax/swing/text/View.java  31 Jul 2004 23:18:08 -0000      1.6
+++ javax/swing/text/View.java  4 Sep 2004 17:00:15 -0000
@@ -174,5 +174,36 @@
   {
     return elt.getEndOffset();
   }
+
+  public Shape getChildAllocation(int index, Shape a)
+  {
+    return null;
+  }
+  
+  /**
+   * @since 1.4
+   */
+  public int getViewIndex(float x, float y, Shape allocation)
+  {
+    return -1;
+  }
+  
+  /**
+   * @since 1.4
+   */
+  public String getToolTipText(float x, float y, Shape allocation)
+  {
+    int index = getViewIndex(x, y, allocation);
+
+    if (index < -1)
+      return null;
+
+    Shape childAllocation = getChildAllocation(index, allocation);
+
+    if (childAllocation.getBounds().contains(x, y))
+      return getView(index).getToolTipText(x, y, childAllocation);
+
+    return null;
+  }
 }
 

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]