KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > j2ee > sun > share > configbean > customizers > common > BaseCustomizer


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  * BaseCustomizer.java
21  *
22  * Created on October 8, 2003, 11:13 AM
23  */

24
25 package org.netbeans.modules.j2ee.sun.share.configbean.customizers.common;
26
27 import java.util.ResourceBundle JavaDoc;
28
29 import java.awt.Color JavaDoc;
30 import java.awt.Component JavaDoc;
31 import java.awt.Container JavaDoc;
32
33 import java.beans.Customizer JavaDoc;
34 import java.beans.PropertyChangeEvent JavaDoc;
35 import java.beans.PropertyChangeListener JavaDoc;
36
37 import javax.swing.JPanel JavaDoc;
38 import javax.swing.ImageIcon JavaDoc;
39 import javax.swing.UIManager JavaDoc;
40 import org.openide.ErrorManager;
41
42 import org.openide.util.HelpCtx;
43
44 import org.netbeans.modules.j2ee.sun.share.configbean.Base;
45 import org.netbeans.modules.j2ee.sun.share.configbean.Utils;
46 import org.netbeans.modules.j2ee.sun.share.configbean.ErrorMessageDB;
47 import org.netbeans.modules.j2ee.sun.share.configbean.ValidationError;
48
49
50 /** Base customizer class is abstract due to not implementing Customizer.setObject()
51  * and getHelpId(). These methods should be implemented by the derived class.
52  *
53  * Derived classes of this class should use the following design pattern:
54  *
55  * They should have an initComponents() method (typically created and locked by
56  * the NetBeans form editor) that is called from the constructor.
57  *
58  * They should also have a user defined method 'void initUserComponents()' that
59  * is called in the constructor <b>after</b> initComponents(). The body of this
60  * method should call <code>addTitlePanel(String)</code>, then perform any required
61  * additions or modifications of the main panel content and then call
62  * <code>addErrorPanel()</code> as the last line to enable the title and error
63  * message displays, respectively. See WebAppRootCustomizer for an example.
64  *
65  * @author Peter Williams
66  * @version %I%, %G%
67  */

68 public abstract class BaseCustomizer extends JPanel JavaDoc implements Customizer JavaDoc,
69     HelpCtx.Provider, CustomizerErrorPanel.ErrorClient {
70             
71     /** Reference to the resource bundle in customizers/common
72      */

73     protected static final ResourceBundle JavaDoc commonBundle = ResourceBundle.getBundle(
74         "org.netbeans.modules.j2ee.sun.share.configbean.customizers.common.Bundle"); // NOI18N
75

76     /** Path for help button image resource
77      */

78     private static final String JavaDoc errorGlyphPath =
79         "org/netbeans/modules/j2ee/sun/share/configbean/customizers/common/resources/errorGlyph.gif"; // NOI18N
80

81     /** We only want to load this once. It's only used here, but in case someone
82      * decides to use it elsewhere, we'll make it public.
83      */

84 // public static final ImageIcon panelErrorIcon =
85
// new ImageIcon(Utils.getResourceURL(errorGlyphPath, BaseCustomizer.class));
86
public static ImageIcon JavaDoc panelErrorIcon;
87
88     static {
89         // This is diagnostic test code to try to get more information about a
90
// suspicious intermittant exception
91
try {
92             panelErrorIcon = new ImageIcon JavaDoc(Utils.getResourceURL(errorGlyphPath, BaseCustomizer.class));
93         } catch(NullPointerException JavaDoc ex) {
94             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
95             panelErrorIcon = null;
96         }
97     }
98     
99     /** Error/warning message icons.
100      */

101     private static final String JavaDoc errorIconPath =
102         "org/netbeans/modules/j2ee/sun/share/configbean/customizers/common/resources/errorIcon.png"; // NOI18N
103
private static final String JavaDoc warningIconPath =
104         "org/netbeans/modules/j2ee/sun/share/configbean/customizers/common/resources/warningIcon.png"; // NOI18N
105

106     public static ImageIcon JavaDoc errorMessageIcon;
107     public static ImageIcon JavaDoc warningMessageIcon;
108
109     static {
110         // Diagnostic test code to try to get more information about a suspicious intermittant exception
111
// (This is circa NB 4.1, so it may not be necessary anymore).
112
try {
113             errorMessageIcon = new ImageIcon JavaDoc(Utils.getResourceURL(errorIconPath, InputDialog.class));
114         } catch(NullPointerException JavaDoc ex) {
115             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
116             errorMessageIcon = null;
117         }
118         try {
119             warningMessageIcon = new ImageIcon JavaDoc(Utils.getResourceURL(warningIconPath, InputDialog.class));
120         } catch(NullPointerException JavaDoc ex) {
121             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex);
122             warningMessageIcon = null;
123         }
124     }
125     
126     
127     /** !PW Foreground color for error message text when in the NetBeans IDE.
128      * See http://ui.netbeans.org/docs/inline_errors/index.html, about
129      * halfway down, for specification. (Was light blue: [89, 79, 191])
130      */

