Hi,
before applying this patch we had a couple of issues with the DefaultCaret and
JTextComponent:
- cut(), copy() and paste() worked even if the component is disabled or in a
non-editable state (observed how RI works and mimiced their behavior)

- caret was drawn even if the component is disabled and/or non-editable

As kind of addition: If you put the following ActionListener on a JTextField tf:

new ActionListener(){
   public void actionPerformed(ae){
     tf.setEditable(!tf.isEditable());
   }
};

And invoke it the RI will always paint the Caret (until it loses its focus and
regains it later). We do not - which is a bit more correct. :)

The ChangeLog:

2006-05-11  Robert Schuster  <[EMAIL PROTECTED]>

        * javax/swing/text/DefaultCaret.java: Made field 'textComponent'
        package-private, added field 'active'.
        (PropertyChangeHandler.propertyChange): Added variable 'name', added
        cases to update field 'active'.
        (mouseDragged): Added documentation, added if-clause to update
        selection or caret position.
        (mouseClicked): Added early return when text component is disabled.
        (focusGained): Moved statements into an if-clause.
        (focusLost): Added subexpression to if-clause.
        (install): Preset value of 'active'.
        (paint): Added subexpression to if-clause.
        (isVisible): Extended return expression.
        * javax/swing/text/JTextComponent.java:
        (copy): Copy only if component is enabled.
        (cut): Cut only if component is enabled and editable.
        (paste): Dito.

cya
Robert
Index: javax/swing/text/DefaultCaret.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/DefaultCaret.java,v
retrieving revision 1.40
diff -u -r1.40 DefaultCaret.java
--- javax/swing/text/DefaultCaret.java	3 May 2006 18:11:05 -0000	1.40
+++ javax/swing/text/DefaultCaret.java	11 May 2006 16:07:10 -0000
@@ -216,13 +216,26 @@
      */
     public void propertyChange(PropertyChangeEvent e)
     {
-      if (e.getPropertyName().equals("document"))
+      String name = e.getPropertyName(); 
+      
+      if (name.equals("document"))
         {
           Document oldDoc = (Document) e.getOldValue();
           oldDoc.removeDocumentListener(documentListener);
           Document newDoc = (Document) e.getNewValue();
           newDoc.addDocumentListener(documentListener);
         }
+      else if (name.equals("editable"))
+        {
+          active = (((Boolean) e.getNewValue()).booleanValue()
+                   && textComponent.isEnabled());
+        }
+      else if (name.equals("enabled"))
+        {
+          active = (((Boolean) e.getNewValue()).booleanValue()
+                   && textComponent.isEditable());
+        }
+      
     }
     
   }
@@ -281,8 +294,10 @@
 
   /**
    * The text component in which this caret is installed.
+   * 
+   * (Package private to avoid synthetic accessor method.)
    */
-  private JTextComponent textComponent;
+  JTextComponent textComponent;
 
   /**
    * Indicates if the selection should be visible or not.
@@ -314,6 +329,12 @@
    * package private to avoid an accessor method.
    */
   boolean visible = false;
