KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > explorer > propertysheet > PropertyPanelTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18 */

19
20 package org.openide.explorer.propertysheet;
21
22 import java.awt.Component JavaDoc;
23 import java.awt.FlowLayout JavaDoc;
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 JavaDoc;
36 import java.awt.IllegalComponentStateException JavaDoc;
37 import java.lang.ref.WeakReference JavaDoc;
38 import java.lang.reflect.InvocationTargetException JavaDoc;
39 import javax.swing.JPanel JavaDoc;
40
41 /** A test of a property panel.
42  */

43 public final class PropertyPanelTest extends NbTestCase {
44     static {
45         //Added with property panel rewrite - the property model given the
46
//variable name "replace" is a String property, and the default
47
//property editor for the JDK does not support a custom editor.
48
//PropertyPanel will no longer allow itself to be put in custom editor
49
//mode if the property does not support a custom editor.
50
String JavaDoc[] syspesp = PropertyEditorManager.getEditorSearchPath();
51         String JavaDoc[] nbpesp = new String JavaDoc[] {
52             "org.netbeans.beaninfo.editors", // NOI18N
53
"org.openide.explorer.propertysheet.editors", // NOI18N
54
};
55         String JavaDoc[] allpesp = new String JavaDoc[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 JavaDoc name) {
64         super(name);
65     }
66     
67     public static void main (String JavaDoc[] args) {
68         junit.textui.TestRunner.run (new NbTestSuite (PropertyPanelTest.class));
69     }
70     
71     //
72
// Sample property impl
73
//
74

75     private String JavaDoc prop;
76     
77     public void setProp (String JavaDoc x) {
78         prop = x;
79     }
80     
81     public String JavaDoc getProp () {
82         return prop;
83     }
84    
85     JFrame jf;
86     protected void setUp() throws Exception JavaDoc {
87         PropUtils.forceRadioButtons=false;
88         jf = new JFrame();
89         jf.getContentPane().setLayout(new FlowLayout JavaDoc());
90         jf.setSize (400,400);
91         jf.setLocation (30,30);
92         jf.show();
93     }
94
95
96     public void testStateUpdates () throws Exception JavaDoc {
97         PropertyDescriptor JavaDoc feature = new PropertyDescriptor JavaDoc ("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         //The property panel must be displayed - it will not attempt to communicate
106
//with the property editor until it is on screen
107
SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
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         //
176
// Now try to do the cleanup
177
//
178

179         DefaultPropertyModel replace = new DefaultPropertyModel (this, "prop");
180         pp.setModel (replace);
181         
182         assertEquals ("Model changed", replace, pp.getModel());
183         
184         
185         WeakReference JavaDoc wEd = new WeakReference JavaDoc (ed);
186         WeakReference JavaDoc wEnv = new WeakReference JavaDoc (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 JavaDoc {
195         //The property panel must be displayed - it will not attempt to communicate
196
//with the property editor until it is on screen
197
SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
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 JavaDoc {
208         //The property panel must be displayed - it will not attempt to communicate
209
//with the property editor until it is on screen
210
SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
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 JavaDoc {
221         PropertyDescriptor JavaDoc feature = new PropertyDescriptor JavaDoc ("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         //
236
// Make sure that the panel listens on changes in env
237
//
238
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 JavaDoc weak = new WeakReference JavaDoc (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 JavaDoc {
256         final Ed editor = new Ed ();
257         
258         class NP extends org.openide.nodes.Node.Property {
259             private Object JavaDoc value;
260             
261             public NP () {
262                 super (Runnable JavaDoc.class);
263             }
264             
265             public Object JavaDoc getValue () {
266                 return value;
267             }
268             
269             public void setValue (Object JavaDoc 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 JavaDoc 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 JavaDoc.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 JavaDoc {
304         class PM implements PropertyModel {
305             private Object JavaDoc 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 JavaDoc getPropertyType () {
322                 return Runnable JavaDoc.class;
323             }
324             
325             public Object JavaDoc getValue() {
326                 return value;
327             }
328             
329             public void setValue(Object JavaDoc o) {
330                 Object JavaDoc old = value;
331                 
332                 this.value = o;
333                 if (listener != null) {
334                     listener.propertyChange (new PropertyChangeEvent (this, "value", old, o));
335                 }
336             }
337             /*
338             public boolean canWrite() {
339                 return true;
340             }
341             
342             public boolean canRead() {
343                 return true;
344             }
345              */

346             
347             public Class JavaDoc 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 JavaDoc.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     /** Tests a truly perverse abuse of PropertyPanel that is needed for backward
371      * compatibility. The editor colorings dialog and diff engine custom editor
372      * dialogs both can cause the PropertyPanel which invoked them to be removed
373      * from the AWT hierarchy and destroyed. <strong>But</strong> the code expects
374      * changes to continue being propagated afterward <strong>and</strong> that
375      * this not cause a memory leak(!!!).
376      *
377      * @see org.openide.explorer.propertysheet.CustomEditorDisplayer.Spud */

378     public void testPropertyPanelPropagatesChangesEvenWhenItDoesntExist() throws Exception JavaDoc {
379         class PM implements PropertyModel {
380             private Object JavaDoc 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 JavaDoc getPropertyType() {
408                 return Runnable JavaDoc.class;
409             }
410             
411             public Object JavaDoc getValue() {
412                 return value;
413             }
414             
415             public void setValue(Object JavaDoc o) {
416                 Object JavaDoc 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 JavaDoc o) throws Exception JavaDoc {
428                 assertSame("Value should have been updated even though property panel doesn't exist", value, o);
429             }
430             
431             public Class JavaDoc 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 JavaDoc weak = new WeakReference JavaDoc(pp);
448         pp = null;
449         
450         Runnable JavaDoc toTest = new Runnable JavaDoc() {
451             public void run() {
452             }
453         };
454         
455         ed.setValue(toTest);
456         
457         model.assertValueChangedTo(toTest);
458         
459     }
460     
461     
462     /** Listener that counts changes.
463      */

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 JavaDoc 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 JavaDoc propertyChangeEvent) {
485             change++;
486         }
487         
488         public void vetoableChange(java.beans.PropertyChangeEvent JavaDoc propertyChangeEvent) throws java.beans.PropertyVetoException JavaDoc {
489             if (shallVeto) {
490                 shallVeto = false;
491                 PropertyVetoException e = new PropertyVetoException ("Veto", propertyChangeEvent);
492                 
493                 // marks this exception as one that we do not want to notify
494
PropertyDialogManager.doNotNotify (e);
495                 throw e;
496             }
497             
498             veto++;
499         }
500         
501     }
502
503     /** Sample property editor.
504      */

505     private static final class Ed extends java.beans.PropertyEditorSupport JavaDoc
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         //The two methods below are added because, in the property panel
521
//rewrite, the property panel uses polling with a ReusablePropertyEnv
522
//to determine valid state for editors that do not support a custom
523
//editor - and the PropertyPanel cannot be initialized into custom
524
//editor mode for a property editor that doesn't actually support
525
//custom editors
526
public boolean supportsCustomEditor() {
527             return true;
528         }
529         
530         //To avoid NPE when propertypanel tries to add the custom editor
531
public Component JavaDoc getCustomEditor() {
532             JPanel JavaDoc result = new JPanel JavaDoc();
533             result.setBackground(java.awt.Color.ORANGE);
534             return result;
535         }
536     }
537     
538 }
539
540
541
542
Popular Tags