1 19 20 package org.netbeans.modules.favorites; 21 22 import java.awt.BorderLayout ; 23 import java.beans.BeanInfo ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.beans.PropertyVetoException ; 27 import java.io.ObjectStreamException ; 28 import java.util.Stack ; 29 import java.util.logging.Level ; 30 import java.util.logging.Logger ; 31 import javax.swing.ActionMap ; 32 import javax.swing.SwingUtilities ; 33 import javax.swing.text.DefaultEditorKit ; 34 import org.openide.awt.StatusDisplayer; 35 import org.openide.explorer.ExplorerManager; 36 import org.openide.explorer.ExplorerUtils; 37 import org.openide.explorer.view.BeanTreeView; 38 import org.openide.explorer.view.TreeView; 39 import org.openide.filesystems.FileObject; 40 import org.openide.filesystems.FileUtil; 41 import org.openide.loaders.DataObject; 42 import org.openide.loaders.DataObjectNotFoundException; 43 import org.openide.loaders.DataShadow; 44 import org.openide.nodes.Node; 45 import org.openide.nodes.NodeEvent; 46 import org.openide.nodes.NodeListener; 47 import org.openide.nodes.NodeMemberEvent; 48 import org.openide.nodes.NodeOp; 49 import org.openide.nodes.NodeReorderEvent; 50 import org.openide.util.HelpCtx; 51 import org.openide.util.NbBundle; 52 import org.openide.util.WeakListeners; 53 import org.openide.windows.TopComponent; 54 import org.openide.windows.WindowManager; 55 56 59 public class Tab extends TopComponent 60 implements Runnable , ExplorerManager.Provider { 61 static final long serialVersionUID =-8178367548546385799L; 62 63 64 private static final DataObject[] needToSelect = new DataObject[1]; 65 66 67 private static transient Tab DEFAULT; 68 69 70 transient protected TreeView view; 71 72 transient private PropertyChangeListener weakRcL; 73 transient private NodeListener weakNRcL; 74 75 transient private NodeListener rcListener; 76 77 transient private boolean valid = true; 78 79 private ExplorerManager manager; 80 81 82 private Tab() { 83 this.manager = new ExplorerManager(); 84 85 ActionMap map = this.getActionMap (); 86 map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(manager)); 87 map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(manager)); 88 map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(manager)); 89 map.put("delete", ExplorerUtils.actionDelete (manager, true)); 91 associateLookup (ExplorerUtils.createLookup (manager, map)); 93 } 94 95 public HelpCtx getHelpCtx () { 96 return new HelpCtx(Tab.class); 97 } 98 99 public ExplorerManager getExplorerManager() { 100 return manager; 101 } 102 103 104 protected String preferredID () { 105 return "favorites"; } 107 108 109 protected void componentShowing () { 110 super.componentShowing (); 111 112 if (view == null) { 113 view = initGui (); 114 115 view.getAccessibleContext().setAccessibleName( 116 NbBundle.getMessage( 117 Tab.class, "ACSN_ExplorerBeanTree")); 118 view.getAccessibleContext().setAccessibleDescription( 119 NbBundle.getMessage( 120 Tab.class, "ACSD_ExplorerBeanTree")); 121 } 122 123 run(); 124 } 125 126 130 protected TreeView initGui () { 131 TreeView view = new BeanTreeView(); 132 view.setRootVisible(false); 133 view.setDragSource (true); 134 setLayout(new BorderLayout ()); 135 add (view); 136 return view; 137 } 138 139 protected void componentActivated() { 140 ExplorerUtils.activateActions(manager, true); 141 } 142 protected void componentDeactivated() { 143 ExplorerUtils.activateActions(manager, false); 144 } 145 146 147 @SuppressWarnings ("deprecation") @Override 148 public void requestFocus () { 149 super.requestFocus(); 150 if (view != null) { 151 view.requestFocus(); 152 } 153 } 154 155 156 @SuppressWarnings ("deprecation") @Override 157 public boolean requestFocusInWindow () { 158 super.requestFocusInWindow(); 159 if (view != null) { 160 return view.requestFocusInWindow(); 161 } else { 162 return false; 163 } 164 } 165 166 168 public void setRootContext (Node rc) { 169 Node oldRC = getExplorerManager().getRootContext(); 170 if (weakRcL != null) { 172 oldRC.removePropertyChangeListener(weakRcL); 173 } 174 if (weakNRcL != null) { 175 oldRC.removeNodeListener(weakNRcL); 176 } 177 getExplorerManager().setRootContext(rc); 178 initializeWithRootContext(rc); 179 } 180 181 public Node getRootContext () { 182 return getExplorerManager().getRootContext(); 183 } 184 185 189 public void run() { 190 if (!valid) { 191 valid = true; 192 validateRootContext(); 193 } 194 } 195 196 202 protected void updateTitle () { 203 setName(getExplorerManager ().getRootContext().getDisplayName()); 205 } 206 207 private NodeListener rcListener () { 208 if (rcListener == null) { 209 rcListener = new RootContextListener(); 210 } 211 return rcListener; 212 } 213 214 216 private void initializeWithRootContext (Node rc) { 217 setIcon(rc.getIcon(BeanInfo.ICON_COLOR_16x16)); 219 setToolTipText(rc.getDisplayName()); 220 setName(rc.getDisplayName()); 221 updateTitle(); 222 if (weakRcL == null) { 224 weakRcL = WeakListeners.propertyChange( 225 rcListener(), rc 226 ); 227 } 228 rc.addPropertyChangeListener(weakRcL); 229 230 if (weakNRcL == null) { 231 weakNRcL = NodeOp.weakNodeListener ( 232 rcListener(), rc 233 ); 234 } 235 rc.addNodeListener(weakNRcL); 236 } 237 238 protected final void scheduleValidation() { 243 valid = false; 244 SwingUtilities.invokeLater(this); } 247 248 249 public void setName(String name) { 250 super.setName(name); 251 if (view != null) { 252 view.getAccessibleContext().setAccessibleName(name); 253 } 254 } 255 256 257 public void setToolTipText(String text) { 258 super.setToolTipText(text); 259 if (view != null) { 260 view.getAccessibleContext().setAccessibleDescription(text); 261 } 262 } 263 264 267 private final class RootContextListener implements NodeListener { 268 public void propertyChange (PropertyChangeEvent evt) { 269 String propName = evt.getPropertyName(); 270 Object source = evt.getSource(); 271 272 Node n = (Node)source; 274 if (Node.PROP_DISPLAY_NAME.equals(propName) || 275 Node.PROP_NAME.equals(propName)) { 276 setName(n.getDisplayName()); 277 } else if (Node.PROP_ICON.equals(propName)) { 278 setIcon(n.getIcon(BeanInfo.ICON_COLOR_16x16)); 279 } else if (Node.PROP_SHORT_DESCRIPTION.equals(propName)) { 280 setToolTipText(n.getShortDescription()); 281 } 282 } 283 284 public void nodeDestroyed(NodeEvent nodeEvent) { 285 Tab.this.close(); 287 } 288 289 public void childrenRemoved(NodeMemberEvent e) {} 290 public void childrenReordered(NodeReorderEvent e) {} 291 public void childrenAdded(NodeMemberEvent e) {} 292 293 } 295 297 public static synchronized Tab getDefault() { 298 if (DEFAULT == null) { 299 DEFAULT = new Tab(); 300 DEFAULT.scheduleValidation(); 305 } 306 307 return DEFAULT; 308 } 309 310 311 public static synchronized Tab findDefault() { 312 if(DEFAULT == null) { 313 TopComponent tc = WindowManager.getDefault().findTopComponent("favorites"); if(DEFAULT == null) { 315 Logger.getLogger(Tab.class.getName()).log(Level.WARNING, null, 316 new IllegalStateException ("Can not find project component for its ID. Returned " + 317 tc)); DEFAULT = new Tab(); 319 DEFAULT.scheduleValidation(); 321 } 322 } 323 324 return DEFAULT; 325 } 326 327 329 public int getPersistenceType() { 330 return TopComponent.PERSISTENCE_ALWAYS; 331 } 332 333 335 337 private static Node findClosestNode (DataObject obj, Node start, boolean useLogicalViews) { 338 DataObject original = obj; 339 340 Stack <DataObject> stack = new Stack <DataObject> (); 341 while (obj != null) { 342 stack.push(obj); 343 DataObject tmp = obj.getFolder(); 344 if (tmp == null) { 345 FileObject fo = FileUtil.getArchiveFile(obj.getPrimaryFile()); 348 if (fo != null) { 349 try { 350 obj = DataObject.find(fo); 351 stack.pop(); 353 } catch (DataObjectNotFoundException exc) { 354 obj = null; 355 } 356 } else { 357 obj = null; 358 } 359 } else { 360 obj = tmp; 361 } 362 } 363 364 Node current = start; 365 int topIdx = stack.size(); 366 int i = 0; 367 while (i < topIdx) { 368 Node n = findDataObject (current, stack.get (i)); 369 if (n != null) { 370 current = n; 371 topIdx = i; 372 i = 0; 373 } else { 374 i++; 375 } 376 } 377 if (!check(current, original) && useLogicalViews) { 378 Node[] children = current.getChildren().getNodes(); 379 for (int j = 0; j < children.length; j++) { 380 Node child = children[j]; 381 Node n = selectInLogicalViews(original, child); 382 if (check(n, original)) { 383 current = n; 384 break; 385 } 386 } 387 } 388 return current; 389 } 390 391 private static Node selectInLogicalViews(DataObject original, Node start) { 392 return start; 393 400 } 401 402 404 private boolean selectNode (DataObject obj, Node root) { 405 Node node = findClosestNode(obj, root, true); 406 try { 407 getExplorerManager ().setSelectedNodes (new Node[] { node }); 408 } catch (PropertyVetoException e) { 409 throw new IllegalStateException (); 411 } 412 return check(node, obj); 413 } 414 415 private static boolean check(Node node, DataObject obj) { 416 DataObject dObj = (DataObject)node.getLookup().lookup(DataObject.class); 417 if (obj == dObj) { 418 return true; 419 } 420 if (dObj instanceof DataShadow && obj == ((DataShadow)dObj).getOriginal()) { 421 return true; 422 } 423 return false; 424 } 425 426 430 private static Node findDataObject (Node node, DataObject obj) { 431 Node[] arr = node.getChildren ().getNodes (true); 432 for (int i = 0; i < arr.length; i++) { 433 DataShadow ds = (DataShadow) arr[i].getCookie (DataShadow.class); 434 if ((ds != null) && (obj == ds.getOriginal())) { 435 return arr[i]; 436 } else { 437 DataObject o = (DataObject) arr[i].getCookie (DataObject.class); 438 if ((o != null) && (obj == o)) { 439 return arr[i]; 440 } 441 } 442 } 443 return null; 444 } 445 446 448 protected void validateRootContext () { 449 Node projectsRc = Favorites.getNode (); 450 setRootContext(projectsRc); 451 } 452 453 454 455 protected boolean containsNode(DataObject obj) { 456 Node node = findClosestNode(obj, getExplorerManager ().getRootContext (), true); 457 return check(node, obj); 458 } 459 460 protected void doSelectNode (DataObject obj) { 461 Node root = getExplorerManager ().getRootContext (); 462 if (selectNode (obj, root)) { 463 requestActive(); 464 StatusDisplayer.getDefault().setStatusText(""); } else { 466 StatusDisplayer.getDefault().setStatusText(NbBundle.getMessage(Tab.class,"MSG_NodeNotFound")); 467 } 468 } 469 470 471 public Object readResolve() throws ObjectStreamException { 472 getDefault().scheduleValidation(); 473 return getDefault(); 474 } 475 476 } | Popular Tags |