131     private static final Object JavaDoc colorMonitor = new Object JavaDoc();
132     private static Color JavaDoc errorTextForegroundColor = null;
133     private static Color JavaDoc warningTextForegroundColor = null;
134     
135     public static Color JavaDoc getErrorForegroundColor() {
136         Color JavaDoc result = null;
137         
138         synchronized(colorMonitor) {
139             if(errorTextForegroundColor == null) {
140                 errorTextForegroundColor = UIManager.getColor("nb.errorForeground");
141                 if(errorTextForegroundColor == null) {
142                     errorTextForegroundColor = new Color JavaDoc(89, 79, 191); // See http://ui.netbeans.org/docs/inline_errors/index.html
143
}
144             }
145             
146             result = errorTextForegroundColor;
147         }
148         
149         return result;
150     }
151     
152     public static Color JavaDoc getWarningForegroundColor() {
153         Color JavaDoc result = null;
154         
155         synchronized(colorMonitor) {
156             if(warningTextForegroundColor == null) {
157                 warningTextForegroundColor = UIManager.getColor("Label.foreground");
158                 if(warningTextForegroundColor == null) {
159                     warningTextForegroundColor = new Color JavaDoc(0,0,0); // black
160
}
161             }
162             
163             result = warningTextForegroundColor;
164         }
165         
166         return result;
167     }
168     
169     /** -----------------------------------------------------------------------
170      * State variables managed by BaseCustomizer
171      */

172     /** The bean being editing, referenced by base class. The design pattern
173      * I've used for the webapp and common customizers also maintains a reference
174      * to the appropriate derived bean class in the derived customizer class.
175      */

176     private Base theBaseBean;
177     
178     /** The title panel */
179     private CustomizerTitlePanel titlePanel;
180     
181     /** The error panel */
182     private CustomizerErrorPanel errorPanel;
183     
184     
185     /** BaseCustomizer constructor */
186     public BaseCustomizer() {
187         titlePanel = new CustomizerTitlePanel();
188         errorPanel = new CustomizerErrorPanel(this);
189     }
190
191     /** Adds the title panel (also contains help button). This method should
192      * be called in the derived customizer's initUserComponents(). It can be
193      * called at any time from this method. (See class description for the
194      * design pattern that defines 'initUserComponents()'.
195      *
196      * @param title The title to display in the panel, e.g "Sun Web Appplication".
197      */

198     protected void addTitlePanel(String JavaDoc title) {
199         titlePanel.setCustomizerTitle(title);
200         add(titlePanel, titlePanel.getConstraints(), 0);
201     }
202     
203     /** Retrieves a reference to the title panel
204      *
205      * @return a reference to the title panel.
206      */

