001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.form;
043:
044: import java.awt.Component;
045: import java.awt.Graphics;
046: import java.awt.Rectangle;
047: import java.beans.PropertyChangeEvent;
048: import java.beans.PropertyChangeListener;
049: import java.beans.PropertyChangeSupport;
050: import java.beans.PropertyEditor;
051: import java.beans.PropertyVetoException;
052: import java.beans.VetoableChangeListener;
053: import javax.swing.JPanel;
054: import javax.swing.event.ChangeEvent;
055: import javax.swing.event.ChangeListener;
056: import org.jdesktop.layout.GroupLayout;
057: import org.jdesktop.layout.LayoutStyle;
058: import org.openide.explorer.propertysheet.ExPropertyEditor;
059: import org.openide.explorer.propertysheet.PropertyEnv;
060:
061: /**
062: * A property editor that can wrap another property editor and make it use
063: * a ResourcePanel allowing to define the property value as a resource
064: * (represented by ResourceValue). E.g. StringEditor in o.n.m.f.editors2 package
065: * wraps a plain property editor for strings. FormPropertyEditorManager and
066: * FormPropertyEditor support this wrapping.
067: *
068: * @author Tomas Pavek
069: */
070: public class ResourceWrapperEditor implements ExPropertyEditor,
071: FormAwareEditor, PropertyChangeListener, ChangeListener,
072: VetoableChangeListener {
073:
074: protected PropertyEditor delegateEditor;
075: protected FormModel formModel;
076: protected FormProperty property;
077: private boolean ignoreChange;
078: private PropertyChangeSupport changeSupport;
079:
080: private Object propertyValue;
081:
082: // not very nice, but we suppose it's ok to have just one valid custom editor at a moment
083: protected ResourcePanel resourcePanel;
084:
085: public ResourceWrapperEditor(PropertyEditor wrappedPropEd) {
086: delegateEditor = wrappedPropEd;
087: delegateEditor.addPropertyChangeListener(this );
088: }
089:
090: public PropertyEditor getDelegatedPropertyEditor() {
091: return delegateEditor;
092: }
093:
094: void setDelegatedPropertyEditor(PropertyEditor delegate) {
095: delegateEditor.removePropertyChangeListener(this );
096: delegateEditor = delegate;
097: delegateEditor.addPropertyChangeListener(this );
098: propertyValue = delegateEditor.getValue();
099: }
100:
101: // -----
102:
103: // FormAwareEditor implementation
104: public void setContext(FormModel formModel, FormProperty prop) {
105: this .formModel = formModel;
106: this .property = prop;
107: if (delegateEditor instanceof FormAwareEditor) {
108: ((FormAwareEditor) delegateEditor).setContext(formModel,
109: prop);
110: }
111: }
112:
113: // FormAwareEditor implementation
114: public void updateFormVersionLevel() {
115: if (getValue() instanceof ResourceValue) {
116: formModel.raiseVersionLevel(FormModel.FormVersion.NB60,
117: FormModel.FormVersion.NB60);
118: }
119: }
120:
121: // ExPropertyEditor implementation
122: public void attachEnv(PropertyEnv env) {
123: if (property != null) {
124: env.removeVetoableChangeListener(this );
125: env.setState(PropertyEnv.STATE_NEEDS_VALIDATION);
126: env.addVetoableChangeListener(this );
127: }
128: if (delegateEditor instanceof ExPropertyEditor)
129: ((ExPropertyEditor) delegateEditor).attachEnv(env);
130: }
131:
132: public void setValue(Object value) {
133: propertyValue = value;
134: ignoreChange = true;
135: setValueToDelegate(value);
136: ignoreChange = false;
137: firePropertyChange();
138: }
139:
140: public Object getValue() {
141: return propertyValue;
142: }
143:
144: public Object getUnwrappedValue() {
145: return delegateEditor.getValue();
146: }
147:
148: public void setAsText(String text) {
149: if (text.equals(delegateEditor.getAsText()))
150: return;
151:
152: ignoreChange = true;
153: delegateEditor.setAsText(text);
154: ignoreChange = false;
155: propertyValue = delegateEditor.getValue();
156: firePropertyChange();
157: }
158:
159: public String getAsText() {
160: return delegateEditor.getAsText();
161: }
162:
163: public boolean isPaintable() {
164: return delegateEditor.isPaintable();
165: }
166:
167: public void paintValue(Graphics g, Rectangle box) {
168: delegateEditor.paintValue(g, box);
169: }
170:
171: public String getJavaInitializationString() {
172: if (propertyValue instanceof ResourceValue)
173: return ((ResourceValue) propertyValue)
174: .getJavaInitializationCode();
175: else
176: return delegateEditor.getJavaInitializationString();
177: }
178:
179: public String[] getTags() {
180: return delegateEditor.getTags();
181: }
182:
183: public Component getCustomEditor() {
184: if (resourcePanel == null) {
185: createResourcePanel();
186: }
187:
188: Component resGUI;
189: if (resourcePanel != null) {
190: String key;
191: boolean enable;
192: if (propertyValue instanceof ResourceValue) {
193: key = ((ResourceValue) propertyValue).getKey();
194: enable = true;
195: } else {
196: key = ResourceSupport.getDefaultKey(property,
197: ResourceSupport.AUTO_RESOURCING);
198: enable = ResourceSupport
199: .isPropertyForResourcing(property);
200: }
201: resourcePanel.init(key, enable);
202: resGUI = resourcePanel.getComponent();
203: } else {
204: resGUI = null;
205: }
206:
207: return createCustomEditorGUI(resGUI);
208: }
209:
210: public boolean supportsCustomEditor() {
211: return true;
212: }
213:
214: public void addPropertyChangeListener(PropertyChangeListener l) {
215: synchronized (this ) {
216: if (changeSupport == null)
217: changeSupport = new PropertyChangeSupport(this );
218: }
219: changeSupport.addPropertyChangeListener(l);
220: }
221:
222: public void removePropertyChangeListener(PropertyChangeListener l) {
223: if (changeSupport != null)
224: changeSupport.removePropertyChangeListener(l);
225: }
226:
227: // -----
228:
229: protected void setValueToDelegate(Object value) {
230: if (value instanceof ResourceValue)
231: value = ((ResourceValue) value).getValue();
232: delegateEditor.setValue(value);
233: }
234:
235: protected void setValueToResourcePanel() {
236: resourcePanel.setValue(delegateEditor.getValue(), null, null);
237: }
238:
239: // called from the delegated editor
240: public void propertyChange(PropertyChangeEvent evt) {
241: if (!ignoreChange) { // change initiated through custom editor of the delegate
242: if (propertyValue instanceof ResourceValue)
243: setValueToResourcePanel();
244: else
245: propertyValue = delegateEditor.getValue();
246: firePropertyChange();
247: }
248: }
249:
250: // called from ResourcePanel when the key or current value has changed
251: public void stateChanged(ChangeEvent e) {
252: ResourceValue resValue = resourcePanel.getResource();
253: if (resValue != null) {
254: if (resValue.getValue() == null) {
255: // resource panel just enabled or set with a new key
256: setValueToResourcePanel();
257: resValue = resourcePanel.getResource();
258: }
259: setValue(resValue);
260: } else { // resource panel disabled
261: propertyValue = delegateEditor.getValue();
262: firePropertyChange();
263: }
264: }
265:
266: // called when OK button is pressed in the custom editor dialog
267: // TODO: this should only be done if this property editor is the selected one
268: public void vetoableChange(PropertyChangeEvent ev)
269: throws PropertyVetoException {
270: if (PropertyEnv.PROP_STATE.equals(ev.getPropertyName())) {
271: boolean excludeRes = false;
272: if (resourcePanel != null) {
273: ResourceValue resValue;
274: if (propertyValue instanceof ResourceValue
275: && (resValue = resourcePanel.getResource()) != null) { // make sure we have the latest resource value
276: if (resValue.getValue() == ResourceValue.IGNORED_VALUE) {
277: throw new PropertyVetoException(
278: "Invalid resource value", ev);
279: // TODO: message dialog about invalid value
280: }
281: if (resValue != propertyValue) {
282: setValue(resValue);
283: }
284: } else {
285: excludeRes = true; // have resource panel, but just using plain value
286: }
287: }
288: ResourceSupport.setExcludedProperty(property, excludeRes);
289: }
290: }
291:
292: private void firePropertyChange() {
293: if (changeSupport != null)
294: changeSupport.firePropertyChange("", null, null); // NOI18N
295: }
296:
297: // -----
298:
299: private void createResourcePanel() {
300: resourcePanel = ResourceSupport.createResourcePanel(property,
301: propertyValue instanceof ResourceValue);
302: if (resourcePanel != null)
303: resourcePanel.addChangeListener(this );
304: }
305:
306: protected Component createCustomEditorGUI(Component resourcePanelGUI) {
307: if (resourcePanelGUI == null)
308: return delegateEditor.getCustomEditor();
309:
310: JPanel panel = new JPanel();
311: Component delComp = delegateEditor.getCustomEditor();
312: GroupLayout layout = new GroupLayout(panel);
313: panel.setLayout(layout);
314: layout.setAutocreateGaps(true);
315: layout.setHorizontalGroup(layout.createParallelGroup().add(
316: delComp).add(
317: layout.createSequentialGroup().addPreferredGap(
318: LayoutStyle.RELATED).add(resourcePanelGUI)
319: .addPreferredGap(LayoutStyle.RELATED)));
320: layout.setVerticalGroup(layout.createSequentialGroup().add(
321: delComp).addPreferredGap(LayoutStyle.UNRELATED).add(
322: resourcePanelGUI));
323:
324: return panel;
325: }
326: }
|