1 package xdoclet.gui;
2
3 import xdoclet.beans.BeanContextSupportEx;
4
5 import javax.swing.event.EventListenerList;
6 import javax.swing.event.TreeModelEvent;
7 import javax.swing.event.TreeModelListener;
8 import javax.swing.tree.TreeModel;
9 import javax.swing.tree.TreePath;
10
11 import java.beans.beancontext.BeanContext;
12 import java.beans.beancontext.BeanContextMembershipEvent;
13 import java.beans.beancontext.BeanContextMembershipListener;
14
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.EventListener;
19
20 /***
21 * This is a TreeModel for BeanContexts modeled after Swing's {@link TreeModel}
22 * interface. It can also be used to populate an Eclipse Tree.
23 *
24 * @author <a href="mailto:aslak.hellesoy at bekk.no">Aslak Hellesøy</a>
25 * @version $Revision: 1.7 $
26 */
27 public class BeanContextTreeModel implements TreeModel, BeanContextMembershipListener {
28 private final BeanContextSupportEx _root;
29 private EventListenerList _listenerList = new EventListenerList();
30
31 private static final int INSERT = 0;
32 private static final int CHANGE = 1;
33 private static final int REMOVE = 2;
34
35 public BeanContextTreeModel(BeanContextSupportEx root) {
36 _root = root;
37
38 // We want to be notified when the content of a node changes,
39 // so we can notify our own listeners (typically JTrees).
40 listenForBeanContextMembershipEvents(root);
41 }
42
43 public Object getRoot() {
44 return _root;
45 }
46
47 public Object getChild(Object parent, int index) {
48 return new ArrayList((BeanContext) parent).get(index);
49 }
50
51 public int getChildCount(Object parent) {
52 if (parent instanceof BeanContext) {
53 return ((BeanContext) parent).size();
54 } else {
55 return 0;
56 }
57 }
58
59 public boolean isLeaf(Object node) {
60 return getChildCount(node) == 0;
61 }
62
63 public void valueForPathChanged(TreePath path, Object newValue) {
64 }
65
66 public int getIndexOfChild(Object parent, Object child) {
67 return new ArrayList((BeanContext) parent).indexOf(child);
68 }
69
70 public void addTreeModelListener(TreeModelListener l) {
71 _listenerList.add(TreeModelListener.class, l);
72 }
73
74 public void removeTreeModelListener(TreeModelListener l) {
75 _listenerList.remove(TreeModelListener.class, l);
76 }
77
78 private void fireTreeModelEvent(Object source, Object[] path, int[] childIndices, Object[] children, int eventType) {
79 TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children);
80 EventListener[] listeners = _listenerList.getListeners(TreeModelListener.class);
81
82 // Process the listeners last to first, notifying
83 // those that are interested in this event
84 for (int i = listeners.length - 1; i >= 0; i--) {
85 switch( eventType ) {
86 case INSERT:
87 ((TreeModelListener) listeners[i]).treeNodesInserted(e);
88 break;
89 case CHANGE:
90 ((TreeModelListener) listeners[i]).treeNodesChanged(e);
91 break;
92 case REMOVE:
93 ((TreeModelListener) listeners[i]).treeNodesRemoved(e);
94 break;
95 }
96 }
97 }
98
99 public BeanContextSupportEx[] getPathToRoot(BeanContextSupportEx aNode) {
100 return getPathToRoot(aNode, 0);
101 }
102
103 private BeanContextSupportEx[] getPathToRoot(BeanContextSupportEx aNode, int depth) {
104 BeanContextSupportEx[] retNodes;
105
106 // This method recurses, traversing towards the root in order
107 // size the array. On the way back, it fills in the nodes,
108 // starting from the root and working back to the original node.
109
110 /* Check for null, in case someone passed in a null node, or
111 they passed in an element that isn't rooted at root. */
112 if (aNode == null) {
113 if (depth == 0) {
114 return null;
115 } else {
116 retNodes = new BeanContextSupportEx[depth];
117 }
118 } else {
119 depth++;
120
121 if (aNode == getRoot()) {
122 retNodes = new BeanContextSupportEx[depth];
123 } else {
124 retNodes = getPathToRoot(aNode.getParent(), depth);
125 }
126
127 retNodes[retNodes.length - depth] = aNode;
128 }
129
130 return retNodes;
131 }
132
133 private void childrenChanged(BeanContextMembershipEvent bcme, int type) {
134 // Make a List out of the source bean context so that
135 // we can find indices.
136 List beanContextList = new ArrayList(bcme.getBeanContext());
137
138 Object[] added = bcme.toArray();
139 int[] indices = new int[added.length];
140
141 for (int i = 0; i < indices.length; i++) {
142 indices[i] = beanContextList.indexOf(added[i]);
143
144 if (added[i] instanceof BeanContextSupportEx) {
145 listenForBeanContextMembershipEvents((BeanContextSupportEx) added[i]);
146 }
147 }
148
149 fireTreeModelEvent(this, getPathToRoot((BeanContextSupportEx) bcme.getBeanContext()), indices, added, type);
150 }
151
152 public void childrenAdded(BeanContextMembershipEvent bcme) {
153 childrenChanged(bcme, INSERT);
154 }
155
156 public void childrenRemoved(BeanContextMembershipEvent bcme) {
157 childrenChanged(bcme, REMOVE);
158 }
159
160 /***
161 * Adds ourself as BeanContextMembershipListener to bean and recursively
162 * to all its children.
163 * @param bean the bean to listen to.
164 */
165 private void listenForBeanContextMembershipEvents(BeanContextSupportEx bean) {
166 bean.addBeanContextMembershipListener(this);
167
168 for (Iterator children = bean.iterator(); children.hasNext();) {
169 Object child = children.next();
170
171 if (child instanceof BeanContextSupportEx) {
172 BeanContextSupportEx beanContextChild = (BeanContextSupportEx) child;
173
174 listenForBeanContextMembershipEvents(beanContextChild);
175 }
176 }
177 }
178 }
This page was automatically generated by Maven