diff --git a/openide.explorer/apichanges.xml b/openide.explorer/apichanges.xml
--- a/openide.explorer/apichanges.xml
+++ b/openide.explorer/apichanges.xml
@@ -50,6 +50,20 @@
Explorer API
+
+
+ TreeView.editNode
added
+
+
+
+
+
+ Added TreeView.editNode(Node)
to programmatically
+ enter inline-edit mode on a TreeView. Method is thread-safe.
+
+
+
+
Hide node icons in OutlineView and TreeView.
diff --git a/openide.explorer/manifest.mf b/openide.explorer/manifest.mf
--- a/openide.explorer/manifest.mf
+++ b/openide.explorer/manifest.mf
@@ -2,5 +2,5 @@
OpenIDE-Module: org.openide.explorer
OpenIDE-Module-Localizing-Bundle: org/openide/explorer/Bundle.properties
AutoUpdate-Essential-Module: true
-OpenIDE-Module-Specification-Version: 6.59
+OpenIDE-Module-Specification-Version: 6.60
diff --git a/openide.explorer/src/org/openide/explorer/view/TreeView.java b/openide.explorer/src/org/openide/explorer/view/TreeView.java
--- a/openide.explorer/src/org/openide/explorer/view/TreeView.java
+++ b/openide.explorer/src/org/openide/explorer/view/TreeView.java
@@ -141,6 +141,7 @@
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.openide.awt.QuickSearch;
+import org.openide.util.Parameters;
/**
@@ -620,6 +621,52 @@
});
}
+ /**
+ * Initiate inline-edit mode for a Node, expanding its parent
+ * and selecting it if necessary. This method is thread-safe.
+ *
+ * If this TreeView is not actually on-screen when the edit is
+ * initiated (for example, a call after the call to editNode() removes
+ * it from the AWT hierarchy) then this method logs an error and does
+ * nothing.
+ *
+ * @since 6.60
+ * @param node A node whose name should be edited visually by the user
+ */
+ public final void editNode(final Node node) {
+ Parameters.notNull("node", node); //NOI18N
+ //Do not use VisualizerNode.runSafe(), which will call
+ //EQ.invokeAndWait()
+ Mutex.EVENT.readAccess(new EditInitiator(node));
+ }
+
+ private final class EditInitiator implements Runnable {
+ private final Node node;
+ EditInitiator (Node target) {
+ this.node = target;
+ }
+
+ @Override
+ public void run() {
+ if (!isDisplayable()) {
+ Logger.getLogger(TreeView.class.getName()).log(
+ Level.WARNING, "Attempt to edit node {0} but " + //NOI18N
+ "component not on screen", node); //NOI18N
+ return;
+ }
+ lookupExplorerManager();
+ TreePath path = getTreePath(node);
+ if (path == null) {
+ throw new IllegalArgumentException ("Unknown node " + node); //NOI18N
+ }
+ if (!tree.isExpanded(path)) {
+ tree.expandPath(path);
+ }
+ tree.setSelectionPath(path);
+ tree.startEditingAtPath(path);
+ }
+ }
+
/** Test whether a node is expanded in the tree or not
* @param n the node to test
* @return true if the node is expanded
diff --git a/openide.explorer/src/org/openide/explorer/view/TreeViewCellEditor.java b/openide.explorer/src/org/openide/explorer/view/TreeViewCellEditor.java
--- a/openide.explorer/src/org/openide/explorer/view/TreeViewCellEditor.java
+++ b/openide.explorer/src/org/openide/explorer/view/TreeViewCellEditor.java
@@ -172,6 +172,10 @@
public void focusGained(FocusEvent evt) {
}
+ Ed ed() { //editNodeTest
+ return (Ed) realEditor;
+ }
+
/**
* This is invoked if a TreeCellEditor is not supplied in the constructor.
* It returns a TextField editor.
@@ -371,6 +375,10 @@
super(tf);
}
+ JTextField comp() { //editNodeTest
+ return (JTextField) super.getComponent();
+ }
+
/** Main method of the editor.
* @return component of editor
*/
diff --git a/openide.explorer/test/unit/src/org/openide/explorer/view/BeanTreeViewTest.java b/openide.explorer/test/unit/src/org/openide/explorer/view/BeanTreeViewTest.java
--- a/openide.explorer/test/unit/src/org/openide/explorer/view/BeanTreeViewTest.java
+++ b/openide.explorer/test/unit/src/org/openide/explorer/view/BeanTreeViewTest.java
@@ -69,6 +69,14 @@
import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
+import java.awt.EventQueue;
+import java.awt.event.HierarchyEvent;
+import java.awt.event.HierarchyListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.concurrent.CountDownLatch;
+import javax.swing.JTextField;
+import org.openide.explorer.view.TreeViewCellEditor.Ed;
/**
* Tests for class BeanTreeViewTest
@@ -539,4 +547,97 @@
return em;
}
}
+
+ public void testEditNode() throws Exception {
+ Children.Array kids = new Children.Array();
+ Node[] n = new Node[20];
+ Node node = null;
+ for (int i=0; i < n.length; i++) {
+ n[i] = new RenamableNode ("" + i);
+ if (i == 5) {
+ node = n[i]; //pick one to edit
+ }
+ }
+ kids.add(n);
+ final Node root = new AbstractNode (kids);
+ root.setDisplayName("Root");
+ final WL wl = new WL();
+ final F[] ff = new F[1];
+ EventQueue.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ ff[0] = new F(root);
+ ff[0].addWindowListener(wl);
+ ff[0].pack();
+ ff[0].setVisible(true);
+ }
+
+ });
+ wl.latch.await();
+ F f = ff[0];
+ //sanity check
+ assertTrue (f.isDisplayable());
+ assertTrue (f.isShowing());
+ assertTrue (f.view.isShowing());
+ JTree tree = f.view.tree;
+ TreeViewCellEditor ce = (TreeViewCellEditor) tree.getCellEditor();
+ Ed ed = ce.ed();
+ final JTextField comp = ed.comp();
+ final CountDownLatch latch = new CountDownLatch(1);
+ comp.addHierarchyListener(new HierarchyListener() {
+
+ @Override
+ public void hierarchyChanged(HierarchyEvent e) {
+ if (comp.isDisplayable()) {
+ latch.countDown();
+ }
+ }
+
+ });
+ f.view.editNode(node);
+ latch.await();
+ assertTrue (tree.isEditing());
+ assertTrue (comp.isDisplayable());
+ f.setVisible(false);
+ f.dispose();
+ }
+
+ private static final class RenamableNode extends AbstractNode {
+ RenamableNode (String name) {
+ super (Children.LEAF);
+ setDisplayName(name);
+ setName (name);
+ }
+
+ @Override
+ public boolean canRename() {
+ return true;
+ }
+ }
+
+ private static final class F extends JFrame implements ExplorerManager.Provider {
+ private final ExplorerManager mgr = new ExplorerManager();
+ private final BeanTreeView view = new BeanTreeView();
+ F(Node root) {
+ setContentPane(view);
+ mgr.setRootContext(root);
+ }
+
+ @Override
+ public ExplorerManager getExplorerManager() {
+ return mgr;
+ }
+
+ }
+
+ private static final class WL extends WindowAdapter {
+ CountDownLatch latch = new CountDownLatch(1);
+
+ @Override
+ public void windowOpened(WindowEvent e) {
+ super.windowOpened(e);
+ latch.countDown();
+ }
+ }
}