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.*;
045: import java.beans.*;
046: import java.util.*;
047:
048: import org.netbeans.modules.form.NamedPropertyEditor;
049:
050: import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
051: import org.openide.util.NbBundle;
052:
053: /** A property editor for array of Strings.
054: * @author Ian Formanek
055: * @version 0.10, 17 Jun 1998
056: */
057: public class StringArrayEditor implements XMLPropertyEditor,
058: StringArrayCustomizable, NamedPropertyEditor {
059:
060: // constants for XML persistence
061: private static final String XML_STRING_ARRAY = "StringArray"; // NOI18N
062: private static final String XML_STRING_ITEM = "StringItem"; // NOI18N
063: private static final String ATTR_COUNT = "count"; // NOI18N
064: private static final String ATTR_INDEX = "index"; // NOI18N
065: private static final String ATTR_VALUE = "value"; // NOI18N
066:
067: // private fields
068: private String[] strings;
069: private PropertyChangeSupport support;
070:
071: public StringArrayEditor() {
072: support = new PropertyChangeSupport(this );
073: }
074:
075: public Object getValue() {
076: return strings;
077: }
078:
079: public void setValue(Object value) {
080: strings = (String[]) value;
081: support.firePropertyChange("", null, null); // NOI18N
082: }
083:
084: // -----------------------------------------------------------------------------
085: // StringArrayCustomizable implementation
086:
087: /** Used to acquire the current value from the PropertyEditor
088: * @return the current value of the property
089: */
090: public String[] getStringArray() {
091: return (String[]) getValue();
092: }
093:
094: /** Used to modify the current value in the PropertyEditor
095: * @param value the new value of the property
096: */
097: public void setStringArray(String[] value) {
098: setValue(value);
099: }
100:
101: // end of StringArrayCustomizable implementation
102:
103: protected final String getStrings(boolean quoted) {
104: if (strings == null)
105: return "null"; // NOI18N
106:
107: StringBuffer buf = new StringBuffer();
108: for (int i = 0; i < strings.length; i++) {
109: // Handles in-string escapes if quoted
110: if (quoted) {
111: buf.append("\""); // NOI18N
112: char[] chars = strings[i].toCharArray();
113: for (int j = 0; j < chars.length; j++) {
114: char c = chars[j];
115: switch (c) {
116: case '\b':
117: buf.append("\\b");
118: break; // NOI18N
119: case '\t':
120: buf.append("\\t");
121: break; // NOI18N
122: case '\n':
123: buf.append("\\n");
124: break; // NOI18N
125: case '\f':
126: buf.append("\\f");
127: break; // NOI18N
128: case '\r':
129: buf.append("\\r");
130: break; // NOI18N
131: case '\"':
132: buf.append("\\\"");
133: break; // NOI18N
134: case '\\':
135: buf.append("\\\\");
136: break; // NOI18N
137: default:
138: if (c >= 0x0020/* && c <= 0x007f*/)
139: buf.append(c);
140: else {
141: buf.append("\\u"); // NOI18N
142: String hex = Integer.toHexString(c);
143: for (int k = 0; k < 4 - hex.length(); k++)
144: buf.append('0');
145: buf.append(hex);
146: }
147: }
148: }
149: buf.append("\""); // NOI18N
150: } else {
151: buf.append(strings[i]);
152: }
153: if (i != strings.length - 1)
154: buf.append(", "); // NOI18N
155: }
156:
157: return buf.toString();
158: }
159:
160: public String getAsText() {
161: return getStrings(false);
162: }
163:
164: public void setAsText(String text) {
165: if (text.equals("null")) { // NOI18N
166: setValue(null);
167: return;
168: }
169: StringTokenizer tok = new StringTokenizer(text, ","); // NOI18N
170: java.util.List<String> list = new LinkedList<String>();
171: while (tok.hasMoreTokens()) {
172: String s = tok.nextToken();
173: list.add(s.trim());
174: }
175: String[] a = list.toArray(new String[list.size()]);
176: setValue(a);
177: }
178:
179: public String getJavaInitializationString() {
180: if (strings == null)
181: return "null"; // NOI18N
182: // [PENDING - wrap strings ???]
183: StringBuffer buf = new StringBuffer("new String[] {"); // NOI18N
184: buf.append(getStrings(true));
185: buf.append("}"); // NOI18N
186: return buf.toString();
187: }
188:
189: public String[] getTags() {
190: return null;
191: }
192:
193: public boolean isPaintable() {
194: return false;
195: }
196:
197: public void paintValue(Graphics g, Rectangle rectangle) {
198: }
199:
200: public boolean supportsCustomEditor() {
201: return true;
202: }
203:
204: public Component getCustomEditor() {
205: return new StringArrayCustomEditor(this );
206: }
207:
208: public void addPropertyChangeListener(
209: PropertyChangeListener propertyChangeListener) {
210: support.addPropertyChangeListener(propertyChangeListener);
211: }
212:
213: public void removePropertyChangeListener(
214: PropertyChangeListener propertyChangeListener) {
215: support.removePropertyChangeListener(propertyChangeListener);
216: }
217:
218: // -------------------------------------------
219: // XMLPropertyEditor implementation
220:
221: /** Called to store current property value into XML subtree.
222: * @param doc The XML document to store the XML in - should be used for
223: * creating nodes only
224: * @return the XML DOM element representing a subtree of XML from which
225: the value should be loaded
226: */
227: public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) {
228: org.w3c.dom.Element arrayEl = doc
229: .createElement(XML_STRING_ARRAY);
230: int count = strings != null ? strings.length : 0;
231: arrayEl.setAttribute(ATTR_COUNT, Integer.toString(count));
232:
233: for (int i = 0; i < count; i++) {
234: org.w3c.dom.Element itemEl = doc
235: .createElement(XML_STRING_ITEM);
236: itemEl.setAttribute(ATTR_INDEX, Integer.toString(i));
237: itemEl.setAttribute(ATTR_VALUE, strings[i]);
238: arrayEl.appendChild(itemEl);
239: }
240:
241: return arrayEl;
242: }
243:
244: /** Called to load property value from specified XML subtree.
245: * If succesfully loaded, the value should be available via getValue().
246: * An IOException should be thrown when the value cannot be restored from
247: * the specified XML element
248: * @param element the XML DOM element representing a subtree of XML from
249: * which the value should be loaded
250: * @exception IOException thrown when the value cannot be restored from
251: the specified XML element
252: */
253: public void readFromXML(org.w3c.dom.Node element)
254: throws java.io.IOException {
255: if (!XML_STRING_ARRAY.equals(element.getNodeName()))
256: throw new java.io.IOException();
257:
258: org.w3c.dom.NamedNodeMap attributes = element.getAttributes();
259: String[] stringArray;
260: org.w3c.dom.Node countNode = null;
261: int count = 0;
262:
263: if ((countNode = attributes.getNamedItem(ATTR_COUNT)) != null
264: && (count = Integer.parseInt(countNode.getNodeValue())) > 0) {
265: stringArray = new String[count];
266: org.w3c.dom.NodeList items = element.getChildNodes();
267: org.w3c.dom.Element itemEl;
268:
269: for (int i = 0; i < items.getLength(); i++) {
270: if (items.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
271: itemEl = (org.w3c.dom.Element) items.item(i);
272: if (itemEl.getNodeName().equals(XML_STRING_ITEM)) {
273: String indexStr = itemEl
274: .getAttribute(ATTR_INDEX);
275: String valueStr = itemEl
276: .getAttribute(ATTR_VALUE);
277: if (indexStr != null && valueStr != null) {
278: int index = Integer.parseInt(indexStr);
279: if (index >= 0 && index < count) {
280: stringArray[index] = valueStr;
281: }
282:
283: }
284: }
285: }
286: }
287: } else
288: stringArray = new String[0];
289:
290: setValue(stringArray);
291: }
292:
293: // NamedPropertyEditor implementation
294: public String getDisplayName() {
295: return NbBundle.getBundle(StringArrayEditor.class).getString(
296: "CTL_StringArrayEditor_DisplayName"); // NOI18N
297: }
298:
299: }
|