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.layoutsupport.delegates;
043:
044: import java.awt.*;
045: import java.beans.*;
046: import java.util.*;
047: import java.lang.reflect.Constructor;
048:
049: import org.openide.nodes.Node;
050: import org.openide.util.Utilities;
051:
052: import org.netbeans.lib.awtextra.AbsoluteLayout;
053: import org.netbeans.lib.awtextra.AbsoluteConstraints;
054:
055: import org.netbeans.modules.form.layoutsupport.*;
056: import org.netbeans.modules.form.codestructure.*;
057: import org.netbeans.modules.form.FormProperty;
058: import org.netbeans.modules.form.FormLoaderSettings;
059:
060: /**
061: * Support class for AbsoluteLayout - for absolute positioning and sizing of
062: * components using AbsoluteConstraints. This is an example of support for
063: * layout manager using component constraints as complex objects initialized
064: * by constructor with parameters mapped to properties. AbsoluteLayoutSupport
065: * is also the superclass of NullLayoutSupport and JLayeredPane support, so it
066: * is a bit more complicated than would be necessary for simple implementation.
067: *
068: * @author Tomas Pavek
069: */
070:
071: public class AbsoluteLayoutSupport extends AbstractLayoutSupport {
072:
073: /** The icon for AbsoluteLayout. */
074: private static String iconURL = "org/netbeans/modules/form/layoutsupport/resources/AbsoluteLayout.gif"; // NOI18N
075: /** The icon for AbsoluteLayout. */
076: private static String icon32URL = "org/netbeans/modules/form/layoutsupport/resources/AbsoluteLayout32.gif"; // NOI18N
077:
078: private static Constructor constrConstructor;
079:
080: private static FormLoaderSettings formSettings = FormLoaderSettings
081: .getInstance();
082:
083: /** Gets the supported layout manager class - AbsoluteLayout.
084: * @return the class supported by this delegate
085: */
086: public Class getSupportedClass() {
087: return AbsoluteLayout.class;
088: }
089:
090: /** Provides an icon to be used for the layout node in Component
091: * Inspector. Only 16x16 color icon is required.
092: * @param type is one of BeanInfo constants: ICON_COLOR_16x16,
093: * ICON_COLOR_32x32, ICON_MONO_16x16, ICON_MONO_32x32
094: * @return icon to be displayed for node in Component Inspector
095: */
096: @Override
097: public Image getIcon(int type) {
098: switch (type) {
099: case BeanInfo.ICON_COLOR_16x16:
100: case BeanInfo.ICON_MONO_16x16:
101: return Utilities.loadImage(iconURL);
102: default:
103: return Utilities.loadImage(icon32URL);
104: }
105: }
106:
107: /** This method is called when switching layout - giving an opportunity to
108: * convert the previous constrainst of components to constraints of the new
109: * layout (this layout). For AbsoluteLayout, we can simply create new
110: * constraints from positions and sizes of real components.
111: * @param previousConstraints [input] layout constraints of components in
112: * the previous layout
113: * @param currentConstraints [output] array of converted constraints for
114: * the new layout - to be filled
115: * @param components [input] real components in a real container having the
116: * previous layout
117: */
118: @Override
119: public void convertConstraints(
120: LayoutConstraints[] previousConstraints,
121: LayoutConstraints[] currentConstraints,
122: Component[] components) {
123: if (currentConstraints == null || components == null)
124: return;
125:
126: for (int i = 0; i < currentConstraints.length; i++)
127: if (currentConstraints[i] == null) {
128: Rectangle bounds = components[i].getBounds();
129: Dimension prefSize = components[i].getPreferredSize();
130: int x = bounds.x;
131: int y = bounds.y;
132: int w = computeConstraintSize(bounds.width, -1,
133: prefSize.width);
134: int h = computeConstraintSize(bounds.height, -1,
135: prefSize.height);
136:
137: currentConstraints[i] = new AbsoluteLayoutConstraints(
138: x, y, w, h);
139: }
140: }
141:
142: /** This method calculates layout constraints for a component dragged
143: * over a container (or just for mouse cursor being moved over container,
144: * without any component).
145: * @param container instance of a real container over/in which the
146: * component is dragged
147: * @param containerDelegate effective container delegate of the container
148: * (for layout managers we always use container delegate instead of
149: * the container)
150: * @param component the real component being dragged, can be null
151: * @param index position (index) of the component in its container;
152: * -1 if there's no dragged component
153: * @param posInCont position of mouse in the container delegate
154: * @param posInComp position of mouse in the dragged component; null if
155: * there's no dragged component
156: * @return new LayoutConstraints object corresponding to the position of
157: * the component in the container
158: */
159: @Override
160: public LayoutConstraints getNewConstraints(Container container,
161: Container containerDelegate, Component component,
162: int index, Point posInCont, Point posInComp) {
163: int x = posInCont.x;
164: int y = posInCont.y;
165: int w = -1;
166: int h = -1;
167:
168: LayoutConstraints constr = getConstraints(index);
169:
170: if (component != null) {
171: int currentW;
172: int currentH;
173:
174: if (constr instanceof AbsoluteLayoutConstraints) {
175: currentW = ((AbsoluteLayoutConstraints) constr).w;
176: currentH = ((AbsoluteLayoutConstraints) constr).h;
177: } else {
178: currentW = -1;
179: currentH = -1;
180: }
181:
182: Dimension size = component.getSize();
183: Dimension prefSize = component.getPreferredSize();
184:
185: w = computeConstraintSize(size.width, currentW,
186: prefSize.width);
187: h = computeConstraintSize(size.height, currentH,
188: prefSize.height);
189: }
190:
191: if (posInComp != null) {
192: x -= posInComp.x;
193: y -= posInComp.y;
194: }
195:
196: if (formSettings.getApplyGridToPosition()) {
197: x = computeGridSize(x, formSettings.getGridX());
198: y = computeGridSize(y, formSettings.getGridY());
199: }
200:
201: assistantParams = new Object[] { Integer.valueOf(x),
202: Integer.valueOf(y) };
203: return createNewConstraints(constr, x, y, w, h);
204: }
205:
206: private Object[] assistantParams;
207:
208: @Override
209: public String getAssistantContext() {
210: return "absoluteLayout"; // NOI18N
211: }
212:
213: @Override
214: public Object[] getAssistantParams() {
215: return assistantParams;
216: }
217:
218: /** This method paints a dragging feedback for a component dragged over
219: * a container (or just for mouse cursor being moved over container,
220: * without any component). For AbsoluteLayout, it simply paints a rectangle
221: * corresponding to the component position and size.
222: * @param container instance of a real container over/in which the
223: * component is dragged
224: * @param containerDelegate effective container delegate of the container
225: * (for layout managers we always use container delegate instead of
226: * the container)
227: * @param component the real component being dragged, can be null
228: * @param newConstraints component layout constraints to be presented
229: * @param newIndex component's index position to be presented; not used
230: * for AbsoluteLayout
231: * @param g Graphics object for painting (with color and line style set)
232: * @return whether any feedback was painted (true in this case)
233: */
234: @Override
235: public boolean paintDragFeedback(Container container,
236: Container containerDelegate, Component component,
237: LayoutConstraints newConstraints, int newIndex, Graphics g) {
238: Rectangle r = ((AbsoluteLayoutConstraints) newConstraints)
239: .getBounds();
240: int w = r.width;
241: int h = r.height;
242:
243: if (w == -1 || h == -1) {
244: // JInternalFrame.getPreferredSize() behaves suspiciously
245: Dimension pref = component instanceof javax.swing.JInternalFrame ? component
246: .getSize()
247: : component.getPreferredSize();
248: if (w == -1)
249: w = pref.width;
250: if (h == -1)
251: h = pref.height;
252: }
253:
254: if (w < 4)
255: w = 4;
256: if (h < 4)
257: h = 4;
258:
259: g.drawRect(r.x, r.y, w, h);
260:
261: return true;
262: }
263:
264: /** Provides resizing options for given component. It can combine the
265: * bit-flag constants RESIZE_UP, RESIZE_DOWN, RESIZE_LEFT, RESIZE_RIGHT.
266: * @param container instance of a real container in which the
267: * component is to be resized
268: * @param containerDelegate effective container delegate of the container
269: * (e.g. like content pane of JFrame)
270: * @param component real component to be resized
271: * @param index position of the component in its container
272: * @return resizing options for the component; 0 if no resizing is possible
273: */
274: @Override
275: public int getResizableDirections(Container container,
276: Container containerDelegate, Component component, int index) {
277: return RESIZE_UP | RESIZE_DOWN | RESIZE_LEFT | RESIZE_RIGHT;
278: }
279:
280: /** This method should calculate layout constraints for a component being
281: * resized.
282: * @param container instance of a real container in which the
283: * component is resized
284: * @param containerDelegate effective container delegate of the container
285: * (e.g. like content pane of JFrame)
286: * @param component real component being resized
287: * @param index position of the component in its container
288: * @param sizeChanges Insets object with size differences
289: * @param posInCont position of mouse in the container delegate
290: * @return component layout constraints for resized component; null if
291: * resizing is not possible or not implemented
292: */
293: @Override
294: public LayoutConstraints getResizedConstraints(Container container,
295: Container containerDelegate, Component component,
296: int index, Rectangle originalBounds, Insets sizeChanges,
297: Point posInCont) {
298: int x, y, w, h;
299: x = originalBounds.x;
300: y = originalBounds.y;
301: w = originalBounds.width;
302: h = originalBounds.height;
303:
304: Dimension prefSize = component.getPreferredSize();
305: int currentW, currentH;
306:
307: LayoutConstraints constr = getConstraints(index);
308: if (constr instanceof AbsoluteLayoutConstraints) {
309: Rectangle r = ((AbsoluteLayoutConstraints) constr)
310: .getBounds();
311: currentW = r.width;
312: currentH = r.height;
313: } else {
314: currentW = computeConstraintSize(w, -1, prefSize.width);
315: currentH = computeConstraintSize(h, -1, prefSize.height);
316: }
317:
318: int x2 = x + w;
319: int y2 = y + h;
320:
321: if (sizeChanges.left + sizeChanges.right == 0)
322: w = currentW; // no change
323: else { // compute resized width and x coordinate
324: w += sizeChanges.left + sizeChanges.right;
325: w = w <= 0 ? -1 : computeConstraintSize(w, currentW,
326: prefSize.width);
327:
328: if (w > 0) {
329: if (formSettings.getApplyGridToSize()) {
330: int gridW = computeGridSize(w, formSettings
331: .getGridX());
332: x -= sizeChanges.left + (gridW - w)
333: * sizeChanges.left
334: / (sizeChanges.left + sizeChanges.right);
335: w = gridW;
336: }
337: } else if (sizeChanges.left != 0)
338: x = x2 - prefSize.width;
339: }
340:
341: if (sizeChanges.top + sizeChanges.bottom == 0)
342: h = currentH; // no change
343: else { // compute resized height and y coordinate
344: h += sizeChanges.top + sizeChanges.bottom;
345: h = h <= 0 ? -1 : computeConstraintSize(h, currentH,
346: prefSize.height);
347:
348: if (h > 0) {
349: if (formSettings.getApplyGridToSize()) {
350: int gridH = computeGridSize(h, formSettings
351: .getGridY());
352: y -= sizeChanges.top + (gridH - h)
353: * sizeChanges.top
354: / (sizeChanges.top + sizeChanges.bottom);
355: h = gridH;
356: }
357: } else if (sizeChanges.top != 0)
358: y = y2 - prefSize.height;
359: }
360:
361: return createNewConstraints(constr, x, y, w, h);
362: }
363:
364: // -------
365:
366: /** This method is called from readComponentCode method to read layout
367: * constraints of a component from code (AbsoluteConstraints in this case).
368: * @param constrExp CodeExpression object of the constraints (taken from
369: * add method in the code)
370: * @param constrCode CodeGroup to be filled with the relevant constraints
371: * initialization code; not needed here because AbsoluteConstraints
372: * object is represented only by a single code expression (based on
373: * constructor) and no statements
374: * @param compExp CodeExpression of the component for which the constraints
375: * are read (not needed here)
376: * @return LayoutConstraints based on information read form code
377: */
378: @Override
379: protected LayoutConstraints readConstraintsCode(
380: CodeExpression constrExp, CodeGroup constrCode,
381: CodeExpression compExp) {
382: AbsoluteLayoutConstraints constr = new AbsoluteLayoutConstraints(
383: 0, 0, -1, -1);
384:
385: CodeExpression[] params = constrExp.getOrigin()
386: .getCreationParameters();
387: if (params.length == 4) {
388: // reading is done in AbsoluteLayoutConstraints
389: constr.readPropertyExpressions(params, 0);
390: }
391:
392: return constr;
393: }
394:
395: /** Called from createComponentCode method, creates code for a component
396: * layout constraints (opposite to readConstraintsCode).
397: * @param constrCode CodeGroup to be filled with constraints code; not
398: * needed here because AbsoluteConstraints object is represented
399: * only by a single constructor code expression and no statements
400: * @param constr layout constraints metaobject representing the constraints
401: * @param compExp CodeExpression object representing the component; not
402: * needed here
403: * @return created CodeExpression representing the layout constraints
404: */
405: @Override
406: protected CodeExpression createConstraintsCode(
407: CodeGroup constrCode, LayoutConstraints constr,
408: CodeExpression compExp, int index) {
409: if (!(constr instanceof AbsoluteLayoutConstraints))
410: return null;
411:
412: AbsoluteLayoutConstraints absConstr = (AbsoluteLayoutConstraints) constr;
413: // code expressions for constructor parameters are created in
414: // AbsoluteLayoutConstraints
415: CodeExpression[] params = absConstr.createPropertyExpressions(
416: getCodeStructure(), 0);
417: return getCodeStructure().createExpression(
418: getConstraintsConstructor(), params);
419: }
420:
421: /** This method is called to get a default component layout constraints
422: * metaobject in case it is not provided (e.g. in addComponents method).
423: * @return the default LayoutConstraints object for the supported layout
424: */
425: @Override
426: protected LayoutConstraints createDefaultConstraints() {
427: return new AbsoluteLayoutConstraints(0, 0, -1, -1);
428: }
429:
430: // --------
431:
432: protected LayoutConstraints createNewConstraints(
433: LayoutConstraints currentConstr, int x, int y, int w, int h) {
434: return new AbsoluteLayoutConstraints(x, y, w, h);
435: }
436:
437: private static int computeConstraintSize(int newSize, int currSize,
438: int prefSize) {
439: return newSize != -1
440: && (newSize != prefSize || (currSize != -1 && currSize == prefSize)) ? newSize
441: : -1;
442: }
443:
444: private static int computeGridSize(int size, int step) {
445: if (step <= 0)
446: return size;
447: int mod = size % step;
448: return mod >= step / 2 ? size + step - mod : size - mod;
449: }
450:
451: private static Constructor getConstraintsConstructor() {
452: if (constrConstructor == null) {
453: try {
454: constrConstructor = AbsoluteConstraints.class
455: .getConstructor(new Class[] { Integer.TYPE,
456: Integer.TYPE, Integer.TYPE,
457: Integer.TYPE });
458: } catch (NoSuchMethodException ex) { // should not happen
459: ex.printStackTrace();
460: }
461: }
462: return constrConstructor;
463: }
464:
465: // -------------
466:
467: /** LayoutConstraints implementation class for AbsoluteConstraints.
468: */
469: public static class AbsoluteLayoutConstraints implements
470: LayoutConstraints {
471: int x, y, w, h; // position and size
472:
473: private Node.Property[] properties;
474: boolean nullMode;
475: Component refComponent;
476:
477: public AbsoluteLayoutConstraints(int x, int y, int w, int h) {
478: this .x = x;
479: this .y = y;
480: this .w = w;
481: this .h = h;
482: }
483:
484: public Node.Property[] getProperties() {
485: if (properties == null) {
486: properties = createProperties();
487: reinstateProperties();
488: }
489: return properties;
490: }
491:
492: public Object getConstraintsObject() {
493: return new AbsoluteConstraints(x, y, w, h);
494: }
495:
496: public LayoutConstraints cloneConstraints() {
497: return new AbsoluteLayoutConstraints(x, y, w, h);
498: }
499:
500: // --------
501:
502: public Rectangle getBounds() {
503: return new Rectangle(x, y, w, h);
504: }
505:
506: protected Node.Property[] createProperties() {
507: return new Node.Property[] {
508: new FormProperty("AbsoluteLayoutConstraints posx", // NOI18N
509: Integer.TYPE, getBundle().getString(
510: "PROP_posx"), // NOI18N
511: getBundle().getString("HINT_posx")) { // NOI18N
512:
513: public Object getTargetValue() {
514: return new Integer(x);
515: }
516:
517: public void setTargetValue(Object value) {
518: x = ((Integer) value).intValue();
519: }
520:
521: @Override
522: public void setPropertyContext(
523: org.netbeans.modules.form.FormPropertyContext ctx) { // disabling this method due to limited persistence
524: } // capabilities (compatibility with previous versions)
525: },
526:
527: new FormProperty("AbsoluteLayoutConstraints posy", // NOI18N
528: Integer.TYPE, getBundle().getString(
529: "PROP_posy"), // NOI18N
530: getBundle().getString("HINT_posy")) { // NOI18N
531:
532: public Object getTargetValue() {
533: return new Integer(y);
534: }
535:
536: public void setTargetValue(Object value) {
537: y = ((Integer) value).intValue();
538: }
539:
540: @Override
541: public void setPropertyContext(
542: org.netbeans.modules.form.FormPropertyContext ctx) { // disabling this method due to limited persistence
543: } // capabilities (compatibility with previous versions)
544: },
545:
546: new FormProperty("AbsoluteLayoutConstraints width", // NOI18N
547: Integer.TYPE, getBundle().getString(
548: "PROP_width"), // NOI18N
549: getBundle().getString("HINT_width")) { // NOI18N
550:
551: public Object getTargetValue() {
552: return new Integer(w);
553: }
554:
555: public void setTargetValue(Object value) {
556: w = ((Integer) value).intValue();
557: }
558:
559: @Override
560: public boolean supportsDefaultValue() {
561: return true;
562: }
563:
564: @Override
565: public Object getDefaultValue() {
566: return new Integer(-1);
567: }
568:
569: @Override
570: public PropertyEditor getExpliciteEditor() {
571: return new SizeEditor();
572: }
573:
574: @Override
575: public Object getValue(String key) {
576: if ("canEditAsText".equals(key)) // NOI18N
577: return Boolean.TRUE;
578: return super .getValue(key);
579: }
580:
581: @Override
582: public String getJavaInitializationString() {
583: if (nullMode && refComponent != null
584: && !isChanged())
585: return Integer.toString(refComponent
586: .getPreferredSize().width);
587: return super .getJavaInitializationString();
588: }
589:
590: @Override
591: public void setPropertyContext(
592: org.netbeans.modules.form.FormPropertyContext ctx) { // disabling this method due to limited persistence
593: } // capabilities (compatibility with previous versions)
594: },
595:
596: new FormProperty(
597: "AbsoluteLayoutConstraints height", // NOI18N
598: Integer.TYPE, getBundle().getString(
599: "PROP_height"), // NOI18N
600: getBundle().getString("HINT_height")) { // NOI18N
601:
602: public Object getTargetValue() {
603: return new Integer(h);
604: }
605:
606: public void setTargetValue(Object value) {
607: h = ((Integer) value).intValue();
608: }
609:
610: @Override
611: public boolean supportsDefaultValue() {
612: return true;
613: }
614:
615: @Override
616: public Object getDefaultValue() {
617: return new Integer(-1);
618: }
619:
620: @Override
621: public PropertyEditor getExpliciteEditor() {
622: return new SizeEditor();
623: }
624:
625: @Override
626: public Object getValue(String key) {
627: if ("canEditAsText".equals(key)) // NOI18N
628: return Boolean.TRUE;
629: return super .getValue(key);
630: }
631:
632: @Override
633: public String getJavaInitializationString() {
634: if (nullMode && refComponent != null
635: && !isChanged())
636: return Integer.toString(refComponent
637: .getPreferredSize().height);
638: return super .getJavaInitializationString();
639: }
640:
641: @Override
642: public void setPropertyContext(
643: org.netbeans.modules.form.FormPropertyContext ctx) { // disabling this method due to limited persistence
644: } // capabilities (compatibility with previous versions)
645: } };
646: }
647:
648: private void reinstateProperties() {
649: try {
650: for (int i = 0; i < properties.length; i++) {
651: FormProperty prop = (FormProperty) properties[i];
652: prop.reinstateProperty();
653: }
654: } catch (IllegalAccessException e1) {
655: } // should not happen
656: catch (java.lang.reflect.InvocationTargetException e2) {
657: } // should not happen
658: }
659:
660: /** This method creates CodeExpression objects for properties of
661: * AbsoluteConstraints - this is used by the layout delegate's method
662: * createConstraintsCode which uses the expressions as parameters
663: * in AbsoluteConstraints constructor.
664: * @param codeStructure main CodeStructure object in which the code
665: * expressions are created
666: * @param shift this parameter is used only by subclasses of
667: * AbsoluteLayoutConstraints (which may insert another
668: * constructor parameters before x, y, w and h)
669: * @return array of created code expressions
670: */
671: protected final CodeExpression[] createPropertyExpressions(
672: CodeStructure codeStructure, int shift) {
673: // first make sure properties are created...
674: getProperties();
675:
676: // ...then create code expressions based on the properties
677: CodeExpression xEl = codeStructure
678: .createExpression(FormCodeSupport
679: .createOrigin(properties[shift++]));
680: CodeExpression yEl = codeStructure
681: .createExpression(FormCodeSupport
682: .createOrigin(properties[shift++]));
683: CodeExpression wEl = codeStructure
684: .createExpression(FormCodeSupport
685: .createOrigin(properties[shift++]));
686: CodeExpression hEl = codeStructure
687: .createExpression(FormCodeSupport
688: .createOrigin(properties[shift]));
689: return new CodeExpression[] { xEl, yEl, wEl, hEl };
690: }
691:
692: /** This method reads CodeExpression objects for properties (used as
693: * AbsoluteConstraints constructor parameters). Called by layout
694: * delegate's readConstraintsCode method.
695: * @param exps array of code expressions to read to properties
696: * @param shift this parameter is used only by subclasses of
697: * AbsoluteLayoutConstraints (which may insert another
698: * constructor parameters before x, y, w and h)
699: */
700: protected final void readPropertyExpressions(
701: CodeExpression[] exps, int shift) {
702: // first make sure properties are created...
703: getProperties();
704:
705: // ...then map the properties to the code expressions
706: for (int i = 0; i < exps.length; i++)
707: FormCodeSupport.readPropertyExpression(exps[i],
708: properties[i + shift], false);
709: }
710: }
711:
712: // -----------
713:
714: /** PropertyEditor for width and height properties of
715: * AbsoluteLayoutConstraints.
716: */
717: public static final class SizeEditor extends PropertyEditorSupport {
718:
719: final Integer prefValue = new Integer(-1);
720: final String prefTag = getBundle().getString("VALUE_preferred"); // NOI18N
721:
722: @Override
723: public String[] getTags() {
724: return new String[] { prefTag };
725: }
726:
727: @Override
728: public String getAsText() {
729: Object value = getValue();
730: return prefValue.equals(value) ? prefTag : value.toString();
731: }
732:
733: @Override
734: public void setAsText(String str) {
735: if (prefTag.equals(str))
736: setValue(prefValue);
737: else
738: try {
739: setValue(new Integer(Integer.parseInt(str)));
740: } catch (NumberFormatException e) {
741: } // ignore
742: }
743:
744: @Override
745: public String getJavaInitializationString() {
746: Object value = getValue();
747: return value != null ? value.toString() : null;
748: }
749: }
750: }
|