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: package org.netbeans.modules.vmd.midp.propertyeditors;
042:
043: import java.awt.BorderLayout;
044: import java.awt.event.ActionEvent;
045: import java.awt.event.ActionListener;
046: import java.awt.event.FocusEvent;
047: import java.awt.event.FocusListener;
048: import java.util.Collections;
049: import java.util.regex.Pattern;
050: import javax.swing.JCheckBox;
051: import javax.swing.JComponent;
052: import javax.swing.JPanel;
053: import javax.swing.JRadioButton;
054: import javax.swing.JTextField;
055: import javax.swing.event.DocumentEvent;
056: import javax.swing.event.DocumentListener;
057: import org.netbeans.modules.vmd.api.model.DesignComponent;
058: import org.netbeans.modules.vmd.api.model.PropertyValue;
059: import org.netbeans.modules.vmd.api.model.TypeID;
060: import org.netbeans.modules.vmd.midp.components.MidpTypes;
061: import org.netbeans.modules.vmd.midp.components.items.ItemCD;
062: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorElement;
063: import org.netbeans.modules.vmd.midp.propertyeditors.api.usercode.PropertyEditorUserCode;
064: import org.openide.awt.Mnemonics;
065: import org.openide.util.NbBundle;
066:
067: /**
068: *
069: * @author Anton Chechel
070: */
071: public class PropertyEditorPreferredSize extends PropertyEditorUserCode
072: implements PropertyEditorElement {
073:
074: private static final String UNLOCKED_TEXT = NbBundle.getMessage(
075: PropertyEditorPreferredSize.class,
076: "LBL_PREF_SIZE_UNLOCKED_TXT"); // NOI18N
077: private static final String UNLOCKED_NUM_TEXT = String
078: .valueOf(ItemCD.UNLOCKED_VALUE.getPrimitiveValue());
079: private CustomEditor customEditor;
080: private JRadioButton radioButton;
081: private String label;
082: private TypeID parentTypeID;
083:
084: private PropertyEditorPreferredSize(String label, String ucLabel,
085: TypeID parentTypeID) {
086: super (ucLabel);
087: this .label = label;
088: this .parentTypeID = parentTypeID;
089: initComponents();
090:
091: initElements(Collections
092: .<PropertyEditorElement> singleton(this ));
093: }
094:
095: public static PropertyEditorPreferredSize createInstance(
096: String label, String ucLabel) {
097: return new PropertyEditorPreferredSize(label, ucLabel, null);
098: }
099:
100: public static PropertyEditorPreferredSize createInstance(
101: String label, String ucLabel, TypeID parentTypeID) {
102: return new PropertyEditorPreferredSize(label, ucLabel,
103: parentTypeID);
104: }
105:
106: private void initComponents() {
107: radioButton = new JRadioButton();
108: Mnemonics.setLocalizedText(radioButton, label);
109: customEditor = new CustomEditor();
110: }
111:
112: public JComponent getCustomEditorComponent() {
113: return customEditor;
114: }
115:
116: public JRadioButton getRadioButton() {
117: return radioButton;
118: }
119:
120: public boolean isInitiallySelected() {
121: return true;
122: }
123:
124: public boolean isVerticallyResizable() {
125: return false;
126: }
127:
128: @Override
129: public String getAsText() {
130: String super Text = super .getAsText();
131: if (super Text != null) {
132: return super Text;
133: }
134:
135: Object valueValue = ((PropertyValue) super .getValue())
136: .getPrimitiveValue();
137: Object unlockedValueValue = ItemCD.UNLOCKED_VALUE
138: .getPrimitiveValue();
139: if (unlockedValueValue.equals(valueValue)) {
140: return UNLOCKED_TEXT;
141: }
142: return String.valueOf(valueValue);
143: }
144:
145: public void setTextForPropertyValue(String text) {
146: saveValue(text);
147: }
148:
149: public String getTextForPropertyValue() {
150: return null;
151: }
152:
153: public void updateState(PropertyValue value) {
154: if (isCurrentValueANull() || value == null) {
155: customEditor.unsetUnlocked(true);
156: } else if (ItemCD.UNLOCKED_VALUE.getPrimitiveValue().equals(
157: value.getPrimitiveValue())) {
158: customEditor.setUnlocked(true);
159: } else {
160: customEditor.unsetUnlocked(true);
161: customEditor.setText(String.valueOf(value
162: .getPrimitiveValue()));
163: }
164: radioButton.setSelected(!isCurrentValueAUserCodeType());
165: }
166:
167: private void saveValue(String text) {
168: if (text.length() > 0) {
169: if (UNLOCKED_TEXT.equals(text)
170: || UNLOCKED_NUM_TEXT.equals(text)) {
171: super .setValue(ItemCD.UNLOCKED_VALUE);
172: return;
173: }
174:
175: int intValue = 0;
176: try {
177: text = text.replaceAll("[^0-9\\-]+", ""); // NOI18N
178: intValue = Integer.parseInt(text) <= 0 ? 0 : Integer
179: .parseInt(text);
180: } catch (NumberFormatException e) {
181: }
182:
183: super .setValue(MidpTypes.createIntegerValue(intValue));
184: }
185: }
186:
187: @Override
188: public void customEditorOKButtonPressed() {
189: super .customEditorOKButtonPressed();
190: if (radioButton.isSelected()) {
191: saveValue(customEditor.getText());
192: }
193: }
194:
195: @Override
196: public Boolean canEditAsText() {
197: if (!isCurrentValueAUserCodeType()) {
198: PropertyValue value = (PropertyValue) super .getValue();
199: if (value == null) {
200: return false;
201: }
202: Object foreverValueValue = ItemCD.UNLOCKED_VALUE
203: .getPrimitiveValue();
204: return !foreverValueValue.equals(value.getPrimitiveValue());
205: }
206: return false;
207: }
208:
209: @Override
210: public boolean canWrite() {
211: if (!isWriteableByParentType()) {
212: return false;
213: }
214:
215: return super .canWrite();
216: }
217:
218: @Override
219: public boolean supportsCustomEditor() {
220: if (!isWriteableByParentType()) {
221: return false;
222: }
223:
224: return super .supportsCustomEditor();
225: }
226:
227: private boolean isWriteableByParentType() {
228: if (component == null || component.get() == null) {
229: return false;
230: }
231:
232: if (parentTypeID != null) {
233: final DesignComponent _component = component.get();
234: final DesignComponent[] parent = new DesignComponent[1];
235: _component.getDocument().getTransactionManager()
236: .readAccess(new Runnable() {
237:
238: public void run() {
239: parent[0] = _component.getParentComponent();
240: }
241: });
242:
243: if (parent[0] != null
244: && parentTypeID.equals(parent[0].getType())) {
245: return false;
246: }
247: }
248: return true;
249: }
250:
251: private class CustomEditor extends JPanel implements
252: ActionListener, DocumentListener, FocusListener {
253:
254: private JTextField textField;
255: private JCheckBox unlockedCheckBox;
256:
257: public CustomEditor() {
258: radioButton.addFocusListener(this );
259: initComponents();
260: }
261:
262: private void initComponents() {
263: setLayout(new BorderLayout());
264:
265: unlockedCheckBox = new JCheckBox();
266: unlockedCheckBox.addActionListener(this );
267: unlockedCheckBox.addFocusListener(this );
268: Mnemonics.setLocalizedText(unlockedCheckBox, NbBundle
269: .getMessage(PropertyEditorPreferredSize.class,
270: "LBL_PREF_SIZE_UNLOCKED")); // NOI18N
271: add(unlockedCheckBox, BorderLayout.NORTH);
272:
273: textField = new JTextField();
274: textField.getDocument().addDocumentListener(this );
275: textField.addFocusListener(this );
276: add(textField, BorderLayout.SOUTH);
277: }
278:
279: public void setText(String text) {
280: textField.setText(text);
281: }
282:
283: public String getText() {
284: return textField.getText();
285: }
286:
287: public void setUnlocked(boolean changeCheckBox) {
288: setText(UNLOCKED_NUM_TEXT);
289: textField.setEditable(false);
290: if (changeCheckBox) {
291: unlockedCheckBox.setSelected(true);
292: }
293: }
294:
295: public void unsetUnlocked(boolean changeCheckBox) {
296: setText(null);
297: textField.setEditable(true);
298: if (changeCheckBox) {
299: unlockedCheckBox.setSelected(false);
300: }
301: }
302:
303: public void actionPerformed(ActionEvent evt) {
304: if (unlockedCheckBox.isSelected()) {
305: setUnlocked(false);
306: } else {
307: unsetUnlocked(false);
308: }
309: }
310:
311: public void insertUpdate(DocumentEvent evt) {
312: if (textField.hasFocus()) {
313: radioButton.setSelected(true);
314: checkNumberStatus();
315: }
316: }
317:
318: public void removeUpdate(DocumentEvent evt) {
319: if (textField.hasFocus()) {
320: radioButton.setSelected(true);
321: checkNumberStatus();
322: }
323: }
324:
325: public void changedUpdate(DocumentEvent evt) {
326: }
327:
328: private void checkNumberStatus() {
329: if (!Pattern.matches("[\\d\\-]+", textField.getText())) { //NOI18N
330: displayWarning(PropertyEditorNumber.NON_DIGITS_TEXT);
331: } else {
332: clearErrorStatus();
333: }
334: try {
335: int number = Integer.valueOf(textField.getText());
336: if (number < 0 && !unlockedCheckBox.isSelected()) {
337: displayWarning(NbBundle.getMessage(
338: PropertyEditorPreferredSize.class,
339: "MSG_POSITIVE_CHARS")); //NOI18N
340: } else {
341: clearErrorStatus();
342: }
343: } catch (NumberFormatException ex) {
344: displayWarning(PropertyEditorNumber.NON_DIGITS_TEXT);
345: }
346:
347: }
348:
349: public void focusGained(FocusEvent e) {
350: if (e.getSource() == radioButton
351: || e.getSource() == textField
352: || e.getSource() == unlockedCheckBox) {
353: checkNumberStatus();
354: }
355: }
356:
357: public void focusLost(FocusEvent e) {
358: clearErrorStatus();
359: }
360: }
361: }
|