1 19 20 package org.openide.src.nodes; 21 22 import java.awt.datatransfer.Transferable ; 23 import java.awt.datatransfer.DataFlavor ; 24 import java.beans.*; 25 import java.io.IOException ; 26 import java.lang.reflect.InvocationTargetException ; 27 import java.util.ResourceBundle ; 28 import java.util.Set ; 29 import java.util.HashSet ; 30 31 import org.openide.src.*; 32 import org.openide.nodes.*; 33 import org.openide.util.HelpCtx; 34 import org.openide.util.Mutex; 35 import org.openide.util.NbBundle; 36 import org.openide.util.WeakListeners; 37 import org.openide.util.actions.SystemAction; 38 import org.openide.util.datatransfer.ExTransferable; 39 40 56 public abstract class ElementNode extends AbstractNode implements IconStrings, ElementProperties { 57 58 static ResourceBundle bundle = NbBundle.getBundle(ElementNode.class); 59 60 private static ElementFormat invalidFormat; 61 62 63 protected static final SourceOptions sourceOptions = (SourceOptions) SourceOptions.findObject(SourceOptions.class, true); 64 65 66 private static final String [] ICON_AFFECTING_PROPERTIES = new String [] { 67 PROP_MODIFIERS 68 }; 69 70 71 protected Element element; 72 73 74 protected ElementFormat elementFormat = new ElementFormat (""); 76 77 protected boolean writeable; 78 79 80 private transient PropertyChangeListener listener; 81 82 89 public ElementNode(Element element, Children children, boolean writeable) { 90 super(children); 91 this.element = element; 92 this.writeable = writeable; 93 setIconBase(resolveIconBase()); 94 setDisplayName(getElementFormat().format(element)); 95 listener = createElementListener(); 96 element.addPropertyChangeListener(WeakListeners.propertyChange (listener, element)); 97 displayFormat = null; 98 } 99 100 103 public String getShortDescription() { 104 try { 105 return getHintElementFormat().format(element); 106 } 107 catch (IllegalArgumentException e) { 108 return super.getShortDescription(); 109 } 110 } 111 112 120 abstract protected String resolveIconBase(); 121 122 126 protected String [] getIconAffectingProperties() { 127 return ICON_AFFECTING_PROPERTIES; 128 } 129 130 136 public final ElementFormat getElementFormat() { 137 return elementFormat; 138 } 139 140 145 public final void setElementFormat(ElementFormat elementFormat) { 146 setDisplayName(elementFormat.format(ElementNode.this.element)); 147 this.elementFormat = elementFormat; 148 } 149 150 final void setElementFormat0(ElementFormat elementFormat) { 151 try { 152 setElementFormat(elementFormat); 153 } catch (IllegalArgumentException iae) { 154 setElementFormat(getInvalidFormat()); 155 } 156 } 157 158 static ElementFormat getInvalidFormat() { 159 if (invalidFormat != null) 160 return invalidFormat; 161 return invalidFormat = new ElementFormat(bundle.getString("FMT_InvalidFormat")); } 163 164 167 abstract protected ElementFormat getHintElementFormat(); 168 169 public HelpCtx getHelpCtx () { 170 return new HelpCtx (ElementNode.class); 171 } 172 173 178 public boolean canRename() { 179 return isWriteable(); 180 } 181 182 187 public boolean canDestroy () { 188 return isWriteable(); 189 } 190 191 196 public Transferable clipboardCopy () throws IOException { 197 ExTransferable ex = ExTransferable.create(super.clipboardCopy()); 198 ex.put(new ElementStringTransferable()); 199 return ex; 200 } 201 202 207 public Transferable clipboardCut () throws IOException { 208 if (!isWriteable()) 209 throw new IOException (); 210 211 ExTransferable ex = ExTransferable.create(super.clipboardCut()); 212 ex.put(new ElementStringTransferable()); 215 return ex; 216 } 217 218 219 class ElementStringTransferable extends ExTransferable.Single { 220 221 ElementStringTransferable() { 222 super(DataFlavor.stringFlavor); 223 } 224 225 226 protected Object getData() { 227 return element.toString(); 228 } 229 } 230 231 235 public boolean canCopy () { 236 return true; 237 } 238 239 243 public boolean canCut () { 244 return isWriteable(); 245 } 246 247 250 public void setActions(SystemAction[] actions) { 251 systemActions = actions; 252 } 253 254 257 void superFireCookieChange() { 258 fireCookieChange(); 259 } 260 261 273 public Node.Cookie getCookie (Class type) { 274 Node.Cookie c = super.getCookie(type); 275 if (c == null) 276 c = element.getCookie(type); 277 278 return c; 279 } 280 281 284 public boolean equals (Object o) { 285 return (o instanceof ElementNode) && (element.equals (((ElementNode)o).element)); 286 } 287 288 291 public int hashCode () { 292 return element.hashCode (); 293 } 294 295 296 300 public Node.Handle getHandle () { 301 Node.Handle supe = super.getHandle (); 302 if (supe != null) 303 return supe; 304 else if (element instanceof SourceElement) 305 return null; 306 else 307 return new ElementNodeHandle (element, writeable, elementFormat); 308 } 309 310 private static final class ElementNodeHandle implements Node.Handle { 311 private static final long serialVersionUID = 910667289626540L; 312 private Element element; 313 private boolean writable; 314 private ElementFormat elementFormat; 315 public ElementNodeHandle (Element element, boolean writable, ElementFormat elementFormat) { 316 this.element = element; 317 this.writable = writable; 318 this.elementFormat = elementFormat; 319 } 320 public Node getNode () throws IOException { 321 ElementNodeFactory factory = new DefaultFactory (writable); 322 Node n; 323 if (element instanceof ClassElement) 324 n = factory.createClassNode ((ClassElement) element); 325 else if (element instanceof ConstructorElement) 326 n = factory.createConstructorNode ((ConstructorElement) element); 327 else if (element instanceof FieldElement) 328 n = factory.createFieldNode ((FieldElement) element); 329 else if (element instanceof InitializerElement) 330 n = factory.createInitializerNode ((InitializerElement) element); 331 else if (element instanceof MethodElement) 332 n = factory.createMethodNode ((MethodElement) element); 333 else 334 throw new IOException ("what is element " + element + "? cannot restore node"); if (n instanceof ElementNode) 336 ((ElementNode) n).setElementFormat (elementFormat); 337 return n; 338 } 339 public String toString () { 340 return "ElementNodeHandle[" + element + "]"; } 342 } 343 344 boolean isWriteable() { 345 return writeable && SourceEditSupport.isWriteable(this.element); 346 } 347 348 void superSetName(String name) { 349 super.setName(name); 350 } 351 352 void superPropertyChange (String name, Object o, Object n) { 353 if (hasPropertyChangeListener()) { 354 if (name == null || findPropertyNames().contains(name)) { 355 super.firePropertyChange (name, o, n); 356 } 357 } 358 } 359 360 364 private Set findPropertyNames() { 365 Set names = new HashSet (); 366 Node.PropertySet[] npsets = getPropertySets(); 367 for (int i = 0; i < npsets.length; i++) { 368 Node.PropertySet npset = npsets[i]; 369 Node.Property[] nps = npset.getProperties(); 370 for (int j = 0; j < nps.length; j++) { 371 Node.Property np = nps[j]; 372 names.add(np.getName()); 373 } 374 } 375 return names; 376 } 377 378 public Node.PropertySet[] getPropertySets() { 379 return super.getPropertySets(); 380 } 381 382 void superShortDescriptionChange (String o, String n) { 383 super.fireShortDescriptionChange(o, n); 384 } 385 386 PropertyChangeListener createElementListener() { 387 return new ElementListener(); 388 } 389 390 392 396 class ElementListener implements PropertyChangeListener { 397 399 public void propertyChange(final PropertyChangeEvent evt) { 400 Mutex.EVENT.writeAccess(new Runnable () { 401 public void run() { 402 String propName = evt.getPropertyName(); 403 if (propName == null) { 404 setDisplayName(getElementFormat().format(ElementNode.this.element)); 405 setIconBase(resolveIconBase()); 406 } 407 else { 408 if (ElementProperties.PROP_VALID.equals(propName)) { 410 fireNodeDestroyed(); 411 return; 412 } 413 if (getElementFormat().dependsOnProperty(propName)) 415 setDisplayName(getElementFormat().format(ElementNode.this.element)); 416 417 String [] iconProps = getIconAffectingProperties(); 419 for (int i = 0; i < iconProps.length; i++) { 420 if (iconProps[i].equals(propName)) { 421 setIconBase(resolveIconBase()); 422 break; 423 } 424 } 425 426 if (propName.equals(ElementProperties.PROP_NAME)) { 427 try { 431 superSetName(((MemberElement)ElementNode.this.element).getName().toString()); 432 } 433 catch (ClassCastException e) { 434 } 436 } 437 else { 438 if (propName.equals(Node.PROP_COOKIE)) { 439 superFireCookieChange(); 441 return; 442 } 443 } 444 } 445 446 if (getHintElementFormat().dependsOnProperty(evt.getPropertyName())) 447 superShortDescriptionChange("", getShortDescription()); 449 superPropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); 450 } 451 }); 452 } 453 } 454 455 457 459 static abstract class ElementProp extends PropertySupport { 460 467 public ElementProp(String name, java.lang.Class type, boolean canW) { 468 super(name, type, 469 bundle.getString("PROP_" + name), 470 bundle.getString("HINT_" + name), 471 true, canW); 472 } 473 474 481 public void setValue (Object val) throws IllegalArgumentException , 482 IllegalAccessException , InvocationTargetException { 483 if (!canWrite()) 484 throw new IllegalAccessException (bundle.getString("MSG_Cannot_Write")); 485 } 486 487 491 void runAtomic(Element element, final SourceEditSupport.ExceptionalRunnable exRun) throws InvocationTargetException { 492 try { 493 SourceEditSupport.runAsUser(element, exRun); 494 } catch (SourceException e) { 495 throw new InvocationTargetException (e); 496 } 497 } 498 } 499 } 500 | Popular Tags |