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.editors;
043:
044: import java.awt.BorderLayout;
045: import java.awt.Component;
046: import java.awt.Graphics;
047: import java.awt.Rectangle;
048: import java.lang.reflect.Modifier;
049: import java.util.StringTokenizer;
050: import javax.swing.JPanel;
051: import org.openide.ErrorManager;
052: import org.openide.explorer.propertysheet.ExPropertyEditor;
053: import org.openide.explorer.propertysheet.PropertyEnv;
054: import org.openide.util.NbBundle;
055:
056: /** Property editors for java modifiers.
057: *
058: * @author Petr Hamernik
059: */
060: public class ModifierEditor extends JPanel implements ExPropertyEditor {
061:
062: public static final String PROP_MODIFIERS = "modifiers"; // NOI18N
063: /**
064: * attribute name for the feature descriptor of the property environment
065: * @see #ACCESS_MODIFIERS_CUSTOM_EDITOR
066: * @see #OTHERS_MODIFIERS_CUSTOM_EDITOR
067: */
068: public static final String CUSTOM_EDITOR_TYPE = "customEditorType"; // NOI18N
069: /** if it is set as feature descriptor's attribute value in the environment then the getCustomComponent returns
070: * the combo box for access modifiers
071: */
072: public static final Integer ACCESS_MODIFIERS_CUSTOM_EDITOR = new Integer(
073: 0);
074: /** if it is set as feature descriptor's attribute value in the environment then the getCustomComponent returns
075: * the panel containing other modifiers than the access modifiers.
076: */
077: public static final Integer OTHERS_MODIFIERS_CUSTOM_EDITOR = new Integer(
078: 1);
079: /** if it is set as feature descriptor's attribute value in the environment then the getCustomComponent returns
080: * the panel containing full range of modifiers
081: */
082: public static final Integer FULL_CUSTOM_EDITOR = new Integer(2);
083:
084: /** Instance of custom property editor - visual panel. */
085: private ModifierPanel panel;
086:
087: /** Current mask */
088: private int mask;
089:
090: /** Current value */
091: private int modifier;
092:
093: private PropertyEnv env;
094:
095: /**
096: * @see #getType
097: */
098: private Object type;
099:
100: /** Creates new modifiers editor with full mask.
101: */
102: public ModifierEditor() {
103: this (ModifierPanel.EDITABLE_MASK);
104: }
105:
106: /** Creates new modifiers editor.
107: * @param mask The mask of modifier values which should be possible to change.
108: */
109: public ModifierEditor(int mask) {
110: modifier = 0;
111: setMask(mask & ModifierPanel.EDITABLE_MASK);
112: }
113:
114: private Component customComponent;
115:
116: @Override
117: public void addNotify() {
118: setLayout(new BorderLayout());
119: panel = new ModifierPanel(this );
120: Object type = getType();
121: if (ACCESS_MODIFIERS_CUSTOM_EDITOR == type) {
122: customComponent = panel.getAccessComponent();
123: } else if (OTHERS_MODIFIERS_CUSTOM_EDITOR == type) {
124: customComponent = panel.getModifiersComponent();
125: } else {
126: customComponent = panel.getCompactComponent();
127: }
128: add(customComponent, BorderLayout.CENTER);
129:
130: super .addNotify();
131: }
132:
133: @Override
134: public void removeNotify() {
135: super .removeNotify();
136: if (panel != null) {
137: remove(customComponent);
138: panel = null;
139: }
140: }
141:
142: /** Getter for property mask.
143: *@return Value of property mask.
144: */
145: int getMask() {
146: return mask;
147: }
148:
149: /** Set the mask of editable modifiers.
150: * @param mask new value of the mask.
151: */
152: public void setMask(int mask) {
153: if (this .mask != mask) {
154: int oldMask = this .mask;
155: this .mask = mask & ModifierPanel.EDITABLE_MASK;
156: firePropertyChange(ModifierPanel.PROP_MASK, new Integer(
157: oldMask), new Integer(mask));
158: setModifier(modifier & mask);
159: }
160: }
161:
162: /** Getter for property modifier.
163: *@return Value of property modifier.
164: */
165: int getModifier() {
166: return modifier;
167: }
168:
169: /** Setter for property modifier.
170: *@param modifier New value of property modifier.
171: */
172: void setModifier(int modifier) {
173: if (this .modifier != modifier) {
174: int oldModifier = this .modifier;
175: this .modifier = modifier;
176: // for our panel
177: firePropertyChange(ModifierPanel.PROP_MODIFIER,
178: new Integer(oldModifier), new Integer(modifier));
179: // for the outside world
180: firePropertyChange(PROP_MODIFIERS,
181: new Integer(oldModifier), new Integer(modifier));
182: }
183: }
184:
185: /**
186: * @return type of the editor
187: * @see #ACCESS_MODIFIERS_CUSTOM_EDITOR
188: * @see #OTHERS_MODIFIERS_CUSTOM_EDITOR
189: * @see #FULL_CUSTOM_EDITOR
190: */
191: Object getType() {
192: return type;
193: }
194:
195: /** Set new value */
196: public void setValue(Object object) throws IllegalArgumentException {
197: if (object == null) {
198: setModifier(0);
199: return;
200: }
201: if (object instanceof Integer) {
202: setModifier(((Integer) object).intValue());
203: } else {
204: throw new IllegalArgumentException();
205: }
206: }
207:
208: /** @return the java source code representation
209: * of the current value.
210: */
211: public String getJavaInitializationString() {
212: return new Integer(getModifier()).toString();
213: }
214:
215: /** Get the value */
216: public Object getValue() {
217: return new Integer(getModifier());
218: }
219:
220: /** @return <CODE>false</CODE> */
221: public boolean isPaintable() {
222: return false;
223: }
224:
225: /** Does nothing. */
226: public void paintValue(Graphics g, Rectangle rectangle) {
227: }
228:
229: /** @return textual representition of current value of the modifiers. */
230: public String getAsText() {
231: return Modifier.toString(getModifier());
232: }
233:
234: /** Parse the text and sets the modifier editor value */
235: public void setAsText(String string)
236: throws IllegalArgumentException {
237: int newValue = 0;
238: int oldValue = modifier;
239:
240: StringTokenizer tukac = new StringTokenizer(string, ", ", false); // NOI18N
241: while (tukac.hasMoreTokens()) {
242: String token = tukac.nextToken();
243: boolean known = false;
244: for (int i = 0; i < ModifierPanel.MODIFIER_COUNT; i++) {
245: if ((ModifierPanel.MODIFIER_VALUES[i] & mask) != 0) {
246: if (token.equals(ModifierPanel.MODIFIER_NAMES[i])) {
247: if (((ModifierPanel.MODIFIER_VALUES[i] == Modifier.FINAL) && ((newValue & Modifier.ABSTRACT) != 0))
248: || ((ModifierPanel.MODIFIER_VALUES[i] == Modifier.ABSTRACT) && ((newValue & Modifier.FINAL) != 0)))
249: break;
250: newValue |= ModifierPanel.MODIFIER_VALUES[i];
251: known = true;
252: break;
253: }
254: }
255: }
256: if ((newValue & ModifierPanel.ACCESS_MASK) == 0) {
257: for (int i = 1; i <= 3; i++) {
258: if ((ModifierPanel.ACCESS_VALUES[i] & mask) != 0) {
259: if (token.equals(ModifierPanel.ACCESS_NAMES[i])) {
260: newValue |= ModifierPanel.ACCESS_VALUES[i];
261: known = true;
262: break;
263: }
264: }
265: }
266: }
267: if (!known) {
268: IllegalArgumentException x = new IllegalArgumentException(
269: "Invalid modifier: " + token); // NOI18N
270: String message = java.text.MessageFormat.format(
271: getString("MSG_IllegalModifierString"), // NOI18N
272: new Object[] { token });
273: ErrorManager.getDefault().annotate(x,
274: ErrorManager.USER, null, message, null, null);
275: throw x;
276: }
277: }
278: if (oldValue != newValue) {
279: modifier = newValue;
280: firePropertyChange(ModifierPanel.PROP_MODIFIER,
281: new Integer(oldValue), new Integer(modifier));
282: }
283: }
284:
285: /** @return <CODE>null</CODE> */
286: public String[] getTags() {
287: return null;
288: }
289:
290: /** @return <CODE>this</CODE> */
291: public Component getCustomEditor() {
292: return this ;
293: }
294:
295: /** @return <CODE>true</CODE> */
296: public boolean supportsCustomEditor() {
297: return true;
298: }
299:
300: /** Get the customized property value.
301: * @return the property value
302: * @exception IllegalStateException when the custom property editor does not contain a valid property value
303: * (and thus it should not be set)
304: */
305: public Object getPropertyValue() throws IllegalStateException {
306: return getValue();
307: }
308:
309: /**
310: * This method is called by the IDE to pass
311: * the environment to the property editor.
312: */
313: public void attachEnv(PropertyEnv env) {
314: this .env = env;
315: type = env.getFeatureDescriptor().getValue(CUSTOM_EDITOR_TYPE);
316: if (type == null) {
317: type = FULL_CUSTOM_EDITOR;
318: } else if (ACCESS_MODIFIERS_CUSTOM_EDITOR.equals(type)) {
319: type = ACCESS_MODIFIERS_CUSTOM_EDITOR;
320: } else if (OTHERS_MODIFIERS_CUSTOM_EDITOR.equals(type)) {
321: type = OTHERS_MODIFIERS_CUSTOM_EDITOR;
322: } else {
323: type = FULL_CUSTOM_EDITOR;
324: }
325:
326: }
327:
328: private static String getString(String key) {
329: return NbBundle.getMessage(ModifierEditor.class, key);
330: }
331: }
|