1 19 20 package org.openide.util.actions; 21 22 import java.awt.event.ActionEvent ; 23 import java.beans.PropertyChangeEvent ; 24 import java.beans.PropertyChangeListener ; 25 import java.util.ArrayList ; 26 import java.util.Arrays ; 27 import java.util.Collection ; 28 import java.util.Collections ; 29 import java.util.List ; 30 import javax.swing.Action ; 31 import org.netbeans.junit.NbTestCase; 32 import org.openide.nodes.AbstractNode; 33 import org.openide.nodes.Children; 34 import org.openide.nodes.Node; 35 import org.openide.util.HelpCtx; 36 import org.openide.util.lookup.AbstractLookup; 37 import org.openide.util.lookup.InstanceContent; 38 39 42 public class NodeActionTest extends NbTestCase { 43 44 public NodeActionTest(String name) { 45 super(name); 46 } 47 48 private Node n1, n2, n3; 49 50 51 55 protected boolean runInEQ() { 56 return true; 57 } 58 59 protected void setUp() throws Exception { 60 n1 = new AbstractNode(Children.LEAF); 61 n1.setName("n1"); 62 n1.setDisplayName("text"); 63 n2 = new AbstractNode(Children.LEAF); 64 n2.setName("n2"); 65 n2.setDisplayName("text"); 66 n3 = new AbstractNode(Children.LEAF); 67 n3.setName("n3"); 68 n3.setDisplayName("somethingelse"); 69 } 70 71 public void testBasicUsage() throws Exception { 72 SimpleNodeAction a1 = SystemAction.get(SimpleNodeAction.class); 73 ActionsInfraHid.WaitPCL l = new ActionsInfraHid.WaitPCL(NodeAction.PROP_ENABLED); 74 try { 75 a1.addPropertyChangeListener(l); 77 assertFalse(a1.isEnabled()); 78 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 81 assertTrue(l.changed()); 82 l.gotit = 0; 83 assertTrue(a1.isEnabled()); 84 ActionsInfraHid.setCurrentNodes(new Node[] {n1, n2}); 85 assertTrue(l.changed()); 86 l.gotit = 0; 87 assertFalse(a1.isEnabled()); 88 ActionsInfraHid.setCurrentNodes(new Node[] {n2}); 89 assertTrue(l.changed()); 90 l.gotit = 0; 91 assertTrue(a1.isEnabled()); 92 ActionsInfraHid.setCurrentNodes(new Node[] {n3}); 93 assertTrue(l.changed()); 94 l.gotit = 0; 95 assertFalse(a1.isEnabled()); 96 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 98 assertTrue(l.changed()); 99 l.gotit = 0; 100 assertTrue(a1.isEnabled()); 101 a1.actionPerformed(null); 102 a1.actionPerformed(new ActionEvent (a1, ActionEvent.ACTION_PERFORMED, "runit")); 103 assertEquals(Arrays.asList(new List [] { 104 Collections.singletonList(n1), 105 Collections.singletonList(n1), 106 }), a1.runOn); 107 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 109 if (!l.changed()) { 111 Thread.sleep(1000); 113 } 114 l.gotit = 0; 115 assertTrue(a1.isEnabled()); 116 ActionsInfraHid.setCurrentNodes(new Node[] {n3}); 117 assertTrue(l.changed()); 118 l.gotit = 0; 119 assertFalse(a1.isEnabled()); 120 ActionsInfraHid.setCurrentNodes(new Node[] {n3}); 121 if (!l.changed()) { 122 Thread.sleep(1000); 124 } 125 l.gotit = 0; 126 assertFalse(a1.isEnabled()); 127 } finally { 128 a1.removePropertyChangeListener(l); 129 ActionsInfraHid.setCurrentNodes(new Node[0]); 130 ActionsInfraHid.setCurrentNodes(null); 131 a1.runOn.clear(); 132 } 133 } 134 135 public void testPerformActionWithArgs() throws Exception { 136 SimpleNodeAction a1 = SystemAction.get(SimpleNodeAction.class); 137 try { 138 assertFalse(a1.isEnabled()); 139 assertEquals(Collections.EMPTY_LIST, a1.runOn); 140 a1.actionPerformed(new ActionEvent (n1, ActionEvent.ACTION_PERFORMED, "exec")); 141 a1.actionPerformed(new ActionEvent (new Node[] {n1}, ActionEvent.ACTION_PERFORMED, "exec")); 142 assertEquals(Arrays.asList(new List [] { 143 Collections.singletonList(n1), 144 Collections.singletonList(n1), 145 }), a1.runOn); 146 } finally { 150 ActionsInfraHid.setCurrentNodes(new Node[0]); 151 ActionsInfraHid.setCurrentNodes(null); 152 a1.runOn.clear(); 153 } 154 } 155 156 158 public void testFocusChange() throws Exception { 159 helpTestFocusChange(); 160 169 } 170 private void helpTestFocusChange() throws Exception { 171 SimpleNodeAction a1 = SystemAction.get(SimpleNodeAction.class); 172 DoesNotSurviveFocusChgAction a2 = SystemAction.get(DoesNotSurviveFocusChgAction.class); 173 ActionsInfraHid.WaitPCL l1 = new ActionsInfraHid.WaitPCL(NodeAction.PROP_ENABLED); 174 ActionsInfraHid.WaitPCL l2 = new ActionsInfraHid.WaitPCL(NodeAction.PROP_ENABLED); 175 try { 176 180 a1.addPropertyChangeListener(l1); 181 a2.addPropertyChangeListener(l2); 182 assertFalse(a1.isEnabled()); 183 assertFalse(a2.isEnabled()); 184 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 185 assertTrue(l1.changed()); 186 l1.gotit = 0; 187 assertTrue(a1.isEnabled()); 188 assertTrue(l2.changed()); 189 l2.gotit = 0; 190 assertTrue(a2.isEnabled()); 191 ActionsInfraHid.setCurrentNodes(null); 192 assertTrue(l2.changed()); 193 l2.gotit = 0; 194 assertFalse(a2.isEnabled()); 195 if (!l1.changed()) { 196 Thread.sleep(1000); 197 } 198 l1.gotit = 0; 199 assertTrue(a1.isEnabled()); 200 ActionsInfraHid.setCurrentNodes(new Node[] {n2}); 201 assertTrue(l2.changed()); 202 l2.gotit = 0; 203 assertTrue(a2.isEnabled()); 204 if (!l1.changed()) { 205 Thread.sleep(1000); 206 } 207 l1.gotit = 0; 208 assertTrue(a1.isEnabled()); 209 210 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 213 assertTrue(l1.changed()); 214 l1.gotit = 0; 215 assertTrue(a1.isEnabled()); 216 assertTrue(l2.changed()); 217 l2.gotit = 0; 218 assertTrue(a2.isEnabled()); 219 ActionsInfraHid.setCurrentNodes(new Node[0]); 220 assertTrue(l2.changed()); 221 l2.gotit = 0; 222 assertFalse(a2.isEnabled()); 223 l1.gotit = 0; 224 assertFalse(a1.isEnabled()); 225 } finally { 226 a1.removePropertyChangeListener(l1); 227 a2.removePropertyChangeListener(l2); 228 ActionsInfraHid.setCurrentNodes(new Node[0]); 229 ActionsInfraHid.setCurrentNodes(null); 230 } 231 a1 = null; 232 a2 = null; 233 } 234 235 243 public void testNoRedundantEnablementChecks() throws Exception { 244 LazyNodeAction a = SystemAction.get(LazyNodeAction.class); 245 ActionsInfraHid.WaitPCL l = new ActionsInfraHid.WaitPCL(NodeAction.PROP_ENABLED); 246 try { 247 assertEquals(0, a.count); 248 assertFalse(a.listeners); 249 assertFalse(a.isEnabled()); 250 a.addPropertyChangeListener(l); 251 assertTrue(a.listeners); 252 assertFalse(a.isEnabled()); 253 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 254 assertTrue(l.changed()); 255 l.gotit = 0; 256 assertTrue(a.isEnabled()); 257 a.count = 0; 259 assertTrue(a.isEnabled()); 260 assertEquals("Adjacent calls to isEnabled() do not recheck the same node selection", 0, a.count); 261 271 ActionsInfraHid.setCurrentNodes(new Node[] {n2}); 273 if (!l.changed()) { 274 Thread.sleep(1000); 275 } 276 l.gotit = 0; 277 assertTrue(a.isEnabled()); 278 assertEquals("A real change to selection calls enable(Node[]) again", 1, a.count); 279 a.count = 0; 281 ActionsInfraHid.setCurrentNodes(new Node[] {n1, n3}); 282 assertTrue(l.changed()); 283 l.gotit = 0; 284 assertEquals("Do not make extra checks until someone asks", 0, a.count); 285 ActionsInfraHid.setCurrentNodes(new Node[] {n2, n3}); 286 assertTrue("Do not keep firing changes when nobody is paying attention", !l.changed()); 287 a.removePropertyChangeListener(l); 289 assertFalse(a.listeners); 290 ActionsInfraHid.setCurrentNodes(new Node[] {}); 291 Thread.sleep(1000); 292 assertFalse(a.isEnabled()); 293 a.count = 0; 294 assertFalse(a.isEnabled()); 295 assertEquals("Even with no listeners, adjacent isEnabled()s are clean", 0, a.count); 296 ActionsInfraHid.setCurrentNodes(new Node[] {n3}); 297 Thread.sleep(1000); 298 assertEquals("With no listeners, node selection changes are ignored", 0, a.count); 299 assertTrue(a.isEnabled()); 300 assertEquals("With no listeners, isEnabled() works on demand", 1, a.count); 301 } finally { 302 a.removePropertyChangeListener(l); 303 ActionsInfraHid.setCurrentNodes(new Node[0]); 304 ActionsInfraHid.setCurrentNodes(null); 305 a.count = 0; 306 } 307 } 308 309 317 public void testCallSetEnabledDirectly() throws Exception { 318 SimpleNodeAction a1 = SystemAction.get(SimpleNodeAction.class); 319 ActionsInfraHid.WaitPCL l = new ActionsInfraHid.WaitPCL(NodeAction.PROP_ENABLED); 320 try { 321 assertFalse(a1.isEnabled()); 322 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 323 assertTrue(a1.isEnabled()); 324 n1.setDisplayName("foo"); 325 a1.setEnabled(false); 326 assertFalse(a1.isEnabled()); 327 n1.setDisplayName("text"); 328 ActionsInfraHid.setCurrentNodes(new Node[] {n2}); 329 assertTrue(a1.isEnabled()); 330 a1.addPropertyChangeListener(l); 332 assertTrue(a1.isEnabled()); 333 n2.setDisplayName("foo"); 334 a1.setEnabled(false); 335 assertTrue(l.changed()); 336 l.gotit = 0; 337 assertFalse(a1.isEnabled()); 338 n2.setDisplayName("text"); 339 ActionsInfraHid.setCurrentNodes(new Node[] {n1}); 340 assertTrue(l.changed()); 341 l.gotit = 0; 342 assertTrue(a1.isEnabled()); 343 n1.setDisplayName("foo"); 344 a1.setEnabled(false); 345 assertTrue(l.changed()); 346 l.gotit = 0; 347 assertFalse(a1.isEnabled()); 348 n1.setDisplayName("text"); 349 ActionsInfraHid.setCurrentNodes(new Node[] {n2}); 350 assertTrue(l.changed()); 351 l.gotit = 0; 352 assertTrue(a1.isEnabled()); 353 } finally { 354 a1.removePropertyChangeListener(l); 355 n1.setDisplayName("text"); 356 ActionsInfraHid.setCurrentNodes(new Node[0]); 357 ActionsInfraHid.setCurrentNodes(null); 358 } 359 } 360 361 365 public void testNodeActionIsCorrectlyClonned() throws Exception { 366 class MN extends AbstractNode { 367 public MN(String displayName) { 368 super(Children.LEAF); 369 setDisplayName(displayName); 370 } 371 } 372 373 class Counter implements PropertyChangeListener { 374 int cnt; 375 376 public void propertyChange(PropertyChangeEvent ev) { 377 cnt++; 378 } 379 380 public void assertCnt(String txt, int cnt) { 381 assertEquals(txt, cnt, this.cnt); 382 this.cnt = 0; 383 } 384 } 385 386 387 SimpleNodeAction s = SimpleNodeAction.get(SimpleNodeAction.class); 388 Counter counter = new Counter(); 389 390 InstanceContent ic = new InstanceContent(); 391 AbstractLookup lookup = new AbstractLookup(ic); 392 393 Action clone = s.createContextAwareInstance(lookup); 394 clone.addPropertyChangeListener(counter); 395 396 assertTrue("Not enabled", !clone.isEnabled()); 397 398 MN mn1 = new MN("text"); 399 ic.add(mn1); 400 401 assertTrue("Enabled", clone.isEnabled()); 402 counter.assertCnt("Once change in enabled state", 1); 403 404 clone.actionPerformed(new ActionEvent (this, 0, "")); 405 406 assertEquals("Has been executed just once: ", 1, SimpleNodeAction.runOn.size()); 407 Collection c = (Collection )SimpleNodeAction.runOn.iterator().next(); 408 SimpleNodeAction.runOn.clear(); 409 assertTrue("Has been executed on mn1", c.contains(mn1)); 410 411 MN mn2 = new MN("x"); 412 ic.add(mn2); 413 414 assertTrue("Not enabled, because there are two items", !clone.isEnabled()); 415 counter.assertCnt("Another change in the state", 1); 416 417 ic.remove(mn1); 418 assertTrue("Not enabled, the one item is not named correctly", !clone.isEnabled()); 419 counter.assertCnt("No change right now, the action remains disabled", 0); 420 421 } 422 423 424 public static class SimpleNodeAction extends NodeAction { 425 protected boolean enable(Node[] activatedNodes) { 426 boolean r = activatedNodes.length == 1 && 427 activatedNodes[0].getDisplayName().equals("text"); 428 return r; 430 } 431 public static final List runOn = new ArrayList (); protected void performAction(Node[] activatedNodes) { 433 runOn.add(Arrays.asList(activatedNodes)); 434 } 435 public String getName() { 436 return "SimpleNodeAction"; 437 } 438 public HelpCtx getHelpCtx() { 439 return null; 440 } 441 public static int INSTANCES = 0; 442 public SimpleNodeAction() { 443 INSTANCES++; 444 } 445 protected boolean clearSharedData() { 446 INSTANCES--; 447 System.err.println("collecting a SimpleNodeAction or subclass"); return super.clearSharedData(); 449 } 450 protected boolean asynchronous() { 451 return false; 452 } 453 } 454 455 public static class DoesNotSurviveFocusChgAction extends SimpleNodeAction { 456 protected boolean surviveFocusChange() { 457 return false; 458 } 459 public String getName() { 460 return "DoesNotSurviveFocusChgAction"; 461 } 462 protected boolean asynchronous() { 463 return false; 464 } 465 } 466 467 public static class LazyNodeAction extends NodeAction { 468 public static int count = 0; 469 protected boolean enable(Node[] activatedNodes) { 470 count++; 471 return activatedNodes.length == 1; 472 } 473 public static boolean listeners = false; 474 protected void addNotify() { 475 if (listeners) throw new IllegalStateException (); 476 super.addNotify(); 477 listeners = true; 478 } 479 protected void removeNotify() { 480 if (!listeners) throw new IllegalStateException (); 481 listeners = false; 482 super.removeNotify(); 483 } 484 protected void performAction(Node[] activatedNodes) { 485 } 487 public String getName() { 488 return "LazyNodeAction"; 489 } 490 public HelpCtx getHelpCtx() { 491 return null; 492 } 493 protected boolean asynchronous() { 494 return false; 495 } 496 } 497 498 } 499 | Popular Tags |