View Javadoc

1   /*
2      Copyright 2002-2006 Martin van den Bemt
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16  package org.xulux.guilayer.swing.models;
17  
18  import java.util.ArrayList;
19  import java.util.Stack;
20  
21  import javax.swing.event.TreeModelEvent;
22  import javax.swing.event.TreeModelListener;
23  import javax.swing.tree.TreeModel;
24  import javax.swing.tree.TreePath;
25  
26  import org.xulux.api.dataprovider.IContentHandler;
27  import org.xulux.dataprovider.contenthandlers.ContentView;
28  import org.xulux.dataprovider.contenthandlers.TreeContentHandler;
29  
30  /**
31   * A cutom tree root, so we can do magic of our own
32   *
33   * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
34   * @version $Id: SwingTreeModel.java,v 1.1 2005/12/18 12:58:21 mvdb Exp $
35   */
36  public class SwingTreeModel extends TreeContentHandler implements TreeModel {
37  
38      /**
39       * the contenthandler
40       */
41      private TreeContentHandler contentHandler;
42      /**
43       * the listenerlist
44       */
45      private ArrayList listenerList;
46      /**
47       * @param contentHandler the tree contentHandler to use..
48       */
49      public SwingTreeModel(TreeContentHandler contentHandler) {
50          this.contentHandler = contentHandler;
51      }
52  
53      /**
54       * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
55       */
56      public void addTreeModelListener(TreeModelListener l) {
57          if (listenerList == null) {
58              listenerList = new ArrayList();
59          }
60          listenerList.add(l);
61      }
62  
63      /**
64       * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
65       */
66      public Object getChild(Object parent, int index) {
67          return contentHandler.getChild(parent, index);
68      }
69  
70      /**
71       * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
72       */
73      public int getChildCount(Object parent) {
74          if (contentHandler == null) {
75              return 0;
76          }
77          return contentHandler.getChildCount(parent);
78      }
79  
80      /**
81       * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
82       */
83      public int getIndexOfChild(Object parent, Object child) {
84          return contentHandler.getIndexOfChild(parent, child);
85      }
86  
87      /**
88       * @see javax.swing.tree.TreeModel#getRoot()
89       */
90      public Object getRoot() {
91          if (contentHandler == null || contentHandler.getRoot() == null) {
92              return "NULLROOT";
93          }
94          return contentHandler.getRoot();
95      }
96  
97      /**
98       * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
99       */
100     public boolean isLeaf(Object node) {
101         //System.out.println("contentHandler :" +contentHandler);
102         if (contentHandler != null) {
103             return contentHandler.isLeaf(node);
104         }
105         return false;
106     }
107 
108     /**
109      * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
110      */
111     public void removeTreeModelListener(TreeModelListener l) {
112         if (listenerList != null) {
113             listenerList.remove(l);
114         }
115     }
116     
117     /**
118      * The treepath stack, which is used to find the treepath
119      * of the specified value
120      */
121     private Stack tpStack;
122 
123     /**
124      * @param value the value to find the treepath for
125      * @return the treepath or null if the value is not found in the content.
126      */
127     public TreePath getTreePath(Object value) {
128           tpStack = new Stack();
129           Object root = getRoot();
130           tpStack.push(root);
131           if (value.equals(root)) {
132               return new TreePath(tpStack.toArray());
133           }
134           walkTree(root, value);
135           TreePath tp = null;
136           if (tpStack != null && tpStack.size() > 0) {
137               tp = new TreePath(tpStack.toArray());
138           }
139           tpStack = null;
140           return tp;
141     }
142     
143     /**
144      * Walk the tree
145      * @param treeItem the treeItem to work with
146      * @param value the value to find
147      */
148     private void walkTree(Object treeItem, Object value) {
149         // if the last entry was a hit, return..
150         Object peekObject = tpStack.peek();
151         if (peekObject instanceof ContentView) {
152             if (((ContentView)peekObject).getSource().equals(value)) {
153                 return;
154             }
155         } else if (peekObject.equals(value)) {
156                 return;
157         }
158         Object parent = peekObject;
159         int childCount = getChildCount(parent);
160         for (int i = 0; i < childCount; i++) {
161             Object child = getChild(parent, i);
162             tpStack.push(child);
163             if (child instanceof ContentView) {
164                 if (((ContentView) child).getSource().equals(value)) {
165                     return;
166                 }
167             }
168             if (child.equals(value)) {
169                 return;
170             }
171             walkTree(child, value);
172         }
173         // if the last entry was not a hit, remove the last from the stack..
174         peekObject = tpStack.peek();
175         if (peekObject instanceof ContentView) {
176             if (!((ContentView)peekObject).getSource().equals(value)) {
177                 tpStack.pop();
178             }
179         } else if (!peekObject.equals(value)) {
180                 tpStack.pop();
181         }
182     }
183     
184     /**
185      * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
186      */
187     public void valueForPathChanged(TreePath path, Object newValue) {
188 
189     }
190 
191     /**
192      * @see org.xulux.nyx.global.IContentHandler#getType()
193      */
194     public Class getType() {
195         return null;
196     }
197 
198     /**
199      * @see org.xulux.nyx.global.contenthandlers.TreeContentHandler#refresh()
200      */
201     public void refresh() {
202         if (listenerList == null) {
203             return;
204         }
205         TreeModelEvent event = null;
206         for (int i = listenerList.size() - 1; i >= 0; i--) {
207             Object listener = listenerList.get(i);
208             if (listener instanceof TreeModelListener) {
209                 if (event == null) {
210                     event = new TreeModelEvent(this, new TreePath(getRoot()));
211                 }
212                 ((TreeModelListener) listener).treeStructureChanged(event);
213             }
214         }
215     }
216     /**
217      * @return the embedded contenthandler.
218      */
219     public IContentHandler getInnerContentHandler() {
220         return this.contentHandler;
221     }
222 
223 }