1 19 20 package org.openide.explorer.propertysheet; 21 22 import java.awt.Component ; 23 import java.awt.FlowLayout ; 24 import java.beans.*; 25 import java.lang.reflect.*; 26 import javax.swing.*; 27 28 import org.openide.*; 29 import org.openide.explorer.propertysheet.*; 30 31 import junit.framework.*; 32 import junit.textui.TestRunner; 33 34 import org.netbeans.junit.*; 35 import java.beans.PropertyDescriptor ; 36 import java.awt.IllegalComponentStateException ; 37 import java.lang.ref.WeakReference ; 38 import java.lang.reflect.InvocationTargetException ; 39 import javax.swing.JPanel ; 40 41 43 public final class PropertyPanelTest extends NbTestCase { 44 static { 45 String [] syspesp = PropertyEditorManager.getEditorSearchPath(); 51 String [] nbpesp = new String [] { 52 "org.netbeans.beaninfo.editors", "org.openide.explorer.propertysheet.editors", }; 55 String [] allpesp = new String [syspesp.length + nbpesp.length]; 56 System.arraycopy(nbpesp, 0, allpesp, 0, nbpesp.length); 57 System.arraycopy(syspesp, 0, allpesp, nbpesp.length, syspesp.length); 58 PropertyEditorManager.setEditorSearchPath(allpesp); 59 } 60 61 62 63 public PropertyPanelTest(String name) { 64 super(name); 65 } 66 67 public static void main (String [] args) { 68 junit.textui.TestRunner.run (new NbTestSuite (PropertyPanelTest.class)); 69 } 70 71 75 private String prop; 76 77 public void setProp (String x) { 78 prop = x; 79 } 80 81 public String getProp () { 82 return prop; 83 } 84 85 JFrame jf; 86 protected void setUp() throws Exception { 87 PropUtils.forceRadioButtons=false; 88 jf = new JFrame(); 89 jf.getContentPane().setLayout(new FlowLayout ()); 90 jf.setSize (400,400); 91 jf.setLocation (30,30); 92 jf.show(); 93 } 94 95 96 public void testStateUpdates () throws Exception { 97 PropertyDescriptor feature = new PropertyDescriptor ("prop", this.getClass ()); 98 feature.setPropertyEditorClass (Ed.class); 99 DefaultPropertyModel model = new DefaultPropertyModel ( 100 this, feature 101 ); 102 103 final PropertyPanel pp = new PropertyPanel (model, PropertyPanel.PREF_CUSTOM_EDITOR); 104 105 SwingUtilities.invokeAndWait(new Runnable () { 108 public void run() { 109 jf.getContentPane().add(pp); 110 System.err.println(" Aded to panel"); 111 jf.validate(); 112 jf.repaint(); 113 System.err.println(" bounds: " + pp.getBounds()); 114 } 115 }); 116 Thread.currentThread().sleep(1000); 117 118 assertTrue ("Ed editor created", pp.getPropertyEditor() instanceof Ed); 119 120 Ed ed = (Ed)pp.getPropertyEditor (); 121 122 assertNotNull("PropertyPanel returns the right property editor", ed); 123 124 assertNotNull("Environment has not been attached", ed.env); 125 126 Listener envListener = new Listener (); 127 Listener panelListener = new Listener (); 128 129 pp.addPropertyChangeListener(panelListener); 130 ed.env.addPropertyChangeListener (envListener); 131 ed.env.addVetoableChangeListener (envListener); 132 133 ed.env.setState (PropertyEnv.STATE_INVALID); 134 135 assertEquals ("State of panel is invalid", PropertyEnv.STATE_INVALID, pp.getState ()); 136 envListener.assertChanges ("Notified in environment", 1, 1); 137 panelListener.assertChanges ("Notified in panel", 1, 0); 138 139 ed.env.setState (PropertyEnv.STATE_INVALID); 140 assertEquals ("Remains invalid", PropertyEnv.STATE_INVALID, pp.getState ()); 141 envListener.assertChanges ("No changes notified", 0, 0); 142 panelListener.assertChanges ("No changes notified in panel", 0, 0); 143 144 pp.updateValue(); 145 146 assertEquals ("Update valud does not change the state if invalid", PropertyEnv.STATE_INVALID, pp.getState ()); 147 envListener.assertChanges ("Changes notified in env", 0, 0); 148 panelListener.assertChanges ("Notified in panel", 0, 0); 149 150 ed.env.setState (PropertyEnv.STATE_NEEDS_VALIDATION); 151 assertEquals ("Now we need validation", PropertyEnv.STATE_NEEDS_VALIDATION, pp.getState ()); 152 envListener.assertChanges ("Notified in environment", 1, 1); 153 panelListener.assertChanges ("Notified in panel", 1, 0); 154 155 pp.updateValue (); 156 assertEquals ("Update from needs validation shall switch to valid state if not vetoed", PropertyEnv.STATE_VALID, pp.getState ()); 157 envListener.assertChanges ("Notified in environment", 1, 1); 158 panelListener.assertChanges ("Notified in panel", 1, 0); 159 160 ed.env.setState (PropertyEnv.STATE_NEEDS_VALIDATION); 161 assertEquals ("Now we need validation", PropertyEnv.STATE_NEEDS_VALIDATION, pp.getState ()); 162 envListener.assertChanges ("Notified in environment", 1, 1); 163 panelListener.assertChanges ("Notified in panel", 1, 0); 164 165 166 envListener.shallVeto = true; 167 pp.updateValue (); 168 assertTrue ("Was vetoed", !envListener.shallVeto); 169 170 assertEquals ("The state remains", PropertyEnv.STATE_NEEDS_VALIDATION, pp.getState ()); 171 envListener.assertChanges ("No approved property changes", 0, -1); 172 panelListener.assertChanges ("No approved property changes", 0, -1); 173 174 175 179 DefaultPropertyModel replace = new DefaultPropertyModel (this, "prop"); 180 pp.setModel (replace); 181 182 assertEquals ("Model changed", replace, pp.getModel()); 183 184 185 WeakReference wEd = new WeakReference (ed); 186 WeakReference wEnv = new WeakReference (ed.env); 187 188 ed = null; 189 190 assertGC ("Property editor should disappear", wEd); 191 assertGC ("Environment should disapper", wEnv); 192 } 193 194 private void addToPanel(final PropertyPanel pp) throws Exception { 195 SwingUtilities.invokeAndWait(new Runnable () { 198 public void run() { 199 jf.getContentPane().add(pp); 200 jf.validate(); 201 jf.repaint(); 202 } 203 }); 204 Thread.currentThread().sleep(500); 205 } 206 207 private void removeFromPanel(final PropertyPanel pp) throws Exception { 208 SwingUtilities.invokeAndWait(new Runnable () { 211 public void run() { 212 jf.getContentPane().remove(pp); 213 jf.validate(); 214 jf.repaint(); 215 } 216 }); 217 Thread.currentThread().sleep(500); 218 } 219 220 public void testPropertyPanelShallGCEvenIfEditorExists () throws Exception { 221 PropertyDescriptor feature = new PropertyDescriptor ("prop", this.getClass ()); 222 feature.setPropertyEditorClass (Ed.class); 223 DefaultPropertyModel model = new DefaultPropertyModel ( 224 this, feature 225 ); 226 227 PropertyPanel pp = new PropertyPanel (model, PropertyPanel.PREF_CUSTOM_EDITOR); 228 addToPanel(pp); 229 230 assertTrue ("Ed editor created", pp.getPropertyEditor() instanceof Ed); 231 232 Ed ed = (Ed)pp.getPropertyEditor (); 233 assertNotNull ("Environment has been attached", ed.env); 234 235 Listener panelListener = new Listener (); 239 240 pp.addPropertyChangeListener (panelListener); 241 ed.env.setState (PropertyEnv.STATE_INVALID); 242 panelListener.assertChanges ("Change notified in panel", 1, 0); 243 244 removeFromPanel(pp); 245 pp.removePropertyChangeListener(panelListener); 246 247 WeakReference weak = new WeakReference (pp); 248 pp = null; 249 model = null; 250 feature = null; 251 252 assertGC ("Panel should disappear even if we have reference to property editor", weak); 253 } 254 255 public void testCompatibilityWhenUsingNodePropertyAndAskingForPropertyModel () throws Exception { 256 final Ed editor = new Ed (); 257 258 class NP extends org.openide.nodes.Node.Property { 259 private Object value; 260 261 public NP () { 262 super (Runnable .class); 263 } 264 265 public Object getValue () { 266 return value; 267 } 268 269 public void setValue (Object o) { 270 this.value = o; 271 } 272 273 public boolean canWrite () { 274 return true; 275 } 276 277 public boolean canRead () { 278 return true; 279 } 280 281 public java.beans.PropertyEditor getPropertyEditor () { 282 return editor; 283 } 284 } 285 286 NP property = new NP (); 287 PropertyPanel panel = new PropertyPanel (property); 288 289 assertEquals ("The property is mine", property, panel.getProperty ()); 290 assertEquals ("Editor is delegated", editor, panel.getPropertyEditor()); 291 assertNotNull ("There is a model", panel.getModel ()); 292 assertEquals ("Type is delegated", Runnable .class, panel.getModel ().getPropertyType()); 293 294 Listener listener = new Listener(); 295 PropertyModel model = panel.getModel (); 296 model.addPropertyChangeListener(listener); 297 panel.getProperty ().setValue (this); 298 299 assertEquals("Value changed in model", this, model.getValue()); 300 assertEquals("Value changed in prop", this, panel.getProperty().getValue()); 301 } 302 303 public void testCompatibilityWhenUsingPropertyModelAndAskingForNodeProperty () throws Exception { 304 class PM implements PropertyModel { 305 private Object value; 306 private PropertyChangeListener listener; 307 308 public PM() { 309 } 310 311 public void addPropertyChangeListener (PropertyChangeListener l) { 312 assertNull ("Support for only one listener is here now", listener); 313 listener = l; 314 } 315 316 public void removePropertyChangeListener (PropertyChangeListener l) { 317 assertEquals ("Removing the one added", listener, l); 318 listener = null; 319 } 320 321 public Class getPropertyType () { 322 return Runnable .class; 323 } 324 325 public Object getValue() { 326 return value; 327 } 328 329 public void setValue(Object o) { 330 Object old = value; 331 332 this.value = o; 333 if (listener != null) { 334 listener.propertyChange (new PropertyChangeEvent (this, "value", old, o)); 335 } 336 } 337 346 347 public Class getPropertyEditorClass () { 348 return Ed.class; 349 } 350 } 351 352 PM model = new PM (); 353 PropertyPanel panel = new PropertyPanel(model, 0); 354 355 assertEquals("The model is mine", model, panel.getModel()); 356 assertEquals("Editor is delegated", Ed.class, panel.getPropertyEditor().getClass ()); 357 assertNotNull("There is a property", panel.getProperty()); 358 assertEquals("Type is delegated", Runnable .class, panel.getProperty ().getValueType()); 359 360 panel.getProperty ().setValue (this); 361 assertEquals ("Value changed in model", this, model.getValue ()); 362 assertEquals ("Value changed in prop", this, panel.getProperty ().getValue ()); 363 364 365 model.setValue (model); 366 assertEquals("Value change propagated into prop", model, panel.getProperty().getValue()); 367 } 368 369 370 378 public void testPropertyPanelPropagatesChangesEvenWhenItDoesntExist() throws Exception { 379 class PM implements PropertyModel { 380 private Object value; 381 private PropertyChangeListener listener=null; 382 private PropertyChangeListener listener2=null; 383 384 public PM() { 385 } 386 387 public void addPropertyChangeListener(PropertyChangeListener l) { 388 if (listener != null) { 389 listener2 = l; 390 } else { 391 listener = l; 392 } 393 } 394 395 public void removePropertyChangeListener(PropertyChangeListener l) { 396 if (l == listener) { 397 listener = null; 398 return; 399 } 400 if (l == listener2) { 401 listener2 = null; 402 return; 403 } 404 fail("Tried to remove a listener that was never attached: " + l); 405 } 406 407 public Class getPropertyType() { 408 return Runnable .class; 409 } 410 411 public Object getValue() { 412 return value; 413 } 414 415 public void setValue(Object o) { 416 Object old = value; 417 this.value = o; 418 if (listener != null) { 419 listener.propertyChange(new PropertyChangeEvent(this, "value", old, o)); 420 } 421 if (listener2 != null) { 422 listener2.propertyChange(new PropertyChangeEvent(this, "value", old, o)); 423 } 424 assertTrue ("Some listener should still be listenening", listener != null || listener2 != null); 425 } 426 427 public void assertValueChangedTo(Object o) throws Exception { 428 assertSame("Value should have been updated even though property panel doesn't exist", value, o); 429 } 430 431 public Class getPropertyEditorClass() { 432 return Ed.class; 433 } 434 } 435 436 PM model = new PM(); 437 PropertyPanel pp = new PropertyPanel(model, PropertyPanel.PREF_CUSTOM_EDITOR); 438 439 addToPanel(pp); 440 441 assertTrue("Ed editor created", pp.getPropertyEditor() instanceof Ed); 442 443 Ed ed = (Ed)pp.getPropertyEditor(); 444 445 removeFromPanel(pp); 446 447 WeakReference weak = new WeakReference (pp); 448 pp = null; 449 450 Runnable toTest = new Runnable () { 451 public void run() { 452 } 453 }; 454 455 ed.setValue(toTest); 456 457 model.assertValueChangedTo(toTest); 458 459 } 460 461 462 464 private static final class Listener 465 implements PropertyChangeListener, VetoableChangeListener { 466 public boolean shallVeto; 467 468 private int veto; 469 private int change; 470 471 public void assertChanges (String t, int c, int v) { 472 if (c != -1) { 473 assertEquals (t + " [propertychange]", c, change); 474 } 475 476 if (v != -1) { 477 assertEquals (t + " [vetochange]", v, veto); 478 } 479 480 change = 0; 481 veto = 0; 482 } 483 484 public void propertyChange(java.beans.PropertyChangeEvent propertyChangeEvent) { 485 change++; 486 } 487 488 public void vetoableChange(java.beans.PropertyChangeEvent propertyChangeEvent) throws java.beans.PropertyVetoException { 489 if (shallVeto) { 490 shallVeto = false; 491 PropertyVetoException e = new PropertyVetoException ("Veto", propertyChangeEvent); 492 493 PropertyDialogManager.doNotNotify (e); 495 throw e; 496 } 497 498 veto++; 499 } 500 501 } 502 503 505 private static final class Ed extends java.beans.PropertyEditorSupport 506 implements ExPropertyEditor { 507 public PropertyEnv env; 508 509 public Ed () { 510 } 511 512 public void addPropertyChangeListener (PropertyChangeListener pcl) { 513 super.addPropertyChangeListener(pcl); 514 } 515 516 public void attachEnv(PropertyEnv env) { 517 this.env = env; 518 } 519 520 public boolean supportsCustomEditor() { 527 return true; 528 } 529 530 public Component getCustomEditor() { 532 JPanel result = new JPanel (); 533 result.setBackground(java.awt.Color.ORANGE); 534 return result; 535 } 536 } 537 538 } 539 540 541 542 | Popular Tags |