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.editors2;
043:
044: import java.awt.Component;
045: import java.beans.PropertyEditor;
046: import java.beans.PropertyEditorSupport;
047: import java.io.IOException;
048: import java.lang.reflect.InvocationTargetException;
049: import java.util.LinkedList;
050: import java.util.List;
051: import java.util.logging.Level;
052: import java.util.logging.Logger;
053: import javax.swing.JLabel;
054: import javax.swing.ListSelectionModel;
055: import javax.swing.SwingConstants;
056: import javax.swing.table.*;
057: import org.netbeans.modules.form.*;
058: import org.netbeans.modules.form.codestructure.CodeVariable;
059: import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
060: import org.openide.util.NbBundle;
061: import org.w3c.dom.Document;
062: import org.w3c.dom.Node;
063: import org.w3c.dom.NodeList;
064:
065: /**
066: * Simple property editor for <code>TableColumnModel</code>.
067: *
068: * @author Jan Stola
069: */
070: public class TableColumnModelEditor extends PropertyEditorSupport
071: implements NamedPropertyEditor, FormCodeAwareEditor,
072: XMLPropertyEditor {
073:
074: /** Property being edited. */
075: private RADProperty property;
076:
077: /**
078: * Retruns display name of this property editor.
079: *
080: * @return diaplay name of this property editor.
081: */
082: public String getDisplayName() {
083: return NbBundle
084: .getMessage(getClass(), "TableColumnModelEditor"); // NOI18N
085: }
086:
087: /**
088: * Sets context of the property editor.
089: *
090: * @param formModel form model.
091: * @param property property being edited.
092: */
093: public void setContext(FormModel formModel, FormProperty property) {
094: this .property = (RADProperty) property;
095: }
096:
097: /**
098: * Raise form version to 6.0 - this editor is available since NB 6.0.
099: */
100: public void updateFormVersionLevel() {
101: property.getPropertyContext().getFormModel().raiseVersionLevel(
102: FormModel.FormVersion.NB60, FormModel.FormVersion.NB60);
103: }
104:
105: /**
106: * Determines whether this property editor supports custom editing.
107: *
108: * @return <code>true</code>.
109: */
110: @Override
111: public boolean supportsCustomEditor() {
112: return true;
113: }
114:
115: /**
116: * Returns custom editor.
117: *
118: * @return custom editor.
119: */
120: @Override
121: public Component getCustomEditor() {
122: JLabel label = new JLabel(NbBundle.getMessage(getClass(),
123: "TableColumnModelEditor_Customizer")); // NOI18N
124: label.setHorizontalAlignment(SwingConstants.CENTER);
125: return label;
126: }
127:
128: public String getSourceCode() {
129: RADComponent comp = property.getRADComponent();
130: CodeVariable var = comp.getCodeExpression().getVariable();
131: String varName = (var == null) ? null : var.getName();
132: String readMethod = property.getPropertyDescriptor()
133: .getReadMethod().getName();
134: String getter = readMethod + "()"; // NOI18N
135: if (varName != null) {
136: getter = varName + '.' + getter;
137: }
138:
139: Object value = getValue();
140: if (value instanceof FormTableColumnModel) {
141: FormTableColumnModel columnModel = (FormTableColumnModel) value;
142: StringBuilder code = new StringBuilder();
143:
144: // selection model
145: int selectionModel = columnModel.getSelectionModel();
146: if (selectionModel > 0) {
147: code
148: .append(getter)
149: .append(
150: ".getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel."); // NOI18N
151: switch (selectionModel) {
152: case 1:
153: code.append("SINGLE_SELECTION");
154: break; // NOI18N
155: case 2:
156: code.append("SINGLE_INTERVAL_SELECTION");
157: break; // NOI18N
158: case 3:
159: code.append("MULTIPLE_INTERVAL_SELECTION");
160: break; // NOI18N
161: }
162: code.append(");\n"); // NOI18N
163: }
164:
165: // columns
166: List<FormTableColumn> columns = columnModel.getColumns();
167: for (int i = 0; i < columns.size(); i++) {
168: FormTableColumn column = columns.get(i);
169: String columnGetter = getter + ".getColumn(" + i + ")"; // NOI18N
170: if (!column.isResizable()) {
171: code.append(columnGetter).append(".setResizable(")
172: .append(
173: Boolean.toString(column
174: .isResizable())).append(
175: ");\n"); // NOI18N
176: }
177: if (column.getMinWidth() != -1) {
178: code.append(columnGetter).append(".setMinWidth(")
179: .append(
180: Integer.toString(column
181: .getMinWidth())).append(
182: ");\n"); // NOI18N
183: }
184: if (column.getPrefWidth() != -1) {
185: code.append(columnGetter).append(
186: ".setPreferredWidth(").append(
187: Integer.toString(column.getPrefWidth()))
188: .append(");\n"); // NOI18N
189: }
190: if (column.getMaxWidth() != -1) {
191: code.append(columnGetter).append(".setMaxWidth(")
192: .append(
193: Integer.toString(column
194: .getMaxWidth())).append(
195: ");\n"); // NOI18N
196: }
197: FormProperty prop = column.getTitle();
198: if (prop.isChanged()) {
199: code.append(columnGetter)
200: .append(".setHeaderValue(").append(
201: prop.getJavaInitializationString())
202: .append(");\n"); // NOI18N
203: }
204: prop = column.getEditor();
205: if (prop.isChanged()) {
206: code.append(columnGetter).append(".setCellEditor(")
207: .append(prop.getJavaInitializationString())
208: .append(");\n"); // NOI18N
209: }
210: prop = column.getRenderer();
211: if (prop.isChanged()) {
212: code.append(columnGetter).append(
213: ".setCellRenderer(").append(
214: prop.getJavaInitializationString()).append(
215: ");\n"); // NOI18N
216: }
217: }
218:
219: return (code.length() == 0) ? null : code.toString();
220: } else {
221: return null;
222: }
223: }
224:
225: private static final String XML_TABLE_COLUMN_MODEL = "TableColumnModel"; // NOI18N
226: private static final String ATTR_SELECTION_MODEL = "selectionModel"; // NOI18N
227: private static final String XML_COLUMN = "Column"; // NOI18N
228: private static final String ATTR_RESIZABLE = "resizable"; // NOI18N
229: private static final String ATTR_WIDTH_MIN = "minWidth"; // NOI18N
230: private static final String ATTR_WIDTH_PREF = "prefWidth"; // NOI18N
231: private static final String ATTR_WIDTH_MAX = "maxWidth"; // NOI18N
232: private static final String XML_TITLE = "Title"; // NOI18N
233: private static final String XML_EDITOR = "Editor"; // NOI18N
234: private static final String XML_RENDERER = "Renderer"; // NOI18N
235: private static final String ATTR_PROP_EDITOR = "editor"; // NOI18N
236: private static final String ATTR_VALUE = "value"; // NOI18N
237: private static final String ATTR_RESOURCE_KEY = "resourceKey"; // NOI18N
238: private static final String ATTR_NO_RESOURCE = "noResource"; // NOI18N
239:
240: public void readFromXML(Node element) throws IOException {
241: org.w3c.dom.NamedNodeMap attributes = element.getAttributes();
242: String selectionModelTxt = attributes.getNamedItem(
243: ATTR_SELECTION_MODEL).getNodeValue();
244: int selectionModel = Integer.parseInt(selectionModelTxt);
245: FormTableColumnModel model = new FormTableColumnModel(property);
246: model.setSelectionModel(selectionModel);
247:
248: NodeList nodes = element.getChildNodes();
249: for (int i = 0; i < nodes.getLength(); i++) {
250: Node node = nodes.item(i);
251: if (XML_COLUMN.equals(node.getNodeName())) {
252: FormTableColumn column = new FormTableColumn(property,
253: model.getColumns().size());
254:
255: org.w3c.dom.NamedNodeMap colAttrs = node
256: .getAttributes();
257: String resizableTxt = colAttrs.getNamedItem(
258: ATTR_RESIZABLE).getNodeValue();
259: String minWidthTxt = colAttrs.getNamedItem(
260: ATTR_WIDTH_MIN).getNodeValue();
261: String prefWidthTxt = colAttrs.getNamedItem(
262: ATTR_WIDTH_PREF).getNodeValue();
263: String maxWidthTxt = colAttrs.getNamedItem(
264: ATTR_WIDTH_MAX).getNodeValue();
265: boolean resizable = Boolean.parseBoolean(resizableTxt);
266: int minWidth = Integer.parseInt(minWidthTxt);
267: int prefWidth = Integer.parseInt(prefWidthTxt);
268: int maxWidth = Integer.parseInt(maxWidthTxt);
269: column.setResizable(resizable);
270: column.setMinWidth(minWidth);
271: column.setPrefWidth(prefWidth);
272: column.setMaxWidth(maxWidth);
273:
274: NodeList subNodes = node.getChildNodes();
275: for (int j = 0; j < subNodes.getLength(); j++) {
276: Node subNode = subNodes.item(j);
277: String nodeName = subNode.getNodeName();
278: if (XML_TITLE.equals(nodeName)) {
279: loadProperty(column.getTitle(), subNode);
280: } else if (XML_EDITOR.equals(nodeName)) {
281: loadProperty(column.getEditor(), subNode);
282: } else if (XML_RENDERER.equals(nodeName)) {
283: loadProperty(column.getRenderer(), subNode);
284: }
285: }
286:
287: model.getColumns().add(column);
288: }
289: }
290: setValue(model);
291: }
292:
293: private void loadProperty(FormProperty property, Node node) {
294: org.w3c.dom.NamedNodeMap attributes = node.getAttributes();
295: Node valueNode = attributes.getNamedItem(ATTR_VALUE);
296: Node noResourceNode = attributes.getNamedItem(ATTR_NO_RESOURCE);
297: Node resourceKeyNode = attributes
298: .getNamedItem(ATTR_RESOURCE_KEY);
299: FormModel formModel = property.getPropertyContext()
300: .getFormModel();
301: try {
302: if (resourceKeyNode != null) {
303: String resourceKey = resourceKeyNode.getNodeValue();
304: Object value = ResourceSupport.findResource(formModel,
305: resourceKey, property.getValueType());
306: property.setValue(value);
307: } else if (valueNode != null) {
308: property.setValue(valueNode.getNodeValue());
309: } else {
310: NodeList nodes = node.getChildNodes();
311: for (int i = 0; i < nodes.getLength(); i++) {
312: Node subNode = nodes.item(i);
313: if (subNode.getNodeType() == Node.ELEMENT_NODE) {
314: String propEdName = attributes.getNamedItem(
315: ATTR_PROP_EDITOR).getNodeValue();
316: XMLPropertyEditor xmlPropEd = null;
317: if (propEdName
318: .equals(RADConnectionPropertyEditor.class
319: .getName())) {
320: xmlPropEd = new RADConnectionPropertyEditor(
321: property.getValueType());
322: ((FormAwareEditor) xmlPropEd).setContext(
323: formModel, property);
324: } else {
325: Class propEdClass = PersistenceObjectRegistry
326: .loadClass(propEdName, FormEditor
327: .getFormDataObject(
328: formModel)
329: .getFormFile());
330: Object propEd = propEdClass.newInstance();
331: if (propEd instanceof XMLPropertyEditor) {
332: xmlPropEd = (XMLPropertyEditor) propEd;
333: if (propEd instanceof FormAwareEditor) {
334: ((FormAwareEditor) propEd)
335: .setContext(formModel,
336: property);
337: }
338: }
339: }
340: if (xmlPropEd != null) {
341: xmlPropEd.readFromXML(subNode);
342: property
343: .setValue(new FormProperty.ValueWithEditor(
344: xmlPropEd.getValue(),
345: xmlPropEd));
346: }
347: break;
348: }
349: }
350: }
351: if (noResourceNode != null) {
352: if (Boolean.parseBoolean(noResourceNode.getNodeValue())) {
353: ResourceSupport.setExcludedProperty(property, true);
354: }
355: }
356: } catch (Exception ex) {
357: Logger.getLogger(getClass().getName()).log(Level.INFO,
358: ex.getMessage(), ex);
359: }
360: }
361:
362: public Node storeToXML(Document doc) {
363: Object value = getValue();
364: org.w3c.dom.Element el = null;
365: if (value instanceof FormTableColumnModel) {
366: FormTableColumnModel model = (FormTableColumnModel) value;
367: el = doc.createElement(XML_TABLE_COLUMN_MODEL);
368: el.setAttribute(ATTR_SELECTION_MODEL, Integer
369: .toString(model.getSelectionModel()));
370:
371: for (FormTableColumn column : model.getColumns()) {
372: org.w3c.dom.Element columnEl = doc
373: .createElement(XML_COLUMN);
374: columnEl.setAttribute(ATTR_RESIZABLE, Boolean
375: .toString(column.isResizable()));
376: columnEl.setAttribute(ATTR_WIDTH_MIN, Integer
377: .toString(column.getMinWidth()));
378: columnEl.setAttribute(ATTR_WIDTH_PREF, Integer
379: .toString(column.getPrefWidth()));
380: columnEl.setAttribute(ATTR_WIDTH_MAX, Integer
381: .toString(column.getMaxWidth()));
382:
383: org.w3c.dom.Element titleEl = doc
384: .createElement(XML_TITLE);
385: org.w3c.dom.Element editorEl = doc
386: .createElement(XML_EDITOR);
387: org.w3c.dom.Element rendererEl = doc
388: .createElement(XML_RENDERER);
389: storeProperty(doc, titleEl, column.getTitle());
390: storeProperty(doc, editorEl, column.getEditor());
391: storeProperty(doc, rendererEl, column.getRenderer());
392: columnEl.appendChild(titleEl);
393: columnEl.appendChild(editorEl);
394: columnEl.appendChild(rendererEl);
395: el.appendChild(columnEl);
396: }
397: }
398: return el;
399: }
400:
401: private void storeProperty(Document doc,
402: org.w3c.dom.Element element, FormProperty property) {
403: if (property.isChanged()) {
404: PropertyEditor editor = property.getCurrentEditor();
405: if (editor instanceof XMLPropertyEditor) {
406: element.setAttribute(ATTR_PROP_EDITOR, editor
407: .getClass().getName());
408: Node node = ((XMLPropertyEditor) editor)
409: .storeToXML(doc);
410: element.appendChild(node);
411: } else {
412: try {
413: Object value = property.getValue();
414: String resourceKey = null;
415: if (value instanceof ResourceValue) {
416: resourceKey = ((ResourceValue) value).getKey();
417: } else {
418: if (value instanceof String) {
419: element.setAttribute(ATTR_VALUE,
420: (String) value);
421: } else {
422: System.err.println("Unable to store "
423: + property); // NOI18N
424: }
425: }
426: if (resourceKey != null) {
427: element.setAttribute(ATTR_RESOURCE_KEY,
428: resourceKey);
429: }
430: } catch (IllegalAccessException iaex) {
431: Logger.getLogger(getClass().getName()).log(
432: Level.INFO, iaex.getMessage(), iaex);
433: } catch (InvocationTargetException itex) {
434: Logger.getLogger(getClass().getName()).log(
435: Level.INFO, itex.getMessage(), itex);
436: }
437: }
438: }
439: boolean noResource = ResourceSupport
440: .isResourceableProperty(property)
441: && ResourceSupport.isExcludedProperty(property);
442: if (noResource) {
443: element.setAttribute(ATTR_NO_RESOURCE, Boolean.TRUE
444: .toString());
445: }
446: }
447:
448: public static class FormTableColumnModel extends
449: FormDesignValueAdapter {
450: private FormProperty property;
451: private int selectionModel;
452: private List<FormTableColumn> columns;
453:
454: public FormTableColumnModel(FormProperty property) {
455: this .property = property;
456: columns = new LinkedList<FormTableColumn>();
457: }
458:
459: public void setSelectionModel(int selectionModel) {
460: this .selectionModel = selectionModel;
461: }
462:
463: public int getSelectionModel() {
464: return selectionModel;
465: }
466:
467: public List<FormTableColumn> getColumns() {
468: return columns;
469: }
470:
471: public Object getDesignValue() {
472: Object value = null;
473: try {
474: value = property.getTargetValue();
475: if (value instanceof TableColumnModel) {
476: TableColumnModel columnModel = (TableColumnModel) value;
477: designValue(columnModel);
478: }
479: } catch (IllegalAccessException iaex) {
480: Logger.getLogger(getClass().getName()).log(Level.INFO,
481: iaex.getMessage(), iaex);
482: } catch (InvocationTargetException itex) {
483: Logger.getLogger(getClass().getName()).log(Level.INFO,
484: itex.getMessage(), itex);
485: }
486: return value;
487: }
488:
489: @Override
490: public Object getDesignValue(Object target) {
491: TableColumnModel columnModel = null;
492: if (target instanceof javax.swing.JTable) {
493: columnModel = ((javax.swing.JTable) target)
494: .getColumnModel();
495: designValue(columnModel);
496: }
497: return columnModel;
498: }
499:
500: private void designValue(TableColumnModel columnModel) {
501: int selectionModel = getSelectionModel();
502: switch (selectionModel) {
503: case 0:
504: break; // not allowed - default value
505: case 1:
506: columnModel.getSelectionModel().setSelectionMode(
507: ListSelectionModel.SINGLE_SELECTION);
508: break;
509: case 2:
510: columnModel.getSelectionModel().setSelectionMode(
511: ListSelectionModel.SINGLE_INTERVAL_SELECTION);
512: break;
513: case 3:
514: columnModel.getSelectionModel().setSelectionMode(
515: ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
516: break;
517: }
518: for (int i = 0; i < columns.size()
519: && i < columnModel.getColumnCount(); i++) {
520: FormTableColumn formColumn = columns.get(i);
521: TableColumn column = columnModel.getColumn(i);
522: column.setResizable(formColumn.isResizable());
523: int width = (formColumn.getMinWidth() == -1) ? defaultColumn()
524: .getMinWidth()
525: : formColumn.getMinWidth();
526: column.setMinWidth(width);
527: width = (formColumn.getPrefWidth() == -1) ? defaultColumn()
528: .getPreferredWidth()
529: : formColumn.getPrefWidth();
530: column.setPreferredWidth(width);
531: width = (formColumn.getMaxWidth() == -1) ? defaultColumn()
532: .getMaxWidth()
533: : formColumn.getMaxWidth();
534: column.setMaxWidth(width);
535: FormProperty prop = formColumn.getTitle();
536: try {
537: if (prop.isChanged()) {
538: column.setHeaderValue(prop.getRealValue());
539: }
540: } catch (Exception ex) {
541: Logger.getLogger(getClass().getName()).log(
542: Level.INFO, ex.getMessage(), ex);
543: }
544: prop = formColumn.getEditor();
545: try {
546: if (prop.isChanged()) {
547: Object editor = prop.getRealValue();
548: if (editor instanceof TableCellEditor) {
549: column
550: .setCellEditor((TableCellEditor) editor);
551: }
552: }
553: } catch (Exception ex) {
554: Logger.getLogger(getClass().getName()).log(
555: Level.INFO, ex.getMessage(), ex);
556: }
557: prop = formColumn.getRenderer();
558: try {
559: if (prop.isChanged()) {
560: Object renderer = prop.getRealValue();
561: if (renderer instanceof TableCellRenderer) {
562: column
563: .setCellRenderer((TableCellRenderer) renderer);
564: }
565: }
566: } catch (Exception ex) {
567: Logger.getLogger(getClass().getName()).log(
568: Level.INFO, ex.getMessage(), ex);
569: }
570: }
571: }
572:
573: private TableColumn defaultColumn;
574:
575: private TableColumn defaultColumn() {
576: if (defaultColumn == null) {
577: defaultColumn = new TableColumn();
578: }
579: return defaultColumn;
580: }
581:
582: }
583:
584: public static class FormTableColumn {
585: private int minWidth;
586: private int prefWidth;
587: private int maxWidth;
588: private boolean resizable;
589: private Property title;
590: private Property editor;
591: private Property renderer;
592:
593: public FormTableColumn(RADProperty prop, int index) {
594: minWidth = -1;
595: prefWidth = -1;
596: maxWidth = -1;
597: resizable = true;
598: title = new Property(prop, "title" + index, String.class,
599: null, null); // NOI18N
600: editor = new Property(prop, "editor" + index,
601: TableCellEditor.class, null, null); // NOI18N
602: renderer = new Property(prop, "renderer" + index,
603: TableCellRenderer.class, null, null); // NOI18N
604: }
605:
606: public int getMinWidth() {
607: return minWidth;
608: }
609:
610: public void setMinWidth(int minWidth) {
611: this .minWidth = minWidth;
612: }
613:
614: public int getPrefWidth() {
615: return prefWidth;
616: }
617:
618: public void setPrefWidth(int prefWidth) {
619: this .prefWidth = prefWidth;
620: }
621:
622: public int getMaxWidth() {
623: return maxWidth;
624: }
625:
626: public void setMaxWidth(int maxWidth) {
627: this .maxWidth = maxWidth;
628: }
629:
630: public boolean isResizable() {
631: return resizable;
632: }
633:
634: public void setResizable(boolean resizable) {
635: this .resizable = resizable;
636: }
637:
638: public FormProperty getTitle() {
639: return title;
640: }
641:
642: public FormProperty getEditor() {
643: return editor;
644: }
645:
646: public FormProperty getRenderer() {
647: return renderer;
648: }
649: }
650:
651: static class Property extends FormProperty {
652: private Object value;
653:
654: Property(RADProperty prop, String name, Class type,
655: String displayName, String description) {
656: super (new FormPropertyContext.SubProperty(prop), name,
657: type, displayName, description);
658: prop.getRADComponent().setPropertyListener(this );
659: }
660:
661: public Object getTargetValue() throws IllegalAccessException,
662: InvocationTargetException {
663: return value;
664: }
665:
666: public void setTargetValue(Object value)
667: throws IllegalAccessException,
668: IllegalArgumentException, InvocationTargetException {
669: this.value = value;
670: }
671: }
672:
673: }
|