I am still working on JTree editing. I have not yet implemented the keys
to start/stop editing, so it is still not test-able. So far, it works to
start editing and stop editing with mouse-clicks. I have not finished
completing editing (updating the nodes text), or implemented all the key
handling to do this. It is about half done.

Also, I added in a change for JPasswordField that was requested by Mark
and Roman.

The patch is rather cumbersome, keep in mind not everything is
completed... so things will probably change slightly.

2005-08-29  Lillian Angel  <[EMAIL PROTECTED]>

        * javax/swing/JPasswordField.java
        (getText): Changed to pass error to AssertionError.
        * javax/swing/plaf/basic/BasicTreeUI.java
        (setCellEditor): Updated boolean when appropriate.
        (stopEditing): Took out redundant code.
        (updateCellEditor): Updated boolean when appropriate.
        (installListeners): Took out CellEditorListener. It is added
        when the cellEditor is set.
        (installUI): Similar.
        (ensureRowsAreVisible): Fixed API documentation
        (startEditing): Fixed to add editing container to the tree.
        (checkForClickInExpandControl): Fixed API documentation.
        (editingStopped): Added code to remove listeners and container.
        (editingCanceled): Similar.
        (mousePressed): Updated to stop editing when a different cell 
        is clicked.
        (treeNodesChanged): Called repaint.
        (treeNodesRemoved): Likewise.
        (treeStructureChanged): Likewise.
        (paintNode): Updated to paint a node that is being edited.
        (paintRecursive): Fixed API documentation.
        * javax/swing/tree/DefaultTreeCellEditor.java
        (paint): Fixed to paint icon and text box in correct location 
        with correct spacing.
        (doLayout): Fixed API documentation.
        (DefaultTreeCellEditor): Took out call to configure editing 
        component.
        (configureEditingComponent): Initialized editing icon.
        (getTreeCellEditorComponent): Took out code to stop editing. 
        Not needed.
        (addCellEditorListener): Passed on to realEditor.
        (removeCellEditorListener): Likewise.

Index: javax/swing/JPasswordField.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/JPasswordField.java,v
retrieving revision 1.13
diff -u -r1.13 JPasswordField.java
--- javax/swing/JPasswordField.java	25 Aug 2005 14:37:11 -0000	1.13
+++ javax/swing/JPasswordField.java	29 Aug 2005 21:05:34 -0000
@@ -224,7 +224,8 @@
       }
     catch (BadLocationException ble)
       {
-        throw new AssertionError("This should not happen");
+        // This should never happen.
+        throw new AssertionError(ble);
       }
   }
Index: javax/swing/plaf/basic/BasicTreeUI.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicTreeUI.java,v
retrieving revision 1.68
diff -u -r1.68 BasicTreeUI.java
--- javax/swing/plaf/basic/BasicTreeUI.java	23 Aug 2005 21:17:39 -0000	1.68
+++ javax/swing/plaf/basic/BasicTreeUI.java	29 Aug 2005 21:05:34 -0000
@@ -71,6 +71,7 @@
 import javax.swing.JComponent;
 import javax.swing.JScrollBar;
 import javax.swing.JScrollPane;
+import javax.swing.JTextField;
 import javax.swing.JTree;
 import javax.swing.SwingUtilities;
 import javax.swing.Timer;
@@ -516,7 +517,11 @@
    */
   protected void setCellEditor(TreeCellEditor editor)
   {
-    cellEditor = editor;
+    if (editor != null) 
+      {
+        cellEditor = editor;
+        createdCellEditor = true;
+      }
   }
 
   /**
@@ -737,10 +742,7 @@
   public boolean stopEditing(JTree tree)
   {
     if (isEditing(tree))
-      {
-        completeEditing();
         return getCellEditor().stopCellEditing();
-      }
     return true;
   }
 
@@ -1092,7 +1094,10 @@
   protected void updateCellEditor()
   {
     if (tree.isEditable() && cellEditor == null)
-      cellEditor = createDefaultCellEditor();
+      {
+        cellEditor = createDefaultCellEditor();
+        createdCellEditor = true;
+      }
   }
 
   /**
@@ -1189,7 +1194,6 @@
     tree.addKeyListener(keyListener);
     tree.addPropertyChangeListener(selectionModelPropertyChangeListener);
     tree.addComponentListener(componentListener);
-    cellEditor.addCellEditorListener(cellEditorListener);
     tree.addTreeExpansionListener(treeExpansionListener);
     if (treeModel != null)
       treeModel.addTreeModelListener(treeModelListener);
@@ -1206,12 +1210,10 @@
     installDefaults((JTree) c);
     tree = (JTree) c;
     
-    cellEditor = createDefaultCellEditor();
     currentCellRenderer = createDefaultCellRenderer();
     rendererPane = createCellRendererPane();
     
     createdRenderer = true;
-    createdCellEditor = true;
     
     TreeModel mod = tree.getModel();
     setModel(mod);
@@ -1262,8 +1264,9 @@
    *        components
    */
   public void paint(Graphics g, JComponent c)