207     public CustomizerTitlePanel getTitlePanel() {
208         return titlePanel;
209     }
210     
211     /** Adds the error panel. This method should be called in the derived
212      * customizer's initUserComponents(). It must be called <b>at the end</b>
213      * of this method, because this panel must be the last panel added to the
214      * customizer (as it goes at the bottom.) (See class description for the
215      * design pattern that defines 'initUserComponents()'.
216      */

217     protected void addErrorPanel() {
218         add(errorPanel, errorPanel.getConstraints());
219     }
220     
221     /** Retrieves a reference to the error panel
222      *
223      * @return a reference to the error panel.
224      */

225     public CustomizerErrorPanel getErrorPanel() {
226         return errorPanel;
227     }
228
229     
230     /** -----------------------------------------------------------------------
231      * Implementation of Customizer interface
232      */

233     public void setObject(Object JavaDoc bean) {
234         if(theBaseBean != bean) {
235             if(theBaseBean != null) {
236                 // Remove any listeners added in addListeners().
237
removeListeners();
238             }
239
240             if(setBean(bean)) {
241                 assert (theBaseBean != null) :
242                     "Derived class failed to call super.setBean() in their implementation"; // NOI18N
243

244                 // Initialize the customizer fields with the data from the new bean.
245
initFields();
246                 
247                 // Add any listeners required (includes message db and control listeners.)
248
addListeners();
249                 
250                 // Perform validation on bean to refresh visible validation.
251
validateBean();
252             }
253         }
254     }
255     
256     
257     /** Initialization method for any bean references maintained by this or
258      * derived classes. If derived classes want to maintain a local reference
259      * to the current bean, presumably typecast to the correct type, or want
260      * to protect against the wrong type being passed in, override this method
261      * but make sure 'super.setBean(bean)' is called before doing anything.
262      *
263      * @param bean This is the bean to be edited and should either be an instance
264      * of a DConfigBean (e.g. EjbRef) or null (for nothing to edit.)
265      * @return true if the bean was non-null and the correct type. Derived classes
266      * should return null if the object is not the type they expect.
267      */

268     protected boolean setBean(Object JavaDoc bean) {
269         boolean result = false;
270         
271         if(bean instanceof Base) {
272             theBaseBean = (Base) bean;
273             result = true;
274         } else {
275             theBaseBean = null;
276         }
277         
278         return result;
279     }
280     
281     // Currently used by getTitlePanel -- may change.
282
Base getBean() {
283         return theBaseBean;
284     }
285
286     /** Initialization method called when the bean referenced by the customizer
287      * changes. Derived classes should implement this method and provide
288      * field initialization and enabling/disabling based on the new bean the
289      * customizer is now editing. This method is not called if the bean is
290      * changed to itself.
291      */

292     protected abstract void initFields();
293
294     
295     /** -----------------------------------------------------------------------
296      * Validation
297      */

298     protected PropertyChangeListener JavaDoc validationListener = new PropertyChangeListener JavaDoc() {
299         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
300             if(ErrorMessageDB.VALIDATION_STATE_CHANGED.equals(evt.getPropertyName())) {
301                 validationStateChanged((Boolean JavaDoc) evt.getNewValue());
302             } else if(ErrorMessageDB.PARTITION_STATE_CHANGED.equals(evt.getPropertyName())) {
303                 partitionStateChanged((ErrorMessageDB.PartitionState) evt.getOldValue(),
304                     (ErrorMessageDB.PartitionState) evt.getNewValue());
305             }
306         }
307     };
308     
309     
310     /** Adds listener to the message database for this bean. If derived classes
311      * override this method, ensure they call this version via super.addListeners().
312      */

313     protected void addListeners() {
314         ErrorMessageDB.getMessageDB(theBaseBean).addPropertyChangeListener(validationListener);
315     }
316     
317     
318     /** Removes listener to the message database for this bean. If derived classes
319      * override this method, ensure they call this version via super.removeListeners().
320      */

