1 19 20 package org.netbeans.api.nodes2looks; 21 22 import java.awt.Component ; 23 import java.awt.Image ; 24 import java.awt.datatransfer.Transferable ; 25 import java.beans.BeanInfo ; 26 import java.io.IOException ; 27 import java.lang.ref.WeakReference ; 28 import java.util.ArrayList ; 29 import java.util.Enumeration ; 30 import java.util.List ; 31 import java.util.Collection ; 32 import java.util.Iterator ; 33 import javax.swing.Action ; 34 import org.netbeans.modules.looks.LookListener; 35 import org.netbeans.modules.looks.LookEvent; 36 import org.netbeans.spi.looks.Look; 37 import org.netbeans.spi.looks.LookSelector; 38 import org.netbeans.spi.looks.Looks; 39 import org.netbeans.spi.looks.Selectors; 40 import org.openide.ErrorManager; 41 import org.openide.nodes.Children; 42 import org.openide.nodes.DefaultHandle; 43 import org.openide.nodes.Node; 44 import org.openide.cookies.InstanceCookie; 45 import org.openide.util.HelpCtx; 46 import org.openide.util.Lookup; 47 import org.openide.util.Utilities; 48 import org.openide.util.actions.SystemAction; 49 import org.openide.util.datatransfer.NewType; 50 import org.openide.util.datatransfer.PasteType; 51 import org.openide.util.lookup.AbstractLookup; 52 53 58 final class LookNode extends Node implements Node.Cookie, InstanceCookie.Of { 59 60 61 private static final NewType[] NO_NEW_TYPES = {}; 62 63 64 private static final PasteType[] NO_PASTE_TYPES = {}; 65 66 67 private static final Node.PropertySet[] NO_PROPERTY_SETS = {}; 68 69 70 private static final Action [] NO_ACTIONS = {}; 71 72 73 private static final String DEFAULT_ICON_16_NAME = 74 "org/netbeans/modules/looks/resources/defaultNode.gif"; 76 77 private static final String DEFAULT_ICON_32_NAME = 78 "org/netbeans/modules/looks/resources/defaultNode32.gif"; 80 84 87 private LookNodeLookupProvider lookupProvider; 89 90 private FirerImpl firer; 92 93 private Cache cache; 95 96 102 public LookNode( Object representedObject ) { 103 this (representedObject, null, null ); 104 } 105 106 111 public LookNode (Object representedObject, Look look ) { 112 this ( representedObject, look, null ); 113 } 114 115 120 public LookNode (Object representedObject, Look look, LookSelector lookSelector ) { 121 this ( representedObject, look, lookSelector, null ); 122 } 123 124 130 public LookNode(Object representedObject, Look look, LookSelector lookSelector, Node.Handle handle ) { 131 this ( create( representedObject, look, lookSelector ) ); 132 133 if (handle != null) { 134 this.cache = new Cache(handle); 135 } 136 else { 137 this.cache = new Cache(); 138 } 139 } 140 141 143 LookNode( Object representedObject, Look look, LookSelector lookSelector, Cache cache ) { 144 this ( create( representedObject, look, lookSelector ) ); 145 this.cache = cache; 146 } 147 148 149 158 private LookNode( Object [] params ) { 159 super( (Children)params[1], (Lookup)params[4] ); 160 ((LookNodeLookupProvider)params[4]).setLookNode( this ); 161 this.lookupProvider = (LookNodeLookupProvider)params[4]; 162 this.firer = new FirerImpl( this, (LookSelector)params[3], (Look)params[2], params[0] ); 163 org.netbeans.modules.looks.Accessor.DEFAULT.changeLookListener( getLook(), getRepresentedObject(), (LookListener)params[5], firer ); org.netbeans.modules.looks.Accessor.DEFAULT.addSelectorListener( getLookSelector(), firer); } 166 167 170 private static Object [] create( Object representedObject, 171 Look look, 172 LookSelector lookSelector ) { 173 174 if (lookSelector == null) { 175 ErrorManager.getDefault ().log ("LookSelector is null, DefaultSelector is used."); lookSelector = Selectors.defaultTypes (); 178 } 179 180 LookListener placehoderListener = new PlaceholderLookListener(); 181 182 if ( look != null ) { 183 Exception e = tryAttach( look, representedObject, placehoderListener ); 184 if ( e != null ) { 185 ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e ); 186 look = null; 187 } 188 } 189 else { 190 look = findFirstLook( lookSelector, representedObject, placehoderListener ); 191 } 192 193 194 if ( look == null ) { 195 Exception e = tryAttach( Looks.bean(), representedObject, placehoderListener ); 199 if ( e != null ) { 200 throw new IllegalStateException ( "BeanLook has to accept all objects " + representedObject ); 202 } 203 else { 204 look = Looks.bean(); 205 } 206 } 207 208 209 Lookup lookup = new LookNodeLookupProvider (); 211 212 Children children = look.isLeaf( representedObject, lookup ) ? Children.LEAF : new LookChildren(); 214 215 Object results[] = new Object [] { 217 representedObject, children, look, lookSelector, lookup, placehoderListener }; 224 225 return results; 226 } 227 228 229 231 236 public final LookSelector getLookSelector() { 237 return firer.lookSelector; 238 } 239 240 244 public synchronized Object getRepresentedObject() { 245 return firer.getRepresentedObject(); 246 } 247 248 private final LookNodeLookupProvider getLookupProvider() { 249 return lookupProvider; 250 } 251 252 259 public void setLook( Look look ) { 260 261 262 263 264 synchronized ( this ) { 266 267 LookListener placeholder = null; 268 269 if ( look == null ) { 270 placeholder = new PlaceholderLookListener(); 272 look = findFirstLook( getLookSelector(), getRepresentedObject(), placeholder ); 273 if ( look == getLook() ) { 274 org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( getLook(), getRepresentedObject(), placeholder ); 275 return; } 277 } 278 279 Object representedObject = getRepresentedObject(); 280 FirerImpl oldFirer = firer; 281 LookSelector oldLookSelector = getLookSelector(); 282 Look oldLook = getLook(); 283 284 oldFirer.look = null; oldFirer.lookSelector = null; oldFirer.representedObject = null; org.netbeans.modules.looks.Accessor.DEFAULT.removeSelectorListener( oldLookSelector, oldFirer ); 288 org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( oldLook, representedObject, oldFirer ); 289 290 firer = new FirerImpl ( this, oldLookSelector, look, representedObject ); 292 this.lookupProvider.setDirty(); 294 if ( placeholder == null ) { 295 org.netbeans.modules.looks.Accessor.DEFAULT.addLookListener( getLook(), getRepresentedObject(), firer ); } 297 else { 298 org.netbeans.modules.looks.Accessor.DEFAULT.changeLookListener( getLook(), getRepresentedObject(), placeholder, firer ); } 300 org.netbeans.modules.looks.Accessor.DEFAULT.addSelectorListener ( getLookSelector(), firer); 301 } 302 303 getCache().store( this ); 305 306 fireCookieChange(); 308 refreshChildren(true); 309 fireNameChange( null, null ); 310 fireDisplayNameChange( null, null ); 311 fireIconChange(); 312 fireOpenedIconChange(); 313 } 314 315 318 public synchronized Look getLook() { 319 return firer.look; 320 } 321 322 325 public Node.Handle getHandle() { 326 if ( cache!= null ) { 327 return cache; 328 } 329 else { 330 return DefaultHandle.createHandle (this); 331 } 332 } 333 334 339 public Node cloneNode () { 340 return new LookNode( getRepresentedObject(), getLook(), getLookSelector(), cache ); 341 } 342 343 345 346 final synchronized LookSelector getLookSelectorForChildren() { 347 Lookup lookup = getLookup(); 348 LookSelector chLs = (LookSelector)lookup.lookup( LookSelector.class ); 349 return chLs == null ? getLookSelector() : chLs; 350 } 351 352 354 final synchronized FirerImpl getFirer (){ 355 return firer; 356 } 357 358 359 void refreshChildren(boolean brutal) { 360 361 Children current = getChildren(); 362 boolean isLeaf = getLook().isLeaf( getRepresentedObject(), getLookup() ); 363 364 if ( isLeaf ) { 365 if ( current == Children.LEAF ) { 366 return; 367 } 368 else { 369 setChildren( Children.LEAF ); 370 return; 371 } 372 } 373 374 if ( current == Children.LEAF ) { 375 setChildren( new LookChildren() ); 376 } 377 else { 378 ((LookChildren)current).refreshChildren( brutal ); 379 } 380 } 381 382 Cache getCache() { 383 return cache; 384 } 385 386 void setCache( Cache cache ) { 387 this.cache = cache; 388 } 389 390 private static Look findFirstLook( LookSelector ls, Object ro, LookListener listener ) { 391 392 Enumeration descriptors = ls.getLooks( ro ); 393 394 while (descriptors.hasMoreElements ()) { 395 Look look = (Look)descriptors.nextElement (); 396 397 Exception e = tryAttach( look, ro, listener ); 398 if ( e == null ) { 399 return look; 400 } 401 402 ErrorManager.getDefault().notify( ErrorManager.INFORMATIONAL, e ); 403 } 404 405 return null; 406 } 407 408 private static Exception tryAttach( Look look, Object representedObject, LookListener listener ) { 409 try { 410 org.netbeans.modules.looks.Accessor.DEFAULT.addLookListener( look, representedObject, listener ); 411 return null; 412 } 413 catch ( ClassCastException e ) { 414 return e; 415 } 416 catch ( IllegalArgumentException e ) { 417 return e; 418 } 419 } 420 421 private Lookup getLookupNoInit() { 422 return lookupProvider; 423 } 424 425 427 final List getChildObjects() { 428 return getLook().getChildObjects( getRepresentedObject(), getLookupNoInit() ); 429 } 430 431 432 434 438 public String getDisplayName() { 439 String displayName = getLook().getDisplayName( getRepresentedObject(), getLookupNoInit() ); 440 return displayName == null ? getName() : displayName; 441 } 442 443 448 public void setDisplayName( String name ) { 449 } 450 451 454 public String getName() { 455 return getLook().getName( getRepresentedObject(), getLookupNoInit() ); 456 } 457 458 462 public void setName( String name ) { 463 try { 464 getLook().rename( getRepresentedObject(), name, getLookupNoInit() ); 465 } 466 catch ( IOException ex ) { 467 RuntimeException e = new IllegalArgumentException (); 468 ErrorManager.getDefault().annotate (e, ex); 469 throw e; 470 471 } 472 } 473 474 479 public void setShortDescription( String shortDescription ) { 480 } 481 482 485 public String getShortDescription() { 486 String shortDescription = getLook().getShortDescription( getRepresentedObject(), getLookupNoInit() ); 487 return shortDescription == null ? getDisplayName() : shortDescription; 488 } 489 490 494 public Image getIcon( int type ) { 495 Image image = getLook().getIcon( getRepresentedObject(), type, getLookupNoInit() ); 496 497 if ( image == null ) { 498 if ( type == BeanInfo.ICON_COLOR_32x32 || type == BeanInfo.ICON_MONO_32x32 ) { 499 return Utilities.loadImage( DEFAULT_ICON_32_NAME ); 500 } 501 return Utilities.loadImage( DEFAULT_ICON_16_NAME ); 502 } 503 return image; 504 } 505 506 511 public Image getOpenedIcon( final int type ) { 512 Image image = getLook().getOpenedIcon( getRepresentedObject(), type, getLookupNoInit() ); 513 return image == null ? getIcon( type ) : image; 514 } 515 516 519 public HelpCtx getHelpCtx () { 520 return getLook().getHelpCtx( getRepresentedObject(), getLookupNoInit() ); 521 } 522 523 525 528 public NewType[] getNewTypes() { 529 NewType arr[] = getLook().getNewTypes( getRepresentedObject(), getLookupNoInit() ); 530 return arr == null ? NO_NEW_TYPES : arr; 531 } 532 533 537 public SystemAction[] getActions() { 538 return toSA (getActions ( false )); 539 } 540 541 546 public Action [] getActions ( boolean context ) { 547 548 Action systemActions[]; 549 550 if ( context ) { 551 systemActions = getLook().getContextActions( getRepresentedObject(), getLookupNoInit() ); 552 } 553 else { 554 systemActions = getLook().getActions( getRepresentedObject(), getLookupNoInit() ); 555 } 556 557 return systemActions == null ? NO_ACTIONS : systemActions; 558 559 } 560 561 566 public SystemAction [] getContextActions() { 567 return toSA (getActions ( true )); 568 } 569 570 574 public SystemAction getDefaultAction() { 575 Action a = getPreferredAction(); 576 return a instanceof SystemAction ? (SystemAction)a : null; 577 } 578 579 588 public Action getPreferredAction() { 589 return getLook().getDefaultAction( getRepresentedObject(), getLookupNoInit() ); 590 } 591 592 596 private static SystemAction[] toSA (Action [] arr) { 597 SystemAction[] sa = new SystemAction[arr.length]; 598 599 for (int i = 0; i < arr.length; i++) { 600 if (arr[i] instanceof SystemAction) { 601 sa[i] = (SystemAction)arr[i]; 602 } 603 } 604 605 return sa; 606 } 607 608 609 611 612 616 public Node.PropertySet[] getPropertySets() { 617 618 Node.PropertySet sets[] = getLook().getPropertySets( getRepresentedObject(), getLookupNoInit() ); 619 return sets == null ? NO_PROPERTY_SETS : sets; 620 621 } 622 623 626 public Component getCustomizer() { 627 return getLook().getCustomizer( getRepresentedObject(), getLookupNoInit() ); 628 } 629 630 634 public boolean hasCustomizer () { 635 return getLook().hasCustomizer( getRepresentedObject(), getLookupNoInit() ); 636 } 637 638 640 645 public boolean canRename() { 646 return getLook().canRename( getRepresentedObject(), getLookupNoInit() ); 647 } 648 649 652 public boolean canDestroy() { 653 return getLook().canDestroy( getRepresentedObject(), getLookupNoInit() ); 654 } 655 656 659 public boolean canCopy() { 660 return getLook().canCopy( getRepresentedObject(), getLookupNoInit() ); 661 } 662 663 666 public boolean canCut() { 667 return getLook().canCut( getRepresentedObject(), getLookupNoInit() ); 668 } 669 670 676 public PasteType[] getPasteTypes( Transferable t) { 677 PasteType arr[] = getLook().getPasteTypes( getRepresentedObject(), t, getLookupNoInit() ); 678 return arr != null ? arr : NO_PASTE_TYPES; 679 } 680 681 690 public PasteType getDropType( Transferable t, int action, int index) { 691 return getLook().getDropType( getRepresentedObject(), t, action, index, getLookupNoInit() ); 692 } 693 694 699 public Transferable clipboardCopy() throws IOException { 700 return getLook().clipboardCopy( getRepresentedObject(), getLookupNoInit() ); 701 } 702 703 708 public Transferable clipboardCut() throws IOException { 709 return getLook().clipboardCut( getRepresentedObject(), getLookupNoInit() ); 710 } 711 712 719 public Transferable drag() throws IOException { 720 return getLook().drag( getRepresentedObject(), getLookupNoInit() ); 721 } 722 723 728 public void destroy () throws IOException { 729 getLook().destroy( getRepresentedObject(), getLookupNoInit() ); 730 } 731 732 734 public Class instanceClass() throws java.io.IOException , ClassNotFoundException { 735 return getRepresentedObject().getClass(); 736 } 737 738 public Object instanceCreate() throws java.io.IOException , ClassNotFoundException { 739 return getRepresentedObject(); 740 } 741 742 public String instanceName() { 743 return getRepresentedObject().getClass().getName(); 744 } 745 746 public boolean instanceOf( Class type ) { 747 return type.isInstance( getRepresentedObject() ); 748 } 749 750 public String toString() { 751 if (getRepresentedObject() != null) { 752 return super.toString(); 753 } else { 754 return "LookNode<" + getLook().getName() + ";DEAD>"; } 756 } 757 758 760 764 static final class FirerImpl extends WeakReference 765 implements Runnable , org.netbeans.modules.looks.SelectorListener, LookListener { 766 767 768 private Object representedObject; 769 770 private LookSelector lookSelector; 771 772 private Look look; 775 776 779 FirerImpl( LookNode lookNode, 780 LookSelector lookSelector, 781 Look look, 782 Object representedObject ) { 783 super( lookNode, Utilities.activeReferenceQueue() ); 784 this.representedObject = representedObject; 785 this.look = look; 786 this.lookSelector = lookSelector; 787 } 788 789 public LookNode getLookNode () { 790 return (LookNode)get(); 791 } 792 793 796 public Object getRepresentedObject() { 797 return representedObject; 798 } 799 800 802 public void change( LookEvent evt ) { 803 804 long mask = evt.getMask(); 805 LookNode l = getLookNode(); 806 807 if ( l != null ) { 808 809 if ( ( mask & Look.GET_NAME ) > 0 ) { 810 l.fireNameChange( null, null ); 811 } 812 if ( ( mask & Look.GET_DISPLAY_NAME ) > 0 ) { 813 l.fireDisplayNameChange( null, null ); 814 } 815 if ( ( mask & Look.GET_ICON ) > 0 ) { 816 l.fireIconChange(); 817 } 818 if ( ( mask & Look.DESTROY ) > 0 ) { 819 l.fireNodeDestroyed(); 820 } 821 if ( ( mask & Look.GET_OPENED_ICON ) > 0 ) { 822 l.fireOpenedIconChange(); 823 } 824 if ( ( mask & Look.GET_PROPERTY_SETS ) > 0 ) { 825 l.firePropertySetsChange( null, null ); 826 } 827 if ( ( mask & Look.GET_CHILD_OBJECTS ) > 0 ) { 828 l.refreshChildren(false); 829 } 830 if ( ( mask & Look.GET_SHORT_DESCRIPTION ) > 0 ) { 831 l.fireShortDescriptionChange( null, null ); 832 } 833 if ( ( mask & Look.GET_LOOKUP_ITEMS ) > 0 ) { 834 l.getLookupProvider().setDirty(); 835 } 836 } 837 } 838 839 841 public void propertyChange( LookEvent evt ) { 842 LookNode l = getLookNode(); 843 if (l != null) { 844 l.firePropertyChange( evt.getPropertyName(), null, null ); 845 } 846 } 847 848 850 public void run () { 851 852 if ( lookSelector != null ) { 853 org.netbeans.modules.looks.Accessor.DEFAULT.removeSelectorListener(lookSelector, this); 854 } 855 if ( look != null ) { 856 org.netbeans.modules.looks.Accessor.DEFAULT.removeLookListener( look, representedObject, this ); 857 } 858 859 representedObject = null; 861 862 } 863 864 866 public void contentsChanged(org.netbeans.modules.looks.SelectorEvent evt) { 867 LookNode ln = getLookNode(); 868 869 if ( evt.affectsObject(representedObject) && ln != null ) { 870 ln.setLook( null ); 871 } 872 } 873 } 875 private static final class LookNodeLookupProvider extends org.openide.util.lookup.AbstractLookup { 876 private LookNode lookNode; 877 878 protected void setLookNode (LookNode l) { 879 lookNode = l; 880 } 881 882 protected void initialize() { 883 setDirty (); 884 } 885 886 888 public void setDirty() { 889 if ( lookNode == null ) { 890 throw new IllegalStateException ( "getLookupCalled before attached node" ); 891 } 892 893 895 Look look = lookNode.getLook(); 896 Collection lookupItems = look.getLookupItems( lookNode.getRepresentedObject(), this ); 897 898 List pairs = new ArrayList ( lookupItems == null ? 1 : 1 + lookupItems.size() ); 899 pairs.add( ItemPair.wrap ( ( new NodeLookupItem( lookNode ) ) ) ); 900 901 902 if ( lookupItems != null ) { 903 for (Iterator it = lookupItems.iterator(); it.hasNext(); ) { 904 pairs.add( ItemPair.wrap ((Lookup.Item)it.next()) ); 905 } 906 } 907 908 setPairs( pairs ); 909 } 910 } 912 913 private static final class ItemPair extends AbstractLookup.Pair { 914 915 private AbstractLookup.Item item; 916 917 private ItemPair (org.openide.util.lookup.AbstractLookup.Item i) { 918 this.item = i; 919 } 920 921 public static AbstractLookup.Pair wrap (Lookup.Item item) { 922 if (false) { 923 return (AbstractLookup.Pair)item; 924 } else { 925 return new ItemPair (item); 926 } 927 } 928 929 protected boolean creatorOf(Object obj) { 930 return item.getInstance() == obj; 931 } 932 933 public String getDisplayName() { 934 return item.getDisplayName (); 935 } 936 937 public String getId() { 938 return item.getId (); 939 } 940 941 public Object getInstance() { 942 return item.getInstance (); 943 } 944 945 public Class getType() { 946 return item.getType (); 947 } 948 949 protected boolean instanceOf(Class c) { 950 return c.isAssignableFrom (getType ()); 951 } 952 953 public boolean equals (Object o) { 954 if (o instanceof ItemPair) { 955 ItemPair p = (ItemPair)o; 956 return item.equals (p.item); 957 } 958 return false; 959 } 960 961 public int hashCode () { 962 return item.hashCode (); 963 } 964 } 966 private static class NodeLookupItem extends Lookup.Item { 967 private LookNode ln; 968 969 public NodeLookupItem( LookNode ln ) { 970 this.ln = ln; 971 } 972 973 public String getDisplayName() { 974 return getId(); 975 } 976 977 public String getId() { 978 return ln.toString(); 979 } 980 981 public Object getInstance() { 982 return ln; 983 } 984 985 public Class getType() { 986 return ln.getClass(); 987 } 988 989 } 990 991 private static class PlaceholderLookListener implements LookListener { 993 994 public void change(LookEvent evt) {} 995 996 public void propertyChange(LookEvent evt) {} 997 998 } 999 1000} 1001 1002 | Popular Tags |