-  {
+  {    
     JTree tree = (JTree) c;
+    
     TreeModel mod = tree.getModel();
     if (mod != null)
       {
@@ -1282,8 +1285,10 @@
   /**
    * Ensures that the rows identified by beginRow through endRow are visible.
    * 
-   * @param beginRow is the first row
-   * @param endRow is the last row
+   * @param beginRow
+   *          is the first row
+   * @param endRow
+   *          is the last row
    */
   protected void ensureRowsAreVisible(int beginRow, int endRow)
   {
@@ -1450,33 +1455,43 @@
         x = event.getX();
         y = event.getY();
       }
-    
+
+    updateCellEditor();
     TreeCellEditor ed = getCellEditor();
-    if (ed == null)
-      updateCellEditor();
-    if(ed != null && ed.isCellEditable(event) && ed.shouldSelectCell(event))
+    if (ed != null && ed.shouldSelectCell(event) && ed.isCellEditable(event))
       {
         editingPath = path;
         editingRow = tree.getRowForPath(editingPath);
-        Object val = editingPath.getLastPathComponent();
-        boolean isLeaf = tree.getModel().isLeaf(val);
-        boolean expanded = tree.isExpanded(editingPath);
-        editingComponent = ed.getTreeCellEditorComponent(
-                     tree, val, true, expanded, isLeaf, editingRow);
         cellEditor.addCellEditorListener(cellEditorListener);
         stopEditingInCompleteEditing = false;
+        Object val = editingPath.getLastPathComponent();
+        boolean expanded = tree.isExpanded(editingPath);
+
+        editingComponent = ed.getTreeCellEditorComponent(tree, val, true,
+                                                         expanded,
+                                                         isLeaf(editingRow),
+                                                         editingRow);
+        
+        editingComponent.getParent().setVisible(true);
+        editingComponent.getParent().validate();
+        tree.add(editingComponent.getParent());
+        editingComponent.getParent().validate();
+        ((JTextField) editingComponent).requestFocusInWindow(false);
         return true;
       }
     return false;
   }
 
   /**
-   * If the <code>mouseX</code> and <code>mouseY</code> are in the expand
-   * or collapse region of the row, this will toggle the row.
+   * If the <code>mouseX</code> and <code>mouseY</code> are in the expand or
+   * collapse region of the row, this will toggle the row.
    * 
-   * @param path the path we are concerned with
-   * @param mouseX is the cursor's x position
-   * @param mouseY is the cursor's y position
+   * @param path
+   *          the path we are concerned with
+   * @param mouseX
+   *          is the cursor's x position
+   * @param mouseY
+   *          is the cursor's y position
    */
   protected void checkForClickInExpandControl(TreePath path, int mouseX,
                                               int mouseY)
@@ -1688,9 +1703,12 @@
     {
       BasicTreeUI.this.editingPath = null;
       BasicTreeUI.this.editingRow = -1;
+      if (editingComponent != null)
+        BasicTreeUI.this.tree.remove(editingComponent.getParent());
       BasicTreeUI.this.editingComponent = null;
+      BasicTreeUI.this.cellEditor.removeCellEditorListener(cellEditorListener);
       BasicTreeUI.this.cellEditor = null;
-      BasicTreeUI.this.tree.repaint();
+      BasicTreeUI.this.createdCellEditor = false;
     }
 
     /**
@@ -1703,9 +1721,12 @@
     {
       BasicTreeUI.this.editingPath = null;
       BasicTreeUI.this.editingRow = -1;
+      if (editingComponent != null)
+        BasicTreeUI.this.tree.remove(editingComponent.getParent());
       BasicTreeUI.this.editingComponent = null;
+      BasicTreeUI.this.cellEditor.removeCellEditorListener(cellEditorListener);
       BasicTreeUI.this.cellEditor = null;
-      BasicTreeUI.this.tree.repaint();
+      BasicTreeUI.this.createdCellEditor = false;
     }
   }// CellEditorHandler
 
@@ -1995,53 +2024,57 @@
 
       if (path != null)
         {
-          boolean inBounds = false;
-          boolean cntlClick = false;
-          Rectangle bounds = BasicTreeUI.this.getPathBounds(
-                                                            BasicTreeUI.this.tree,
-                                                            path);
-
-          bounds.x -= rightChildIndent - 4;
-          bounds.width += rightChildIndent + 4;
-
-          if (bounds.contains(click.x, click.y))
-            inBounds = true;
-          else if (BasicTreeUI.this.hasControlIcons()
-                   && (click.x < (bounds.x - rightChildIndent + 5) 
-                       && click.x > (bounds.x - rightChildIndent - 5)))
-            cntlClick = true;
+          if (!path.equals(BasicTreeUI.this.tree.getLeadSelectionPath()))
+            {
+              if (BasicTreeUI.this.tree.isEditing())
+                BasicTreeUI.this.tree.stopEditing();
+            }
 
-          if ((inBounds || cntlClick) && BasicTreeUI.this.tree.isVisible(path))
+          if (!BasicTreeUI.this.tree.isEditing())
             {
-              if (!cntlClick && !BasicTreeUI.this.isLeaf(row))
+              boolean inBounds = false;
+              boolean cntlClick = false;
+              Rectangle bounds = BasicTreeUI.this.
+                              getPathBounds(BasicTreeUI.this.tree, path);
+
+              bounds.x -= rightChildIndent - 4;
+              bounds.width += rightChildIndent + 4;
+
+              if (bounds.contains(click.x, click.y))
+                inBounds = true;
+              else if (BasicTreeUI.this.hasControlIcons()
+                       && (click.x < (bounds.x - rightChildIndent + 5) && 
+                           click.x > (bounds.x - rightChildIndent - 5)))
+                cntlClick = true;
+
+              if ((inBounds || cntlClick)
+                  && BasicTreeUI.this.tree.isVisible(path))
                 {
-                  Object cell = path.getLastPathComponent();
-                  if (lastClicked != null && lastClicked.equals(cell))
-                    clickCount = 2;
-                  else
+                  if (!cntlClick && !BasicTreeUI.this.isLeaf(row))
                     {
-                      lastClicked = cell;
-                      clickCount = 1;
+                      Object cell = path.getLastPathComponent();
+                      if (lastClicked != null && lastClicked.equals(cell))
+                        clickCount = 2;
+                      else
+                        {
+                          lastClicked = cell;
+                          clickCount = 1;
+                        }
                     }
-                }
 
-              if (clickCount == 2 || cntlClick == true)
-                {
-                  clickCount = 0;
-                  lastClicked = null;
-                  BasicTreeUI.this.tree.getSelectionModel().clearSelection();
-                  if (BasicTreeUI.this.tree.isExpanded(path))
-                    BasicTreeUI.this.tree.collapsePath(path);
-                  else
-                    BasicTreeUI.this.tree.expandPath(path);
-                }
+                  if (clickCount == 2 || cntlClick == true)
+                    {
+                      clickCount = 0;
+                      lastClicked = null;
+                      BasicTreeUI.this.tree.getSelectionModel().clearSelection();
+                      if (BasicTreeUI.this.tree.isExpanded(path))
+                        BasicTreeUI.this.tree.collapsePath(path);
+                      else
+                        BasicTreeUI.this.tree.expandPath(path);
+                    }
 
-              BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, path);
-              
-              // If editing, but the moved to another cell then stop editing
-              if (!path.equals(BasicTreeUI.this.tree.getLeadSelectionPath()))
-                if (BasicTreeUI.this.tree.isEditing())
-                  BasicTreeUI.this.tree.stopEditing();
+                  BasicTreeUI.this.selectPath(BasicTreeUI.this.tree, path);
+                }
             }
         }
     }
@@ -2377,6 +2410,7 @@
      */
     public void treeNodesChanged(TreeModelEvent e)
     {
+      BasicTreeUI.this.tree.repaint();
     }
 
     /**
@@ -2388,6 +2422,7 @@
      */
     public void treeNodesInserted(TreeModelEvent e)
     {
+      BasicTreeUI.this.tree.repaint();
     }
 
     /**
@@ -2402,6 +2437,7 @@
      */
     public void treeNodesRemoved(TreeModelEvent e)
     {
+      BasicTreeUI.this.tree.repaint();
     }
 
     /**
@@ -2415,6 +2451,7 @@
      */
     public void treeStructureChanged(TreeModelEvent e)
     {
+      BasicTreeUI.this.tree.repaint();
     }
   }// TreeModelHandler
 
@@ -2646,18 +2683,30 @@
 
     if (tree.isVisible(curr))
       {
-        TreeCellRenderer dtcr = tree.getCellRenderer();
-        if (dtcr == null)
-          dtcr = createDefaultCellRenderer();
-
         if (!isLeaf)
           expanded = tree.isExpanded(curr);
 
-        Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
-                                                        expanded, isLeaf, 0,
-                                                        false);
-        rendererPane.paintComponent(g, c, c.getParent(), getCellBounds(x, y,
-                                                                       node));
+        if (editingComponent != null && editingPath != null && isEditing(tree)
+            && node.equals(editingPath.getLastPathComponent()))
+          {
+            Rectangle bounds = getPathBounds(tree, editingPath);
+              rendererPane.paintComponent(g, editingComponent.getParent(), null,
+                                          new Rectangle(0, 0, bounds.width, 
+                                                        bounds.height));
+          }
+        else
+          {
+            TreeCellRenderer dtcr = tree.getCellRenderer();
+            if (dtcr == null)
+              dtcr = createDefaultCellRenderer();
+
+            Component c = dtcr.getTreeCellRendererComponent(tree, node,
+                                                            selected, expanded,
+                                                            isLeaf, 0, false);
+
+            rendererPane.paintComponent(g, c, c.getParent(),
+                                        getCellBounds(x, y, node));
+          }
       }
   }
 