+  
+  /** Indicates whether the text component where the caret is installed is
+   * editable and enabled. If either of these properties is <code>false</code>
+   * the caret is not drawn.
+   */ 
+  boolean active = true;
 
   /**
    * The current highlight entry.
@@ -388,14 +409,23 @@
   
   /**
    * Moves the caret position when the mouse is dragged over the text
-   * component, modifying the selection accordingly.
+   * component, modifying the selectiony.
+   * 
+   * <p>When the text component where the caret is installed is disabled,
+   * the selection is not change but you can still scroll the text and
+   * update the caret's location.</p>
    *
    * @param event the <code>MouseEvent</code> describing the drag operation
    */
   public void mouseDragged(MouseEvent event)
   {
     if (event.getButton() == MouseEvent.BUTTON1)
-      moveCaret(event);
+      {
+        if (textComponent.isEnabled())
+          moveCaret(event);
+        else
+          positionCaret(event);
+      }
   }
 
   /**
@@ -426,6 +456,10 @@
    */
   public void mouseClicked(MouseEvent event)
   {
+    // Do not modify selection if component is disabled.
+    if (!textComponent.isEnabled())
+      return;
+    
     int count = event.getClickCount();
     
     if (event.getButton() == MouseEvent.BUTTON1 && count >= 2)
@@ -523,7 +557,7 @@
     // implemented (in regard to text components):
     // - a left-click moves the caret
     // - a left-click when shift is held down expands the selection
-    // - a right-click or click with any additionaly mouse button
+    // - a right-click or click with any additional mouse button
     //   on a text component is ignored
     // - a middle-click positions the caret and pastes the clipboard
     //   contents.
@@ -540,6 +574,7 @@
         else
           {
             positionCaret(event);
+            
             textComponent.paste();
           }
       else
@@ -564,8 +599,11 @@
    */
   public void focusGained(FocusEvent event)
   {
-    setVisible(true);    
-    updateTimerStatus();
+    if (textComponent.isEditable())
+      {
+        setVisible(true);    
+        updateTimerStatus();
+      }
   }
 
   /**
@@ -575,10 +613,11 @@
    */
   public void focusLost(FocusEvent event)
   {
-    if (event.isTemporary() == false)
+    if (textComponent.isEditable() && event.isTemporary() == false)
       {
         setVisible(false);
-        // Stop the blinker, if running.
+        
+        // Stop the blinker
         if (blinkTimer != null && blinkTimer.isRunning())
           blinkTimer.stop();
       }
@@ -670,6 +709,7 @@
     textComponent.addPropertyChangeListener(propertyChangeListener);
     documentListener = new DocumentHandler();
     textComponent.getDocument().addDocumentListener(documentListener);
+    active = textComponent.isEditable() && textComponent.isEnabled();
 
     repaint();
   }
@@ -872,7 +912,7 @@
       }
 
     // Now draw the caret on the new position if visible.
-    if (visible)
+    if (visible && active)
       {
         g.setColor(textComponent.getCaretColor());
         g.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height - 1);
@@ -1013,7 +1053,9 @@
         this.dot = Math.max(this.dot, 0);
         
         handleHighlight();
+
         appear();
+
         adjustVisibility(this);
       }
   }
@@ -1050,7 +1092,9 @@
         this.mark = this.dot;
         
         clearHighlight();
+        
         appear();
+        
         adjustVisibility(this);
       }
   }
@@ -1104,7 +1148,7 @@
    */
   public boolean isVisible()
   {
-    return visible;
+    return visible && active;
   }
 
   /**
Index: javax/swing/text/JTextComponent.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/text/JTextComponent.java,v
retrieving revision 1.56
diff -u -r1.56 JTextComponent.java
--- javax/swing/text/JTextComponent.java	2 May 2006 14:11:31 -0000	1.56
+++ javax/swing/text/JTextComponent.java	11 May 2006 16:07:10 -0000
@@ -1365,7 +1365,7 @@
   {
     if (editable == newValue)
       return;
-
+    
     boolean oldValue = editable;
     editable = newValue;
     firePropertyChange("editable", oldValue, newValue);
@@ -1725,17 +1725,20 @@
 
   public void copy()
   {
+    if (isEnabled())
     doTransferAction("copy", TransferHandler.getCopyAction());
   }
 
   public void cut()
   {
-    doTransferAction("cut", TransferHandler.getCutAction());
+    if (editable && isEnabled())
+      doTransferAction("cut", TransferHandler.getCutAction());
   }
 
   public void paste()
   {
-    doTransferAction("paste", TransferHandler.getPasteAction());
+    if (editable && isEnabled())
+      doTransferAction("paste", TransferHandler.getPasteAction());
   }
 
   private void doTransferAction(String name, Action action)

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to