diff options
Diffstat (limited to 'javax/swing/tree/DefaultTreeCellEditor.java')
-rw-r--r-- | javax/swing/tree/DefaultTreeCellEditor.java | 322 |
1 files changed, 183 insertions, 139 deletions
diff --git a/javax/swing/tree/DefaultTreeCellEditor.java b/javax/swing/tree/DefaultTreeCellEditor.java index b0a4d8db8..4c10bfe1a 100644 --- a/javax/swing/tree/DefaultTreeCellEditor.java +++ b/javax/swing/tree/DefaultTreeCellEditor.java @@ -43,7 +43,6 @@ import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; -import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.event.ActionEvent; @@ -59,10 +58,10 @@ import javax.swing.Icon; import javax.swing.JTextField; import javax.swing.JTree; import javax.swing.SwingUtilities; +import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.CellEditorListener; -import javax.swing.event.ChangeEvent; import javax.swing.event.EventListenerList; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; @@ -77,12 +76,6 @@ public class DefaultTreeCellEditor implements ActionListener, TreeCellEditor, TreeSelectionListener { /** - * The number of the fast mouse clicks, required to start the editing - * session. - */ - static int CLICK_COUNT_TO_START = 3; - - /** * This container that appears on the tree during editing session. * It contains the editing component displays various other editor - * specific parts like editing icon. @@ -99,7 +92,7 @@ public class DefaultTreeCellEditor */ public EditorContainer() { - // Do nothing here. + setLayout(null); } /** @@ -111,12 +104,6 @@ public class DefaultTreeCellEditor // Do nothing here. } - public void setBounds(Rectangle bounds) - { - super.setBounds(bounds); - doLayout(); - } - /** * Overrides Container.paint to paint the node's icon and use the selection * color for the background. @@ -126,11 +113,20 @@ public class DefaultTreeCellEditor */ public void paint(Graphics g) { + // Paint editing icon. if (editingIcon != null) { // From the previous version, the left margin is taken as half // of the icon width. - editingIcon.paintIcon(this, g, 0, 0); + int y = Math.max(0, (getHeight() - editingIcon.getIconHeight()) / 2); + editingIcon.paintIcon(this, g, 0, y); + } + // Paint border. + Color c = getBorderSelectionColor(); + if (c != null) + { + g.setColor(c); + g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); } super.paint(g); } @@ -141,27 +137,33 @@ public class DefaultTreeCellEditor */ public void doLayout() { - // The offset of the editing component. - int eOffset; + if (editingComponent != null) + { + editingComponent.getPreferredSize(); + editingComponent.setBounds(offset, 0, getWidth() - offset, + getHeight()); + } + } - // Move the component to the left, leaving room for the editing icon: - if (editingIcon != null) - eOffset = editingIcon.getIconWidth(); + public Dimension getPreferredSize() + { + Dimension dim; + if (editingComponent != null) + { + dim = editingComponent.getPreferredSize(); + dim.width += offset + 5; + if (renderer != null) + { + Dimension r = renderer.getPreferredSize(); + dim.height = Math.max(dim.height, r.height); + } + if (editingIcon != null) + dim.height = Math.max(dim.height, editingIcon.getIconHeight()); + dim.width = Math.max(100, dim.width); + } else - eOffset = 0; - - Rectangle bounds = getBounds(); - Component c = getComponent(0); - c.setLocation(eOffset, 0); - - // Span the editing component near over all window width. - c.setSize(bounds.width - eOffset, bounds.height); - /* - * @specnote the Sun sets some more narrow editing component width (it is - * not documented how does it is calculated). However as our text field is - * still not able to auto - scroll horizontally, replicating such strategy - * would prevent adding extra characters to the text being edited. - */ + dim = new Dimension(0, 0); + return dim; } } @@ -227,46 +229,15 @@ public class DefaultTreeCellEditor */ public Dimension getPreferredSize() { - String s = getText(); - - Font f = getFont(); - - if (f != null) + Dimension size = super.getPreferredSize(); + if (renderer != null && DefaultTreeCellEditor.this.getFont() == null) { - FontMetrics fm = getToolkit().getFontMetrics(f); - - return new Dimension(SwingUtilities.computeStringWidth(fm, s), - fm.getHeight()); + size.height = renderer.getPreferredSize().height; } return renderer.getPreferredSize(); } } - /** - * Listens for the events from the realEditor. - */ - class RealEditorListener implements CellEditorListener - { - /** - * The method is called when the editing has been cancelled. - * @param event unused - */ - public void editingCanceled(ChangeEvent event) - { - cancelCellEditing(); - } - - /** - * The method is called after completing the editing session. - * - * @param event unused - */ - public void editingStopped(ChangeEvent event) - { - stopCellEditing(); - } - } - private EventListenerList listenerList = new EventListenerList(); /** @@ -367,21 +338,14 @@ public class DefaultTreeCellEditor public DefaultTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer, TreeCellEditor editor) { - setTree(tree); this.renderer = renderer; - - if (editor == null) - editor = createTreeCellEditor(); - else - editor.addCellEditorListener(new RealEditorListener()); - realEditor = editor; - - lastPath = tree.getLeadSelectionPath(); - tree.addTreeSelectionListener(this); + if (realEditor == null) + realEditor = createTreeCellEditor(); editingContainer = createContainer(); - setFont(UIManager.getFont("Tree.font")); - setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor")); + setTree(tree); + Color c = UIManager.getColor("Tree.editorBorderSelectionColor"); + setBorderSelectionColor(c); } /** @@ -505,19 +469,36 @@ public class DefaultTreeCellEditor * @return the component for editing */ public Component getTreeCellEditorComponent(JTree tree, Object value, - boolean isSelected, boolean expanded, + boolean isSelected, + boolean expanded, boolean leaf, int row) { - if (realEditor == null) - realEditor = createTreeCellEditor(); - - return realEditor.getTreeCellEditorComponent(tree, value, isSelected, - expanded, leaf, row); + setTree(tree); + lastRow = row; + determineOffset(tree, value, isSelected, expanded, leaf, row); + if (editingComponent != null) + editingContainer.remove(editingComponent); + + editingComponent = realEditor.getTreeCellEditorComponent(tree, value, + isSelected, + expanded, leaf, + row); + Font f = getFont(); + if (f == null) + { + if (renderer != null) + f = renderer.getFont(); + if (f == null) + f = tree.getFont(); + } + editingContainer.setFont(f); + prepareForEditing(); + return editingContainer; } /** * Returns the value currently being edited (requests it from the - * {@link realEditor}. + * {@link #realEditor}. * * @return the value currently being edited */ @@ -535,16 +516,48 @@ public class DefaultTreeCellEditor * @return true if editing can be started */ public boolean isCellEditable(EventObject event) - { - if (editingComponent == null) - configureEditingComponent(tree, renderer, realEditor); - - if (editingComponent != null && realEditor.isCellEditable(event)) + { + boolean ret = false; + boolean ed = false; + if (event != null) { - prepareForEditing(); - return true; + if (event.getSource() instanceof JTree) + { + setTree((JTree) event.getSource()); + if (event instanceof MouseEvent) + { + MouseEvent me = (MouseEvent) event; + TreePath path = tree.getPathForLocation(me.getX(), me.getY()); + ed = lastPath != null && path != null && lastPath.equals(path); + if (path != null) + { + lastRow = tree.getRowForPath(path); + Object val = path.getLastPathComponent(); + boolean isSelected = tree.isRowSelected(lastRow); + boolean isExpanded = tree.isExpanded(path); + TreeModel m = tree.getModel(); + boolean isLeaf = m.isLeaf(val); + determineOffset(tree, val, isSelected, isExpanded, isLeaf, + lastRow); + } + } + } } - return false; + if (! realEditor.isCellEditable(event)) + ret = false; + else + { + if (canEditImmediately(event)) + ret = true; + else if (ed && shouldStartEditingTimer(event)) + startEditingTimer(); + else if (timer != null && timer.isRunning()) + timer.stop(); + } + if (ret) + prepareForEditing(); + return ret; + } /** @@ -567,14 +580,13 @@ public class DefaultTreeCellEditor */ public boolean stopCellEditing() { - if (editingComponent != null) + boolean ret = false; + if (realEditor.stopCellEditing()) { - stopEditingTimer(); - tree.stopEditing(); - editingComponent = null; - return true; + finish(); + ret = true; } - return false; + return ret; } /** @@ -583,21 +595,15 @@ public class DefaultTreeCellEditor */ public void cancelCellEditing() { - if (editingComponent != null) - { - tree.cancelEditing(); - editingComponent = null; - } - stopEditingTimer(); + realEditor.cancelCellEditing(); + finish(); } - - /** - * Stop the editing timer, if it is installed and running. - */ - private void stopEditingTimer() + + private void finish() { - if (timer != null && timer.isRunning()) - timer.stop(); + if (editingComponent != null) + editingContainer.remove(editingComponent); + editingComponent = null; } /** @@ -640,10 +646,18 @@ public class DefaultTreeCellEditor */ public void valueChanged(TreeSelectionEvent e) { - tPath = lastPath; - lastPath = e.getNewLeadSelectionPath(); - lastRow = tree.getRowForPath(lastPath); - stopCellEditing(); + if (tree != null) + { + if (tree.getSelectionCount() == 1) + lastPath = tree.getSelectionPath(); + else + lastPath = null; + } + // TODO: We really should do the following here, but can't due + // to buggy DefaultTreeSelectionModel. This selection model + // should only fire if the selection actually changes. +// if (timer != null) +// timer.stop(); } /** @@ -653,6 +667,8 @@ public class DefaultTreeCellEditor */ public void actionPerformed(ActionEvent e) { + if (tree != null && lastPath != null) + tree.startEditingAtPath(lastPath); } /** @@ -664,7 +680,17 @@ public class DefaultTreeCellEditor */ protected void setTree(JTree newTree) { - tree = newTree; + if (tree != newTree) + { + if (tree != null) + tree.removeTreeSelectionListener(this); + tree = newTree; + if (tree != null) + tree.addTreeSelectionListener(this); + + if (timer != null) + timer.stop(); + } } /** @@ -675,10 +701,14 @@ public class DefaultTreeCellEditor */ protected boolean shouldStartEditingTimer(EventObject event) { - if ((event instanceof MouseEvent) && - ((MouseEvent) event).getClickCount() == 1) - return true; - return false; + boolean ret = false; + if (event instanceof MouseEvent) + { + MouseEvent me = (MouseEvent) event; + ret = SwingUtilities.isLeftMouseButton(me) && me.getClickCount() == 1 + && inHitRegion(me.getX(), me.getY()); + } + return ret; } /** @@ -686,8 +716,12 @@ public class DefaultTreeCellEditor */ protected void startEditingTimer() { - if (timer != null) - timer.start(); + if (timer == null) + { + timer = new Timer(1200, this); + timer.setRepeats(false); + } + timer.start(); } /** @@ -723,7 +757,6 @@ public class DefaultTreeCellEditor protected boolean inHitRegion(int x, int y) { Rectangle bounds = tree.getPathBounds(lastPath); - return bounds.contains(x, y); } @@ -739,13 +772,24 @@ public class DefaultTreeCellEditor protected void determineOffset(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { - renderer.getTreeCellRendererComponent(tree, value, isSelected, expanded, - leaf, row, true); - Icon c = renderer.getIcon(); - if (c != null) - offset = renderer.getIconTextGap() + c.getIconWidth(); + if (renderer != null) + { + if (leaf) + editingIcon = renderer.getLeafIcon(); + else if (expanded) + editingIcon = renderer.getOpenIcon(); + else + editingIcon = renderer.getClosedIcon(); + if (editingIcon != null) + offset = renderer.getIconTextGap() + editingIcon.getIconWidth(); + else + offset = renderer.getIconTextGap(); + } else - offset = 0; + { + editingIcon = null; + offset = 0; + } } /** @@ -754,8 +798,8 @@ public class DefaultTreeCellEditor */ protected void prepareForEditing() { - editingContainer.removeAll(); - editingContainer.add(editingComponent); + if (editingComponent != null) + editingContainer.add(editingComponent); } /** @@ -776,10 +820,10 @@ public class DefaultTreeCellEditor */ protected TreeCellEditor createTreeCellEditor() { - DefaultCellEditor editor = new DefaultCellEditor(new DefaultTreeCellEditor.DefaultTextField( - UIManager.getBorder("Tree.selectionBorder"))); - editor.addCellEditorListener(new RealEditorListener()); - editor.setClickCountToStart(CLICK_COUNT_TO_START); + Border border = UIManager.getBorder("Tree.editorBorder"); + JTextField tf = new DefaultTreeCellEditor.DefaultTextField(border); + DefaultCellEditor editor = new DefaultCellEditor(tf); + editor.setClickCountToStart(1); realEditor = editor; return editor; } |