1 19 package org.netbeans.modules.java.navigation; 20 21 22 import java.awt.Image ; 23 import java.util.Comparator ; 24 import java.util.HashMap ; 25 import java.util.HashSet ; 26 import java.util.List ; 27 import java.util.Set ; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.ElementKind; 30 import javax.lang.model.element.Modifier; 31 import javax.swing.Action ; 32 import org.netbeans.api.java.source.ElementHandle; 33 import org.netbeans.api.java.source.UiUtils; 34 import org.netbeans.modules.java.navigation.ElementNode.Description; 35 import org.netbeans.modules.java.navigation.actions.OpenAction; 36 import org.openide.filesystems.FileObject; 37 import org.openide.nodes.AbstractNode; 38 import org.openide.nodes.Children; 39 import org.openide.nodes.Children; 40 import org.openide.nodes.Node; 41 import org.openide.util.Utilities; 42 43 47 public class ElementNode extends AbstractNode { 48 49 50 private static Node WAIT_NODE; 51 52 private OpenAction openAction; 53 private Description description; 54 55 56 public ElementNode( Description description ) { 57 super(description.subs == null ? Children.LEAF: new ElementChilren(description.subs, description.ui.getFilters())); 58 this.description = description; 59 setDisplayName( description.name ); 60 } 61 62 63 @Override 64 public Image getIcon(int type) { 65 return description.kind == null ? super.getIcon(type) : Utilities.icon2Image(UiUtils.getElementIcon(description.kind, description.modifiers)); 66 } 67 68 @Override 69 public Image getOpenedIcon(int type) { 70 return getIcon(type); 71 } 72 73 @Override 74 public java.lang.String getDisplayName() { 75 return description.name; 76 } 77 78 @Override 79 public String getHtmlDisplayName() { 80 return description.htmlHeader; 81 } 82 83 @Override 84 public Action [] getActions( boolean context ) { 85 86 if ( context || description.name == null ) { 87 return description.ui.getActions(); 88 } 89 else { 90 Action panelActions[] = description.ui.getActions(); 91 92 Action actions[] = new Action [ 2 + panelActions.length ]; 93 actions[0] = getOpenAction(); 94 actions[1] = null; 95 for( int i = 0; i < panelActions.length; i++ ){ 96 actions[2 + i] = panelActions[i]; 97 } 98 return actions; 99 } 100 } 101 102 @Override 103 public Action getPreferredAction() { 104 return getOpenAction(); 105 } 106 107 108 private synchronized Action getOpenAction() { 109 if ( openAction == null ) { 110 FileObject fo = description.ui.getFileObject(); 111 openAction = new OpenAction(description.elementHandle, fo); 112 } 113 return openAction; 114 } 115 116 static synchronized Node getWaitNode() { 117 if ( WAIT_NODE == null ) { 118 WAIT_NODE = new WaitNode(); 119 } 120 return WAIT_NODE; 121 } 122 123 public void refreshRecursively() { 124 Children ch = getChildren(); 125 if ( ch instanceof ElementChilren ) { 126 ((ElementChilren)ch).resetKeys(description.subs, description.ui.getFilters()); 127 for( Node sub : ch.getNodes() ) { 128 description.ui.expandNode(sub); 129 ((ElementNode)sub).refreshRecursively(); 130 } 131 } 132 } 133 134 public void updateRecursively( Description newDescription ) { 135 Children ch = getChildren(); 136 if ( ch instanceof ElementChilren ) { 137 HashSet <Description> oldSubs = new HashSet <Description>( description.subs ); 138 139 140 Node[] nodes = ch.getNodes( true ); 144 HashMap <Description,ElementNode> oldD2node = new HashMap <Description,ElementNode>(); 145 for (Node node : nodes) { 146 oldD2node.put(((ElementNode)node).description, (ElementNode)node); 147 } 148 149 ((ElementChilren)ch).resetKeys(newDescription.subs, newDescription.ui.getFilters()); 151 152 153 nodes = ch.getNodes( true ); 155 156 for( Description newSub : newDescription.subs ) { 157 ElementNode node = oldD2node.get(newSub); 158 if ( node != null ) { if ( !oldSubs.contains(newSub) && node.getChildren() != Children.LEAF) { 160 description.ui.expandNode(node); } 162 node.updateRecursively( newSub ); } 164 } 165 } 166 167 Description oldDescription = description; description = newDescription; if ( oldDescription.htmlHeader != null && !oldDescription.htmlHeader.equals(description.htmlHeader)) { 170 fireDisplayNameChange(oldDescription.htmlHeader, description.htmlHeader); 172 } 173 if( oldDescription.modifiers != null && !oldDescription.modifiers.equals(newDescription.modifiers)) { 174 fireIconChange(); 175 fireOpenedIconChange(); 176 } 177 } 178 179 public Description getDescritption() { 180 return description; 181 } 182 183 private static final class ElementChilren extends Children.Keys<Description> { 184 185 public ElementChilren(List <Description> descriptions, ClassMemberFilters filters ) { 186 resetKeys( descriptions, filters ); 187 } 188 189 protected Node[] createNodes(Description key) { 190 return new Node[] {new ElementNode(key)}; 191 } 192 193 void resetKeys( List <Description> descriptions, ClassMemberFilters filters ) { 194 setKeys( filters.filter(descriptions) ); 195 } 196 197 198 199 } 200 201 203 static class Description { 204 205 public static final Comparator <Description> ALPHA_COMPARATOR = 206 new DescriptionComparator(true); 207 public static final Comparator <Description> POSITION_COMPARATOR = 208 new DescriptionComparator(false); 209 210 ClassMemberPanelUI ui; 211 212 FileObject fileObject; 214 final String name; 215 final ElementHandle<? extends Element> elementHandle; 216 final ElementKind kind; 217 Set <Modifier> modifiers; 218 List <Description> subs; 219 String htmlHeader; 220 long pos; 221 222 Description( ClassMemberPanelUI ui ) { 223 this.ui = ui; 224 this.name = null; 225 this.elementHandle = null; 226 this.kind = null; 227 } 228 229 Description(ClassMemberPanelUI ui, 230 String name, 231 ElementHandle<? extends Element> elementHandle, 232 ElementKind kind ) { 233 this.ui = ui; 234 this.name = name; 235 this.elementHandle = elementHandle; 236 this.kind = kind; 237 } 238 239 240 241 @Override 242 public boolean equals(Object o) { 243 244 if ( o == null ) { 245 return false; 247 } 248 249 if ( !(o instanceof Description)) { 250 return false; 252 } 253 254 Description d = (Description)o; 255 256 if ( kind != d.kind ) { 257 return false; 259 } 260 261 if ( !name.equals(d.name) ) { 262 return false; 264 } 265 266 if ( !this.elementHandle.signatureEquals(d.elementHandle) ) { 267 return false; 268 } 269 270 276 277 return true; 279 } 280 281 282 public int hashCode() { 283 int hash = 7; 284 285 hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0); 286 hash = 29 * hash + (this.kind != null ? this.kind.hashCode() : 0); 287 return hash; 289 } 290 291 private static class DescriptionComparator implements Comparator <Description> { 292 293 boolean alpha; 294 295 DescriptionComparator( boolean alpha ) { 296 this.alpha = alpha; 297 } 298 299 public int compare(Description d1, Description d2) { 300 301 if ( alpha ) { 302 if ( k2i(d1.kind) != k2i(d2.kind) ) { 303 return k2i(d1.kind) - k2i(d2.kind); 304 } 305 306 return d1.name.compareTo(d2.name); 307 } 308 else { 309 return d1.pos == d2.pos ? 0 : d1.pos < d2.pos ? -1 : 1; 310 } 311 } 312 313 int k2i( ElementKind kind ) { 314 switch( kind ) { 315 case CONSTRUCTOR: 316 return 1; 317 case METHOD: 318 return 2; 319 case FIELD: 320 return 3; 321 case CLASS: 322 case INTERFACE: 323 case ENUM: 324 case ANNOTATION_TYPE: 325 return 4; 326 default: 327 return 100; 328 } 329 } 330 331 } 332 333 } 334 335 private static class WaitNode extends AbstractNode { 336 337 private Image waitIcon = Utilities.loadImage("org/netbeans/modules/java/navigation/resources/wait.gif"); 339 WaitNode( ) { 340 super( Children.LEAF ); 341 } 342 343 @Override 344 public Image getIcon(int type) { 345 return waitIcon; 346 } 347 348 @Override 349 public Image getOpenedIcon(int type) { 350 return getIcon(type); 351 } 352 353 @java.lang.Override 354 public java.lang.String getDisplayName() { 355 return "Please Wait..."; 356 } 357 358 } 359 360 361 } 362 | Popular Tags |