@@ -2665,20 +2714,27 @@
    * Recursively paints all elements of the tree Package private for use in
    * inner classes.
    * 
-   * @param g the Graphics context in which to paint
-   * @param indentation of the current object
-   * @param descent is the number of elements drawn
-   * @param childNumber is the index of the current child in the tree
-   * @param depth is the depth of the current object in the tree
-   * @param tree is the tree to draw to
-   * @param mod is the TreeModel we are using to draw
-   * @param curr is the current object to draw
-   * 
+   * @param g
+   *          the Graphics context in which to paint
+   * @param indentation
+   *          of the current object
+   * @param descent
+   *          is the number of elements drawn
+   * @param childNumber
+   *          is the index of the current child in the tree
+   * @param depth
+   *          is the depth of the current object in the tree
+   * @param tree
+   *          is the tree to draw to
+   * @param mod
+   *          is the TreeModel we are using to draw
+   * @param curr
+   *          is the current object to draw
    * @return int - current descent of the tree
    */
   int paintRecursive(Graphics g, int indentation, int descent, int childNumber,
                      int depth, JTree tree, TreeModel mod, Object curr)
-  {
+  {    
     Rectangle clip = g.getClipBounds();
     if (indentation > clip.x + clip.width + rightChildIndent
         || descent > clip.y + clip.height + getRowHeight())
Index: javax/swing/tree/DefaultTreeCellEditor.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/tree/DefaultTreeCellEditor.java,v
retrieving revision 1.11
diff -u -r1.11 DefaultTreeCellEditor.java
--- javax/swing/tree/DefaultTreeCellEditor.java	24 Aug 2005 20:37:37 -0000	1.11
+++ javax/swing/tree/DefaultTreeCellEditor.java	29 Aug 2005 21:05:34 -0000
@@ -115,39 +115,49 @@
     }
 
     /**
-     * Overrides Container.paint to paint the node's icon and use 
-     * the selection color for the background.
+     * Overrides Container.paint to paint the node's icon and use the selection
+     * color for the background.
      * 
-     * @param g - the specified Graphics window
+     * @param g -
+     *          the specified Graphics window
      */
     public void paint(Graphics g)
     {
-      int textIconGap = 4; // default value
-      Rectangle vr = new Rectangle();
-      Rectangle ir = new Rectangle();
-      Rectangle tr = new Rectangle();
+      lastPath = tree.getSelectionPath();
+      Rectangle tr = tree.getPathBounds(lastPath);
       
-      FontMetrics fm = editingComponent.getToolkit().getFontMetrics(getFont());
-      SwingUtilities.layoutCompoundLabel(((JComponent) editingComponent), fm,
-           ((JTextField) editingComponent).getText(), editingIcon,
-           JTextField.LEFT, JTextField.LEFT, JTextField.LEFT, JTextField.LEFT, 
-           vr, ir, tr, 4);
-            
-      Rectangle cr = tr.union(ir);
-      cr.width += offset;
-      
-      // paint icon
-      if (DefaultTreeCellEditor.this.editingIcon != null)
-        DefaultTreeCellEditor.this.editingIcon.paintIcon(DefaultTreeCellEditor.
-                                        this.editingComponent, g, cr.x, cr.y);
-
+      if (tr != null)
+        {
+          Insets i = ((DefaultTextField) editingComponent).getBorder()
+                                                  .getBorderInsets(this);
+          int textIconGap = 3;
+          tr.height -= i.top;
+          tr.x -= i.left;
+          
+          // paints icon
+          if (editingIcon == null)
+            editingIcon = renderer.getIcon();
+          if (editingIcon != null)
+            {
+              editingIcon.paintIcon(this, g, tr.x - editingIcon.
+                                              getIconWidth()/2, tr.y + i.top + i.bottom);
+              tr.x += editingIcon.getIconWidth()/2 + textIconGap;
+            }
+          
+          tr.width += offset;
+          
+          // paint background
+          g.translate(tr.x, tr.y);
+          editingComponent.setSize(new Dimension(tr.width, tr.height));
+          editingComponent.paint(g);
+          g.translate(-tr.x, -tr.y);
+        }
       super.paint(g);
-      (new CellRendererPane()).paintComponent(g, editingComponent, this, cr);
     }
 
     /**
-     * Lays out this Container. If editing, the editor will be placed 
-     * at offset in the x direction and 0 for y.
+     * Lays out this Container. If editing, the editor will be placed at offset
+     * in the x direction and 0 for y.
      */
     public void doLayout()
     {
@@ -330,8 +340,6 @@
       editor = createTreeCellEditor();
     realEditor = editor;
     
-    configureEditingComponent(tree, renderer, realEditor);
-    
     editingContainer = createContainer();
     UIDefaults defaults = UIManager.getLookAndFeelDefaults();
     setFont(defaults.getFont("Tree.font"));
@@ -361,7 +369,18 @@
             boolean isLeaf = tree.getModel().isLeaf(val);
             boolean expanded = tree.isExpanded(lastPath);
             determineOffset(tree, val, true, expanded, isLeaf, lastRow);
-            editingComponent = editor.getTreeCellEditorComponent(tree, val,
+            
+            // set up icon
+            if (isLeaf)
+              renderer.setIcon(renderer.getLeafIcon());
+            else if (expanded)
+              renderer.setIcon(renderer.getOpenIcon());
+            else
+              renderer.setIcon(renderer.getClosedIcon());
+            
+            editingIcon = renderer.getIcon();
+            
+            editingComponent = getTreeCellEditorComponent(tree, val,
                                                                  true,
                                                                  expanded,
                                                                  isLeaf,
@@ -461,14 +480,9 @@
   {
     if (realEditor == null)
       createTreeCellEditor();
-    
-    Component c = realEditor.getTreeCellEditorComponent(tree, value, isSelected,
-                                                             expanded, leaf, row);
-    if (tree != null && editingComponent != null)
-        if (tree.isEditing())
-          tree.stopEditing();
-    
-    return c;
+
+    return realEditor.getTreeCellEditorComponent(tree, value, isSelected,
+                                                        expanded, leaf, row);
   }
 
   /**
@@ -556,7 +570,7 @@
    */
   public void addCellEditorListener(CellEditorListener listener)
   {
-    listenerList.add(CellEditorListener.class, listener);
+    realEditor.addCellEditorListener(listener);
   }
 
   /**
@@ -566,7 +580,7 @@
    */
   public void removeCellEditorListener(CellEditorListener listener)
   {
-    listenerList.remove(CellEditorListener.class, listener);
+    realEditor.removeCellEditorListener(listener);
   }
 
   /**
_______________________________________________
Classpath-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to