summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java')
-rw-r--r--libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java297
1 files changed, 145 insertions, 152 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
index f2ebcfca9ac..1c6e6c5e502 100644
--- a/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/libjava/classpath/javax/swing/plaf/basic/BasicTreeUI.java
@@ -45,6 +45,7 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
+import java.awt.Label;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
@@ -114,9 +115,18 @@ import javax.swing.tree.TreeSelectionModel;
* @see javax.swing.JTree
* @author Lillian Angel (langel@redhat.com)
* @author Sascha Brawer (brawer@dandelis.ch)
+ * @author Audrius Meskauskas (audriusa@bioinformatics.org)
*/
public class BasicTreeUI extends TreeUI
{
+ /**
+ * The tree cell editing may be started by the single mouse click on the
+ * selected cell. To separate it from the double mouse click, the editing
+ * session starts after this time (in ms) after that single click, and only
+ * no other clicks were performed during that time.
+ */
+ static int WAIT_TILL_EDITING = 900;
+
/** Collapse Icon for the tree. */
protected transient Icon collapsedIcon;
@@ -225,12 +235,6 @@ public class BasicTreeUI extends TreeUI
/** Set to true if the editor has a different size than the renderer. */
protected boolean editorHasDifferentSize;
- /** The action listener for the editor's Timer. */
- Timer editorTimer = new EditorUpdateTimer();
-
- /** The new value of the node after editing. */
- Object newVal;
-
/** The action bound to KeyStrokes. */
TreeAction action;
@@ -266,6 +270,20 @@ public class BasicTreeUI extends TreeUI
private TreeExpansionListener treeExpansionListener;
private TreeModelListener treeModelListener;
+
+ /**
+ * This timer fires the editing action after about 1200 ms if not reset during
+ * that time. It handles the editing start with the single mouse click
+ * (and not the double mouse click) on the selected tree node.
+ */
+ Timer startEditTimer;
+
+ /**
+ * The special value of the mouse event is sent indicating that this is not
+ * just the mouse click, but the mouse click on the selected node. Sending
+ * such event forces to start the cell editing session.
+ */
+ static final MouseEvent EDIT = new MouseEvent(new Label(), 7,7,7,7,7,7, false);
/**
* Creates a new BasicTreeUI object.
@@ -303,7 +321,7 @@ public class BasicTreeUI extends TreeUI
{
return new BasicTreeUI();
}
-
+
/**
* Returns the Hash color.
*
@@ -796,7 +814,10 @@ public class BasicTreeUI extends TreeUI
public boolean stopEditing(JTree tree)
{
if (isEditing(tree))
- completeEditing(true, false, false);
+ {
+ completeEditing(false, false, true);
+ finish();
+ }
return !isEditing(tree);
}
@@ -807,9 +828,12 @@ public class BasicTreeUI extends TreeUI
* is the tree to cancel the editing session on.
*/
public void cancelEditing(JTree tree)
- {
- if (isEditing(tree))
- completeEditing(false, true, false);
+ {
+ // There is no need to send the cancel message to the editor,
+ // as the cancellation event itself arrives from it. This would
+ // only be necessary when cancelling the editing programatically.
+ completeEditing(false, false, false);
+ finish();
}
/**
@@ -1213,6 +1237,7 @@ public class BasicTreeUI extends TreeUI
protected void updateCachedPreferredSize()
{
int maxWidth = 0;
+ updateCurrentVisiblePath();
boolean isLeaf = false;
if (currentVisiblePath != null)
{
@@ -1246,7 +1271,7 @@ public class BasicTreeUI extends TreeUI
protected void pathWasExpanded(TreePath path)
{
validCachedPreferredSize = false;
- tree.repaint();
+ tree.repaint();
}
/**
@@ -1271,7 +1296,6 @@ public class BasicTreeUI extends TreeUI
leftChildIndent = UIManager.getInt("Tree.leftChildIndent");
setRowHeight(UIManager.getInt("Tree.rowHeight"));
tree.setRowHeight(getRowHeight());
- tree.requestFocusInWindow(false);
tree.setScrollsOnExpand(UIManager.getBoolean("Tree.scrollsOnExpand"));
setExpandedIcon(UIManager.getIcon("Tree.expandedIcon"));
setCollapsedIcon(UIManager.getIcon("Tree.collapsedIcon"));
@@ -1621,7 +1645,14 @@ public class BasicTreeUI extends TreeUI
}
if (messageTree)
- treeModel.valueForPathChanged(tree.getLeadSelectionPath(), newVal);
+ {
+ TreeCellEditor editor = getCellEditor();
+ if (editor != null)
+ {
+ Object value = editor.getCellEditorValue();
+ treeModel.valueForPathChanged(tree.getLeadSelectionPath(), value);
+ }
+ }
}
/**
@@ -1636,44 +1667,48 @@ public class BasicTreeUI extends TreeUI
*/
protected boolean startEditing(TreePath path, MouseEvent event)
{
- int x;
- int y;
- if (event == null)
- {
- Rectangle bounds = getPathBounds(tree, path);
- x = bounds.x;
- y = bounds.y;
- }
- else
- {
- x = event.getX();
- y = event.getY();
- }
+ // Force to recalculate the maximal row height.
+ maxHeight = 0;
+
+ // Force to recalculate the cached preferred size.
+ validCachedPreferredSize = false;
updateCellEditor();
TreeCellEditor ed = getCellEditor();
- if (ed != null && ed.shouldSelectCell(event) && ed.isCellEditable(event))
+
+ if (ed != null
+ && (event == EDIT || ed.shouldSelectCell(event))
+ && ed.isCellEditable(event))
{
+ Rectangle bounds = getPathBounds(tree, path);
+
+ // Extend the right boundary till the tree width.
+ bounds.width = tree.getWidth() - bounds.x;
+
editingPath = path;
editingRow = tree.getRowForPath(editingPath);
- Object val = editingPath.getLastPathComponent();
- cellEditor.addCellEditorListener(cellEditorListener);
+ Object value = editingPath.getLastPathComponent();
+
stopEditingInCompleteEditing = false;
boolean expanded = tree.isExpanded(editingPath);
isEditing = true;
- editingComponent = ed.getTreeCellEditorComponent(tree, val, true,
+ editingComponent = ed.getTreeCellEditorComponent(tree, value, true,
expanded,
isLeaf(editingRow),
editingRow);
- editingComponent.getParent().setVisible(true);
- editingComponent.getParent().validate();
- tree.add(editingComponent.getParent());
- editingComponent.getParent().validate();
- validCachedPreferredSize = false;
-
- ((JTextField) editingComponent).requestFocusInWindow(false);
- editorTimer.start();
+
+ // Remove all previous components (if still present). Only one
+ // container with the editing component inside is allowed in the tree.
+ tree.removeAll();
+
+ // The editing component must be added to its container. We add the
+ // container, not the editing component itself.
+ Component container = editingComponent.getParent();
+ container.setBounds(bounds);
+ tree.add(container);
+ editingComponent.requestFocus();
+
return true;
}
return false;
@@ -1922,7 +1957,7 @@ public class BasicTreeUI extends TreeUI
tree.clearSelection();
if (tree.isEditing() && !e.getActionCommand().equals("startEditing"))
- tree.cancelEditing();
+ tree.stopEditing();
tree.scrollPathToVisible(lead);
}
@@ -1957,51 +1992,7 @@ public class BasicTreeUI extends TreeUI
}
}
- /**
- * The timer that updates the editor component.
- */
- private class EditorUpdateTimer extends Timer implements ActionListener
- {
- /**
- * Creates a new EditorUpdateTimer object with a default delay of 0.3
- * seconds.
- */
- public EditorUpdateTimer()
- {
- super(300, null);
- addActionListener(this);
- }
-
- /**
- * Lets the caret blink and repaints the table.
- */
- public void actionPerformed(ActionEvent ev)
- {
- Caret c = ((JTextField) editingComponent).getCaret();
- if (c != null)
- c.setVisible(!c.isVisible());
- tree.repaint();
- }
-
- /**
- * Updates the blink delay according to the current caret.
- */
- public void update()
- {
- stop();
- Caret c = ((JTextField) editingComponent).getCaret();
- if (c != null)
- {
- setDelay(c.getBlinkRate());
- if (((JTextField) editingComponent).isEditable())
- start();
- else
- c.setVisible(false);
- }
- }
- }
-
- /**
+ /**
* Updates the preferred size when scrolling, if necessary.
*/
public class ComponentHandler extends ComponentAdapter implements
@@ -2089,29 +2080,7 @@ public class BasicTreeUI extends TreeUI
*/
public void editingStopped(ChangeEvent e)
{
- editingPath = null;
- editingRow = -1;
- stopEditingInCompleteEditing = false;
- if (editingComponent != null)
- {
- tree.remove(editingComponent.getParent());
- editingComponent = null;
- }
- if (cellEditor != null)
- {
- newVal = ((JTextField) getCellEditor().getCellEditorValue()).getText();
- completeEditing(false, false, true);
- if (cellEditor instanceof DefaultTreeCellEditor)
- tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
- cellEditor.removeCellEditorListener(cellEditorListener);
- setCellEditor(null);
- createdCellEditor = false;
- }
- isEditing = false;
- tree.requestFocusInWindow(false);
- editorTimer.stop();
- validCachedPreferredSize = false;
- tree.repaint();
+ stopEditing(tree);
}
/**
@@ -2123,25 +2092,7 @@ public class BasicTreeUI extends TreeUI
*/
public void editingCanceled(ChangeEvent e)
{
- editingPath = null;
- editingRow = -1;
- stopEditingInCompleteEditing = false;
- if (editingComponent != null)
- tree.remove(editingComponent.getParent());
- editingComponent = null;
- if (cellEditor != null)
- {
- if (cellEditor instanceof DefaultTreeCellEditor)
- tree.removeTreeSelectionListener((DefaultTreeCellEditor) cellEditor);
- cellEditor.removeCellEditorListener(cellEditorListener);
- setCellEditor(null);
- createdCellEditor = false;
- }
- tree.requestFocusInWindow(false);
- editorTimer.stop();
- isEditing = false;
- validCachedPreferredSize = false;
- tree.repaint();
+ cancelEditing(tree);
}
}// CellEditorHandler
@@ -2261,7 +2212,15 @@ public class BasicTreeUI extends TreeUI
* is the mouse event that occured
*/
public void mousePressed(MouseEvent e)
- {
+ {
+ // Any mouse click cancels the previous waiting edit action, initiated
+ // by the single click on the selected node.
+ if (startEditTimer != null)
+ {
+ startEditTimer.stop();
+ startEditTimer = null;
+ }
+
Point click = e.getPoint();
TreePath path = getClosestPathForLocation(tree, click.x, click.y);
@@ -2298,9 +2257,37 @@ public class BasicTreeUI extends TreeUI
{
if (inBounds)
{
- selectPath(tree, path);
- if (e.getClickCount() == 2 && !isLeaf(row))
- toggleExpandState(path);
+ TreePath currentLead = tree.getLeadSelectionPath();
+ if (
+ currentLead != null &&
+ currentLead.equals(path) &&
+ e.getClickCount() == 1 &&
+ tree.isEditable()
+ )
+ {
+ // Schedule the editing session.
+ final TreePath editPath = path;
+
+ if (startEditTimer != null)
+ startEditTimer.stop();
+
+ startEditTimer = new Timer(WAIT_TILL_EDITING,
+ new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ startEditing(editPath, EDIT);
+ }
+ });
+ startEditTimer.setRepeats(false);
+ startEditTimer.start();
+ }
+ else
+ {
+ selectPath(tree, path);
+ if (e.getClickCount() == 2 && !isLeaf(row))
+ toggleExpandState(path);
+ }
}
if (cntlClick)
@@ -2686,7 +2673,7 @@ public class BasicTreeUI extends TreeUI
public class TreeHomeAction extends AbstractAction
{
- /** direction is either home or end */
+ /** The direction, either home or end */
protected int direction;
/**
@@ -2983,7 +2970,7 @@ public class BasicTreeUI extends TreeUI
public void valueChanged(TreeSelectionEvent event)
{
if (tree.isEditing())
- tree.cancelEditing();
+ tree.stopEditing();
}
}// TreeSelectionHandler
@@ -3650,25 +3637,14 @@ public class BasicTreeUI extends TreeUI
if (row != 0)
bounds.x += gap;
bounds.width = preferredSize.width + bounds.x;
- if (editingComponent != null && editingPath != null && isEditing(tree)
- && node.equals(editingPath.getLastPathComponent()))
- {
- rendererPane.paintComponent(g, editingComponent.getParent(), null,
- bounds);
- }
- else
- {
- TreeCellRenderer dtcr = tree.getCellRenderer();
- if (dtcr == null)
- dtcr = createDefaultCellRenderer();
-
- Component c = dtcr.getTreeCellRendererComponent(tree, node,
- selected,
- isExpanded, isLeaf,
- row,
- tree.hasFocus());
- rendererPane.paintComponent(g, c, c.getParent(), bounds);
- }
+ TreeCellRenderer dtcr = tree.getCellRenderer();
+ if (dtcr == null)
+ dtcr = createDefaultCellRenderer();
+
+ Component c = dtcr.getTreeCellRendererComponent(tree, node, selected,
+ isExpanded, isLeaf,
+ row, tree.hasFocus());
+ rendererPane.paintComponent(g, c, c.getParent(), bounds);
}
}
@@ -3801,4 +3777,21 @@ public class BasicTreeUI extends TreeUI
}
return null;
}
+
+ /**
+ * Finish the editing session.
+ */
+ void finish()
+ {
+ editingPath = null;
+ editingRow = -1;
+ stopEditingInCompleteEditing = false;
+ isEditing = false;
+ tree.removeAll();
+ validCachedPreferredSize = false;
+
+ // Repaint the region, where was the editing component.
+ tree.repaint(editingComponent.getParent().getBounds());
+ editingComponent = null;
+ }
} // BasicTreeUI
OpenPOWER on IntegriCloud