321     protected void removeListeners() {
322         ErrorMessageDB.getMessageDB(theBaseBean).removePropertyChangeListener(validationListener);
323     }
324     
325         
326     /** Method called by validation database listener when the global validation
327      * state of the edited bean changes. True means the bean is valid (and it's
328      * database is empty). False means there is at least one error on some partition
329      * associated with this bean.
330      *
331      * @param newState New valid state of the edited bean (true = valid).
332      */

333     public void validationStateChanged(Boolean JavaDoc newState) {
334     }
335
336     
337     /** Method called by validation database listener when any partition corresponding
338      * to the edited bean changes. Both old and new states of the partition are
339      * provided so that the user can determine if just messages changed or if
340      * the actual validation state of the partition changed. Override this method
341      * if you want to display errors from anything but the global partition, such
342      * as if this customizer has distinct viewing tabs. See WebAppRootCustomizer
343      * for an example.
344      *
345      * @param oldState The former state of this partition.
346      * @param newState The new state of this partition.
347      */

348     public void partitionStateChanged(ErrorMessageDB.PartitionState oldState,
349         ErrorMessageDB.PartitionState newState) {
350         showErrors();
351     }
352     
353     
354     /** Validates all fields in the bean.
355      *
356      * @return true if the bean is valid, false otherwise.
357      */

358     public boolean validateBean() {
359         return theBaseBean.validateFields(false);
360     }
361
362     
363     /** Validates an individual field (independently of any other errors).
364      *
365      * @param fieldId the field id of the field to be validated.
366      * @return true if the bean is valid, false otherwise.
367      */

368     public boolean validateField(String JavaDoc fieldId) {
369         return theBaseBean.validateField(fieldId);
370     }
371     
372     
373     /** Short cut so derived classes don't have to get the error panel first.
374      */

375     public void showErrors() {
376         errorPanel.showErrors(theBaseBean);
377     }
378     
379     
380     /** Returns the help ID for this customizer. If the customizer has multiple
381      * tabs, the help ID will be for the current active tab (and subtab, etc.)
382      *
383      * @return String representing the current active help ID for this customizer
384      */

385     public abstract String JavaDoc getHelpId();
386     
387     
388     /** -----------------------------------------------------------------------
389      * Implementation of HelpCtx.Provider interface
390      */

391     public HelpCtx getHelpCtx() {
392         return new HelpCtx(getHelpId());
393     }
394     
395     /** -----------------------------------------------------------------------
396      * Helper method to determine the index of a component within a container
397      * (!PW Why isn't this in java.awt.Container? Did I miss it?)
398      *
399      * @param container The container to search.
400      * @param target The component to search for.
401      * @return integer index of the component within the container or -1 if not found.
402      */

403     public static int getComponentIndex(Container JavaDoc container, Component JavaDoc target) {
404         int result = -1;
405         
406         Component JavaDoc [] components = container.getComponents();
407         if(components != null) {
408             for(int i = 0; i < components.length; i++) {
409                 if(components[i] == target) {
410                     result = i;
411                     break;
412                 }
413             }
414         }
415         
416         return result;
417     }
418     
419     /** -----------------------------------------------------------------------
420      * Implementation of CustomizerErrorPanel.ErrorClient interface
421      */

422     /** Returns the foreground color to use for the error text. This is defined
423      * by NetBeans UI spec as RGB: (89, 79, 191)
424      *
425      * @return Color object representing the desired foreground color.
426      */

427     public Color JavaDoc getErrorMessageForegroundColor() {
428         return BaseCustomizer.getErrorForegroundColor();
429     }
430     
431     
432     /** Gets the current panel descriptor. Derived classes with subpanels should
433      * override this method to ensure it returns the partition for the current
434      * selected panel.
435      *
436      * @return Global partition object by default.
437      */

438     public ValidationError.Partition getPartition() {
439         return ValidationError.PARTITION_GLOBAL;
440     }
441 }
442
Popular Tags