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.vmd.midp.propertyeditors;
043:
044: import java.awt.Dimension;
045: import java.awt.GridBagConstraints;
046: import java.awt.GridBagLayout;
047: import java.util.Collections;
048: import javax.swing.JComponent;
049: import javax.swing.JLabel;
050: import javax.swing.JPanel;
051: import javax.swing.JRadioButton;
052: import javax.swing.JScrollPane;
053: import javax.swing.JTextArea;
054: import javax.swing.JTextField;
055: import javax.swing.event.DocumentEvent;
056: import javax.swing.event.DocumentListener;
057: import javax.swing.text.JTextComponent;
058: import org.netbeans.modules.vmd.api.model.DesignComponent;
059: import org.netbeans.modules.vmd.api.model.PropertyValue;
060: import org.netbeans.modules.vmd.api.model.TypeID;
061: import org.netbeans.modules.vmd.midp.components.MidpTypes;
062: import org.netbeans.modules.vmd.midp.components.displayables.TextBoxCD;
063: import org.netbeans.modules.vmd.midp.components.items.TextFieldCD;
064: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorUserCode;
065: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorElement;
066: import org.openide.awt.Mnemonics;
067: import org.openide.util.NbBundle;
068:
069: /**
070: * This class provides property editor for common text properties such as label,
071: * text, etc. This is also an example how to use PropertyEditorUserCode API
072: * with one PropertyEditorElement.
073: *
074: * @author Karol Harezlak
075: * @author Anton Chechel
076: */
077: public class PropertyEditorString extends PropertyEditorUserCode
078: implements PropertyEditorElement {
079:
080: public static final int DEPENDENCE_NONE = 0;
081: public static final int DEPENDENCE_TEXT_BOX = 1;
082: public static final int DEPENDENCE_TEXT_FIELD = 2;
083:
084: private CustomEditor customEditor;
085: private JRadioButton radioButton;
086: private int dependence;
087: private String comment;
088: private String defaultValue;
089: private boolean useTextArea;
090: private TypeID parentTypeID;
091: private String label;
092:
093: /**
094: * Creates instance of PropertyEditorString.
095: *
096: * @param String comment to be displayed underneath of text area in custom
097: * property editor. Can be null.
098: * @param int dependence of particular DesignComponent type. Possible values
099: * are DEPENDENCE_NONE, DEPENDENCE_TEXT_BOX, DEPENDENCE_TEXT_FIELD. This value
100: * will affect for that components after property value will be changed. For
101: * example is given text length is more than TextBoxCD.PROP_MAX_SIZE then
102: * this property will be automatically increased to be equal of text length.
103: */
104: private PropertyEditorString(String comment, int dependence,
105: boolean useTextArea, String label, TypeID parentTypeID) {
106: super (NbBundle.getMessage(PropertyEditorString.class,
107: "LBL_STRING_STR")); // NOI18N
108: this .comment = comment;
109: this .dependence = dependence;
110: this .useTextArea = useTextArea;
111: this .label = label;
112: this .parentTypeID = parentTypeID;
113: initComponents();
114:
115: initElements(Collections
116: .<PropertyEditorElement> singleton(this ));
117: }
118:
119: /**
120: * Creates instance of PropertyEditorString.
121: *
122: * @param String comment to be displayed underneath of text area in custom
123: * property editor. Can be null.
124: * @param int dependence of particular DesignComponent type. Possible values
125: * are DEPENDENCE_NONE, DEPENDENCE_TEXT_BOX, DEPENDENCE_TEXT_FIELD. This value
126: * will affect for that components after property value will be changed. For
127: * example is given text length is more than TextBoxCD.PROP_MAX_SIZE then
128: * this property will be automatically increased to be equal of text length.
129: * @param String default value of the property editor, could be different from default
130: * value specified in the component descriptor
131: */
132: private PropertyEditorString(String comment, int dependence,
133: String defaultValue, String label) {
134: this (comment, dependence, true, label, null);
135: this .defaultValue = defaultValue;
136: }
137:
138: /**
139: * Creates instance of PropertyEditorString without dependences.
140: */
141: public static final PropertyEditorString createInstance(String label) {
142: return new PropertyEditorString(null, DEPENDENCE_NONE, true,
143: label, null);
144: }
145:
146: /**
147: * Creates instance of PropertyEditorString with particular dependences.
148: * @param int dependence
149: * @see PropertyEditorString(String comment, int dependence)
150: */
151: public static final PropertyEditorString createInstance(
152: int dependence, String label) {
153: return new PropertyEditorString(null, dependence, true, label,
154: null);
155: }
156:
157: /**
158: * Creates instance of PropertyEditorString with particular dependences and NOT editable for given parent TypeID.
159: * @param int dependence
160: * @param parentTypeID parentComponent TypeID
161: * @see PropertyEditorString(String comment, int dependence)
162: */
163: public static final PropertyEditorString createInstance(
164: String label, TypeID parentTypeID) {
165: return new PropertyEditorString(null, DEPENDENCE_NONE, true,
166: label, parentTypeID);
167: }
168:
169: /**
170: * Creates instance of PropertyEditorString using JTExtField.
171: */
172: public static final PropertyEditorString createTextFieldInstance(
173: String label) {
174: return new PropertyEditorString(null, DEPENDENCE_NONE, false,
175: label, null);
176: }
177:
178: /**
179: * Creates instance of PropertyEditorString without dependences with default value.
180: */
181: public static final PropertyEditorString createInstanceWithDefaultValue(
182: String defaultValue, String label) {
183: return new PropertyEditorString(null, DEPENDENCE_NONE,
184: defaultValue, label);
185: }
186:
187: /**
188: * Creates instance of PropertyEditorString without dependences with default value.
189: */
190: public static final PropertyEditorString createInstanceWithComment(
191: String comment, String label) {
192: return new PropertyEditorString(comment, DEPENDENCE_NONE, null,
193: label);
194: }
195:
196: private void initComponents() {
197: radioButton = new JRadioButton();
198: Mnemonics.setLocalizedText(radioButton, label);
199: customEditor = new CustomEditor(comment);
200: }
201:
202: @Override
203: public Object getDefaultValue() {
204: if (defaultValue == null) {
205: return super .getDefaultValue();
206: }
207: return MidpTypes.createStringValue(defaultValue);
208: }
209:
210: /*
211: * Custom editor
212: */
213: public JComponent getCustomEditorComponent() {
214: return customEditor.getComponent();
215: }
216:
217: /*
218: * Radio button
219: */
220: public JRadioButton getRadioButton() {
221: return radioButton;
222: }
223:
224: /*
225: * This element should be selected by default
226: */
227: public boolean isInitiallySelected() {
228: return true;
229: }
230:
231: /*
232: * This element should be vertically resizable
233: */
234: public boolean isVerticallyResizable() {
235: return useTextArea;
236: }
237:
238: /*
239: * Returns text from PropertyValue to be displayed in the inplace editor
240: */
241: @Override
242: public String getAsText() {
243: String super Text = super .getAsText();
244: if (super Text != null) {
245: return super Text;
246: }
247:
248: PropertyValue value = (PropertyValue) super .getValue();
249: return (String) value.getPrimitiveValue();
250: }
251:
252: /*
253: * Sets PropertyValue according to given text. This method invoked when user
254: * sets new value in the inplace editor.
255: */
256: public void setTextForPropertyValue(String text) {
257: saveValue(text);
258: }
259:
260: /*
261: * This method used when PropertyEditorUserCode has more than one element
262: * incapsulated. In that case particular element returns text to be saved
263: * to PropertyValue.
264: */
265: public String getTextForPropertyValue() {
266: return null;
267: }
268:
269: @Override
270: public boolean canWrite() {
271: if (!isWriteableByParentType()) {
272: return false;
273: }
274:
275: return super .canWrite();
276: }
277:
278: @Override
279: public boolean supportsCustomEditor() {
280: if (!isWriteableByParentType()) {
281: return false;
282: }
283:
284: return super .supportsCustomEditor();
285: }
286:
287: /*
288: * This method updates state of custom property editor.
289: */
290: public void updateState(PropertyValue value) {
291: if (isCurrentValueANull() || value == null) {
292: customEditor.setText(null);
293: } else {
294: customEditor.setText((String) value.getPrimitiveValue());
295: }
296: if (!isCurrentValueAUserCodeType()) {
297: radioButton.setSelected(true);
298: radioButton.requestFocus();
299: }
300: }
301:
302: private void saveValue(String text) {
303: super .setValue(MidpTypes.createStringValue(text));
304: if (component == null || component.get() == null) {
305: return;
306: }
307:
308: final DesignComponent _component = component.get();
309: final int length = text.length();
310: switch (dependence) {
311: case DEPENDENCE_TEXT_BOX:
312: _component.getDocument().getTransactionManager()
313: .writeAccess(new Runnable() {
314:
315: public void run() {
316: PropertyValue value = _component
317: .readProperty(TextBoxCD.PROP_MAX_SIZE);
318: if (MidpTypes.getInteger(value) < length) {
319: _component
320: .writeProperty(
321: TextBoxCD.PROP_MAX_SIZE,
322: MidpTypes
323: .createIntegerValue(length));
324: }
325: }
326: });
327: break;
328: case DEPENDENCE_TEXT_FIELD:
329: _component.getDocument().getTransactionManager()
330: .writeAccess(new Runnable() {
331:
332: public void run() {
333: PropertyValue value = _component
334: .readProperty(TextFieldCD.PROP_MAX_SIZE);
335: if (MidpTypes.getInteger(value) < length) {
336: _component
337: .writeProperty(
338: TextFieldCD.PROP_MAX_SIZE,
339: MidpTypes
340: .createIntegerValue(length));
341: }
342: }
343: });
344: }
345: }
346:
347: /*
348: * Saves PropertyValue
349: */
350: @Override
351: public void customEditorOKButtonPressed() {
352: super .customEditorOKButtonPressed();
353: if (radioButton.isSelected()) {
354: saveValue(customEditor.getText());
355: }
356: }
357:
358: private boolean isWriteableByParentType() {
359: if (component == null || component.get() == null) {
360: return false;
361: }
362:
363: if (parentTypeID != null) {
364: final DesignComponent _component = component.get();
365: final DesignComponent[] parent = new DesignComponent[1];
366: _component.getDocument().getTransactionManager()
367: .readAccess(new Runnable() {
368:
369: public void run() {
370: parent[0] = _component.getParentComponent();
371: }
372: });
373:
374: if (parent[0] != null
375: && parentTypeID.equals(parent[0].getType())) {
376: return false;
377: }
378: }
379: return true;
380: }
381:
382: /*
383: * Custom property editor. JEditorPane plus possible JLabels with comments.
384: */
385: private class CustomEditor implements DocumentListener {
386:
387: private JPanel panel;
388: private JTextComponent editorPane;
389: private String comment;
390:
391: public CustomEditor(String comment) {
392: this .comment = comment;
393: initComponents();
394: }
395:
396: private void initComponents() {
397: panel = new JPanel(new GridBagLayout());
398:
399: JComponent textComponent;
400: if (useTextArea) {
401: editorPane = new JTextArea();
402: textComponent = new JScrollPane();
403: ((JScrollPane) textComponent)
404: .setViewportView(editorPane);
405: ((JScrollPane) textComponent)
406: .setPreferredSize(new Dimension(400, 100));
407: } else {
408: textComponent = editorPane = new JTextField();
409: }
410: editorPane.getDocument().addDocumentListener(this );
411:
412: GridBagConstraints gridBagConstraints = new GridBagConstraints();
413: gridBagConstraints.gridx = 0;
414: gridBagConstraints.gridy = 0;
415: gridBagConstraints.fill = GridBagConstraints.BOTH;
416: gridBagConstraints.anchor = GridBagConstraints.NORTHWEST;
417: gridBagConstraints.weightx = 1.0;
418: gridBagConstraints.weighty = 1.0;
419: panel.add(textComponent, gridBagConstraints);
420:
421: if (comment != null) {
422: JLabel label = new JLabel(comment);
423: gridBagConstraints = new GridBagConstraints();
424: gridBagConstraints.gridx = 0;
425: gridBagConstraints.gridy = 1;
426: gridBagConstraints.fill = GridBagConstraints.BOTH;
427: gridBagConstraints.ipadx = 1;
428: gridBagConstraints.ipady = 10;
429: gridBagConstraints.anchor = GridBagConstraints.WEST;
430: gridBagConstraints.weightx = 1.0;
431: gridBagConstraints.weighty = 1.0;
432: panel.add(label, gridBagConstraints);
433: }
434: }
435:
436: public JComponent getComponent() {
437: return panel;
438: }
439:
440: public void setText(String text) {
441: editorPane.setText(text);
442: }
443:
444: public String getText() {
445: return editorPane.getText();
446: }
447:
448: public void insertUpdate(DocumentEvent e) {
449: if (editorPane.hasFocus()) {
450: radioButton.setSelected(true);
451: }
452: }
453:
454: public void removeUpdate(DocumentEvent e) {
455: if (editorPane.hasFocus()) {
456: radioButton.setSelected(true);
457: }
458: }
459:
460: public void changedUpdate(DocumentEvent e) {
461: }
462: }
463: }
|