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-2007 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.uml.ui.swing.treetable;
043:
044: import java.awt.Component;
045: import java.util.StringTokenizer;
046: import java.util.Vector;
047: import java.util.HashMap;
048:
049: import javax.swing.Icon;
050: import javax.swing.ImageIcon;
051: import javax.swing.JLabel;
052: import javax.swing.JTree;
053: import javax.swing.event.EventListenerList;
054: import javax.swing.event.TreeModelEvent;
055: import javax.swing.event.TreeModelListener;
056: import javax.swing.tree.DefaultMutableTreeNode;
057: import javax.swing.tree.TreeModel;
058: import javax.swing.tree.TreePath;
059:
060: import org.netbeans.modules.uml.common.ETSystem;
061: import org.netbeans.modules.uml.core.configstringframework.ConfigStringTranslator;
062: import org.netbeans.modules.uml.core.support.umlutils.IPropertyDefinition;
063: import org.netbeans.modules.uml.core.support.umlutils.IPropertyElement;
064: import org.netbeans.modules.uml.core.support.umlutils.PropertyElement;
065: import org.netbeans.modules.uml.ui.swing.propertyeditor.PropertyEditor;
066:
067: /**
068: * @author sumitabhk
069: *
070: */
071: public class PropertyTreeTableModel implements TreeTableModel {
072: // Names of the columns.
073: static protected String[] cNames = { " ", " ", " " };
074:
075: // Types of the columns.
076: static protected Class[] cTypes = { ImageIcon.class,
077: PropertyElement.class, String.class };
078:
079: private Vector<Object> m_Children = null;
080: private HashMap<Object, Vector<Object>> m_BuiltChildren = new HashMap<Object, Vector<Object>>();
081: private Vector<Icon> m_Icons = new Vector<Icon>();
082:
083: protected JDefaultMutableTreeNode root = null;
084:
085: private static JTreeTable treeTable = null;
086:
087: protected EventListenerList listenerList = new EventListenerList();
088: private PropertyEditor m_editor = null;
089: private ConfigStringTranslator m_Translator = new ConfigStringTranslator();
090:
091: private Object m_EditableComponent = null;
092:
093: /**
094: *
095: */
096: public PropertyTreeTableModel() {
097: super ();
098: }
099:
100: public PropertyTreeTableModel(JDefaultMutableTreeNode root,
101: PropertyEditor editor) {
102: super ();
103: this .root = root;
104: m_editor = editor;
105: }
106:
107: public PropertyTreeTableModel(JDefaultMutableTreeNode root,
108: IPropertyElement ele) {
109: super ();
110: this .root = root;
111: JDefaultMutableTreeNode node = new JDefaultMutableTreeNode(ele,
112: true);
113: root.add(node);
114:
115: }
116:
117: public static void main(String[] args) {
118: }
119:
120: /* (non-Javadoc)
121: * @see TreeTableModel#getColumnCount()
122: */
123: public int getColumnCount() {
124: return cNames.length;
125: }
126:
127: /* (non-Javadoc)
128: * @see TreeTableModel#getColumnName(int)
129: */
130: public String getColumnName(int column) {
131: return cNames[column];
132: }
133:
134: /* (non-Javadoc)
135: * @see TreeTableModel#getColumnClass(int)
136: */
137: public Class getColumnClass(int column) {
138: if (column == 1) {
139: return this .getClass();
140: }
141: if (column <= cTypes.length)
142: return cTypes[column];
143: return null;
144: }
145:
146: /* (non-Javadoc)
147: * @see TreeTableModel#getValueAt(java.lang.Object, int)
148: */
149: public Object getValueAt(Object node, int column) {
150: if (node instanceof JDefaultMutableTreeNode) {
151: JDefaultMutableTreeNode n = (JDefaultMutableTreeNode) node;
152: Object obj = n.getUserObject();
153: if (obj instanceof IPropertyElement) {
154: IPropertyElement ele = (IPropertyElement) n
155: .getUserObject();
156: if (column == 1) {
157: IPropertyDefinition pDef = ele
158: .getPropertyDefinition();
159: if (pDef != null) {
160: if (n.isRoot()) {
161: return m_editor
162: .calculateTopElementName(ele);
163: } else {
164: return pDef.getDisplayName();
165: }
166: }
167: } else if (column == 2) {
168: String retValue = null;
169: String value = ele.getTranslatedValue();
170: retValue = value;
171: try {
172: IPropertyDefinition pDef = ele
173: .getPropertyDefinition();
174: if (pDef != null) {
175: long mult = pDef.getMultiplicity();
176: if (mult > 1) {
177: String str = pDef.getValidValues();
178: if (str == null) {
179: //here we do not want to show anything
180: retValue = null;
181: }
182: } else {
183: int enumVal = Integer.valueOf(value)
184: .intValue();
185: //there is a possibility that enums are specified in definitions,
186: //in which case the value obtained will not be correct.
187: String enumValues = pDef
188: .getFromAttrMap("enumValues");
189: if (enumValues != null) {
190: StringTokenizer tokenizer = new StringTokenizer(
191: enumValues, "|");
192: int counter = 0;
193: while (tokenizer.hasMoreTokens()) {
194: String token = tokenizer
195: .nextToken();
196: if (token.equals(value)) {
197: enumVal = counter;
198: break;
199: }
200: counter++;
201: }
202: }
203: //here we want to find out the enum value and show the
204: //translated value.
205: String values = pDef.getValidValues();
206: if (values != null
207: && values.indexOf("|") >= 0) {
208: StringTokenizer tokenizer = new StringTokenizer(
209: values, "|");
210: int j = 0;
211: while (tokenizer.hasMoreTokens()) {
212: String token = tokenizer
213: .nextToken();
214: if (j == enumVal) {
215: String transVal = m_Translator
216: .translate(pDef,
217: token);
218: retValue = transVal;
219: }
220: j++;
221: }
222: }
223: }
224: }
225: } catch (NumberFormatException e) {
226: }
227: return retValue;
228: } else if (column == 0) {
229: Object obj1 = getRoot();
230: if (obj1 instanceof JDefaultMutableTreeNode) {
231: JDefaultMutableTreeNode root = (JDefaultMutableTreeNode) obj1;
232:
233: //We want to show images only if there is only one node selected.
234: int countChild = root.getChildCount();
235: if (countChild == 1) {
236: root = (JDefaultMutableTreeNode) root
237: .getChildAt(0);
238: int index = root.getIndex(n);
239: //ETSystem.out.println("Index for " + ele.getName() + " " + index);
240: if (m_Icons.size() == 0) {
241: m_Icons = m_editor.loadImages(root);
242: }
243: if (m_Icons != null
244: && m_Icons.size() > index + 1) {
245: //check to see if we have filtered the list in any way
246: if (m_editor.isShowingFilteredOnIcons()
247: || m_editor
248: .isShowingComboFilteredList()) {
249: //an already showing filtered list, so need to
250: // show only the first icon.
251: if (index == -1 && n.equals(root)) {
252: return m_Icons
253: .elementAt(index + 1);
254: } else {
255: return null;
256: }
257: } else {
258: //get the right icon.
259: if (index == -1 && n.equals(root)) {
260: return m_Icons
261: .elementAt(index + 1);
262: } else if (index >= 0) {
263: return m_Icons
264: .elementAt(index + 1);
265: }
266: }
267: } else {
268: return null;
269: }
270: }
271: }
272: }
273: }
274: }
275: return null;
276: }
277:
278: /* (non-Javadoc)
279: * @see TreeTableModel#isCellEditable(java.lang.Object, int)
280: */
281: public boolean isCellEditable(Object node, int column) {
282: // if (column == 2)
283: // {
284: // return true;
285: // }
286: return true;
287: }
288:
289: /* (non-Javadoc)
290: * @see TreeTableModel#setValueAt(java.lang.Object, java.lang.Object, int)
291: */
292: public void setValueAt(Object aValue, Object node, int column) {
293: if (aValue != null && node != null) {
294: ETSystem.out.println("Calling setValueAt for " + column
295: + aValue.toString() + node.toString());
296: }
297: if (aValue instanceof JTreeTable.TreeTableCellRenderer) {
298: JTreeTable.TreeTableCellRenderer rend = (JTreeTable.TreeTableCellRenderer) aValue;
299:
300: }
301: //m_editor.processLastCell();
302: }
303:
304: /* (non-Javadoc)
305: * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
306: */
307: public Object getChild(Object parent, int index) {
308: Object retObj = null;
309: if (parent != null) {
310: JDefaultMutableTreeNode node = (JDefaultMutableTreeNode) parent;
311: int count = node.getChildCount();
312: if (count > 0 && index <= count) {
313: retObj = node.getChildAt(index);
314: } else {
315: retObj = getChildren(parent)[index];
316: }
317: }
318: return retObj;
319: }
320:
321: protected Object[] getChildren(Object node) {
322: Object[] retObj = null;
323: // if (m_BuiltChildren != null)
324: // {
325: // Vector<Object> obj = m_BuiltChildren.get(node);
326: // if (obj != null)
327: // {
328: // retObj = obj.toArray();
329: // }
330: // else
331: // {
332: // DefaultMutableTreeNode n = (DefaultMutableTreeNode)node;
333: // IPropertyElement ele = (IPropertyElement)n.getUserObject();
334: // Vector<Object> children = PropertyEditor.instance().buildSubElementsThatNeedToDisplay(ele, n);
335: // m_BuiltChildren.put(node, children);
336: // retObj = children.toArray();
337: // }
338: // }
339:
340: JDefaultMutableTreeNode n = (JDefaultMutableTreeNode) node;
341: int count = n.getChildCount();
342: if (count == 0) {
343: IPropertyElement ele = (IPropertyElement) n.getUserObject();
344: Vector<Object> children = m_editor
345: .buildSubElementsThatNeedToDisplay(ele, n);
346: //m_BuiltChildren.put(node, children);
347: retObj = children.toArray();
348: }
349:
350: return retObj;
351: }
352:
353: public void setChildren(Vector<Object> newChildren) {
354: m_Children.clear();
355: m_Children = newChildren;
356: }
357:
358: /* (non-Javadoc)
359: * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
360: */
361: public int getChildCount(Object parent) {
362: int retCount = 0;
363: if (parent != null) {
364: JDefaultMutableTreeNode node = (JDefaultMutableTreeNode) parent;
365: int count = node.getChildCount();
366: if (count > 0) {
367: retCount = count;
368: } else {
369: retCount = getChildren(parent).length;
370: }
371: }
372: return retCount;
373: }
374:
375: /* (non-Javadoc)
376: * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
377: */
378: public boolean isLeaf(Object node) {
379: if (node instanceof JDefaultMutableTreeNode) {
380: JDefaultMutableTreeNode n = (JDefaultMutableTreeNode) node;
381: Object obj = n.getUserObject();
382: if (obj != null && obj instanceof IPropertyElement) {
383: IPropertyElement ele = (IPropertyElement) obj;
384: IPropertyDefinition pDef = ele.getPropertyDefinition();
385: long mult = pDef.getMultiplicity();
386: String name = ele.getName();
387: Vector subDefs = pDef.getSubDefinitions();
388: int subDefCount = 0;
389: if (subDefs != null) {
390: subDefCount = subDefs.size();
391: }
392: if (mult <= 1) {
393: Vector elems = ele.getSubElements();
394: if (elems == null
395: || (elems != null && elems.size() == 0)) {
396: if (name != null && name.equals("dummy")
397: && subDefCount > 0) {
398: return false;
399: } else {
400: return true;
401: }
402: }
403: }
404: }
405: }
406: return false;
407: }
408:
409: /* (non-Javadoc)
410: * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
411: */
412: public void valueForPathChanged(TreePath path, Object newValue) {
413:
414: }
415:
416: /* (non-Javadoc)
417: * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
418: */
419: public int getIndexOfChild(Object parent, Object child) {
420: for (int i = 0; i < getChildCount(parent); i++) {
421: if (getChild(parent, i).equals(child)) {
422: return i;
423: }
424: }
425: return -1;
426: }
427:
428: /* (non-Javadoc)
429: * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
430: */
431: public void addTreeModelListener(TreeModelListener l) {
432: listenerList.add(TreeModelListener.class, l);
433: }
434:
435: /* (non-Javadoc)
436: * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
437: */
438: public void removeTreeModelListener(TreeModelListener l) {
439: listenerList.remove(TreeModelListener.class, l);
440:
441: }
442:
443: /* (non-Javadoc)
444: * @see javax.swing.tree.TreeModel#getRoot()
445: */
446: public Object getRoot() {
447: return root;
448: }
449:
450: /*
451: * Notify all listeners that have registered interest for
452: * notification on this event type. The event instance
453: * is lazily created using the parameters passed into
454: * the fire method.
455: * @see EventListenerList
456: */
457: protected void fireTreeStructureChanged(Object source,
458: Object[] path, int[] childIndices, Object[] children) {
459: // Guaranteed to return a non-null array
460: Object[] listeners = listenerList.getListenerList();
461: TreeModelEvent e = null;
462: // Process the listeners last to first, notifying
463: // those that are interested in this event
464: for (int i = listeners.length - 2; i >= 0; i -= 2) {
465: if (listeners[i] == TreeModelListener.class) {
466: // Lazily create the event:
467: if (e == null)
468: e = new TreeModelEvent(source, path, childIndices,
469: children);
470: ((TreeModelListener) listeners[i + 1])
471: .treeStructureChanged(e);
472: }
473: }
474: }
475:
476: /*
477: * Notify all listeners that have registered interest for
478: * notification on this event type. The event instance
479: * is lazily created using the parameters passed into
480: * the fire method.
481: * @see EventListenerList
482: */
483: protected void fireTreeNodesChanged(Object source, Object[] path,
484: int[] childIndices, Object[] children) {
485: // Guaranteed to return a non-null array
486: Object[] listeners = listenerList.getListenerList();
487: TreeModelEvent e = null;
488: // Process the listeners last to first, notifying
489: // those that are interested in this event
490: for (int i = listeners.length - 2; i >= 0; i -= 2) {
491: if (listeners[i] == TreeModelListener.class) {
492: // Lazily create the event:
493: if (e == null)
494: e = new TreeModelEvent(source, path, childIndices,
495: children);
496: ((TreeModelListener) listeners[i + 1])
497: .treeNodesChanged(e);
498: }
499: }
500: }
501:
502: /*
503: * Notify all listeners that have registered interest for
504: * notification on this event type. The event instance
505: * is lazily created using the parameters passed into
506: * the fire method.
507: * @see EventListenerList
508: */
509: protected void fireTreeNodesInserted(Object source, Object[] path,
510: int[] childIndices, Object[] children) {
511: // Guaranteed to return a non-null array
512: Object[] listeners = listenerList.getListenerList();
513: TreeModelEvent e = null;
514: // Process the listeners last to first, notifying
515: // those that are interested in this event
516: for (int i = listeners.length - 2; i >= 0; i -= 2) {
517: if (listeners[i] == TreeModelListener.class) {
518: // Lazily create the event:
519: if (e == null)
520: e = new TreeModelEvent(source, path, childIndices,
521: children);
522: ((TreeModelListener) listeners[i + 1])
523: .treeNodesInserted(e);
524: }
525: }
526: }
527:
528: /*
529: * Notify all listeners that have registered interest for
530: * notification on this event type. The event instance
531: * is lazily created using the parameters passed into
532: * the fire method.
533: * @see EventListenerList
534: */
535: protected void fireTreeNodesRemoved(Object source, Object[] path,
536: int[] childIndices, Object[] children) {
537: // Guaranteed to return a non-null array
538: Object[] listeners = listenerList.getListenerList();
539: TreeModelEvent e = null;
540: // Process the listeners last to first, notifying
541: // those that are interested in this event
542: for (int i = listeners.length - 2; i >= 0; i -= 2) {
543: if (listeners[i] == TreeModelListener.class) {
544: // Lazily create the event:
545: if (e == null)
546: e = new TreeModelEvent(source, path, childIndices,
547: children);
548: ((TreeModelListener) listeners[i + 1])
549: .treeNodesRemoved(e);
550: }
551: }
552: }
553:
554: public void expand(int row, boolean val) {
555: treeTable.getTree().expandNode(row, val);
556:
557: }
558:
559: public void setTreeTable(JTreeTable tree) {
560: treeTable = tree;
561: }
562:
563: public Vector<Icon> getIcons() {
564: return m_Icons;
565: }
566:
567: public void setEditingComponent(Object obj) {
568: if (obj == null && m_EditableComponent != null) {
569: try {
570: ((Component) m_EditableComponent).removeNotify();
571: } catch (Exception e) {
572: //do nothing, removeNotify is throwing at times.
573: }
574: } else {
575: m_EditableComponent = obj;
576: }
577: }
578:
579: public Object getEditingComponent() {
580: return m_EditableComponent;
581: }
582:
583: }
|