View Javadoc

1   // Copyright 2004-2005, FreeHEP.
2   package hep.wired.util;
3   
4   import java.util.*;
5   import javax.swing.*;
6   import javax.swing.event.*;
7   import javax.swing.tree.*;
8   
9   /***
10   * TreeModel for TriStates.
11   *
12   * @author Mark Donszelmann
13   * @version $Id: TristateTreeModel.java 672 2005-03-08 00:16:11Z duns $
14   */
15  public class TristateTreeModel implements TreeModel, TreeModelListener {
16  
17      protected List treeModelListeners = new ArrayList();
18      protected TreeModel model;
19      protected TristateTreeNode root;
20  
21      public TristateTreeModel() {
22          this(null);
23      }
24  
25      public TristateTreeModel(TreeModel model) {
26          root = null;
27          setModel(model);
28      }
29      
30      public void setModel(TreeModel newModel) {
31          if (model != null) {
32              model.removeTreeModelListener(this);
33          }
34          model = newModel;
35          if (model != null) {
36              model.addTreeModelListener(this);
37          }
38          // NOTE: force a new setting of root
39          root = null;
40          root = (TristateTreeNode)getRoot();
41          fireTreeStructureChanged();
42      }
43  
44      // Delegated from tree
45      public String convertValueToText(Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
46          return value != null ? value.toString() : "null";
47      } 
48      
49      protected void checkForChildren(TristateTreeNode parent, TreeModel model, boolean recursive) {
50          Object modelParent = parent.getUserObject();
51          int n = model.getChildCount(modelParent);
52          if (parent.getChildCount() != n) {
53              for (int i=0; i<n; i++) {
54                  TristateTreeNode child = createTreeNode(model.getChild(modelParent, i));
55                  parent.add(child);
56                  if (recursive) checkForChildren(child, model, recursive);
57              }
58          }
59      }
60  
61      protected TristateTreeNode createTreeNode(Object modelNode) {
62          return new DefaultTristateTreeNode(modelNode);
63      }
64      
65      public Set/*<Object>*/ getSelectedSet(Class type) {
66          return getSelectedSet(type, Integer.MAX_VALUE);
67      }
68      
69      public Set/*<Object>*/ getSelectedSet(Class type, int maxLevel) {
70          Set set = new HashSet();
71          TristateTreeNode node = (TristateTreeNode)getRoot();
72          if ((node != null) && (node.getState() != TristateCheckBox.NOT_SELECTED)) {
73              addSelected(set, node, type, Math.max(maxLevel, maxLevel+2));
74          }
75          return set;
76      }
77  
78      private void addSelected(Set/*<Object>*/ set, TristateTreeNode node, Class type, int level) {
79          if (level <= 0) return;
80          if (node.isSelected()) {
81              Object object = node.getUserObject();
82              if ((type == null) || type.isAssignableFrom(object.getClass())) {
83                  set.add(object);
84              }
85          }
86          int n = getChildCount(node);
87          for (int i=0; i<n; i++) {
88              TristateTreeNode child = (TristateTreeNode)getChild(node, i);
89              if (child.getState() != TristateCheckBox.NOT_SELECTED) {
90                  addSelected(set, child, type, level-1);
91              }
92          }
93      }
94      
95  // TreeModelListener
96      public Object getRoot() {
97          if ((root == null) && (model != null) && (model.getRoot() != null)) {
98              root = new DefaultTristateTreeNode(model.getRoot());
99              checkForChildren(root, model, true);
100         }
101         return root;
102     }
103 
104     public Object getChild(Object parent, int index) {
105         return ((TristateTreeNode)parent).getChildAt(index);
106     }
107                            
108     public int getChildCount(Object parent) {
109         return ((TristateTreeNode)parent).getChildCount(); 
110     }
111     
112     public boolean isLeaf(Object node) {
113         return getChildCount(node) == 0;
114     }
115 
116     public void valueForPathChanged(TreePath path, Object newValue) {
117         // FIXME, WIRED-390 maybe newvalue needs converting
118         if (model != null) model.valueForPathChanged(path, newValue);
119         treeNodesChanged(new TreeModelEvent(this, path));
120     }
121 
122     public int getIndexOfChild(Object parent, Object child) {
123         if ((parent instanceof TreeNode) && (child instanceof TreeNode)) {
124             return ((TreeNode)parent).getIndex((TreeNode)child);
125         }
126         return -1;
127     }
128     
129     public void addTreeModelListener(TreeModelListener l) {
130         treeModelListeners.add(l);
131     }
132 
133     public void removeTreeModelListener(TreeModelListener l) {
134         treeModelListeners.remove(l);
135     }   
136 
137     public void fireTreeStructureChanged() {
138         if (root == null) return;
139         
140         TreeModelEvent e = new TreeModelEvent(this, new Object[] { root } );
141         for (Iterator i=treeModelListeners.iterator(); i.hasNext(); ) {
142             ((TreeModelListener)i.next()).treeStructureChanged(e);
143         }
144     }
145 
146 // TreeModelListener
147     public void treeNodesChanged(TreeModelEvent e) {
148         for (Iterator i=treeModelListeners.iterator(); i.hasNext(); ) {
149             ((TreeModelListener)i.next()).treeNodesChanged(e);
150         }
151     }
152 
153     public void treeNodesInserted(TreeModelEvent e) {
154         // FIXME, WIRED-390 check if we need to recreate/modify the tree
155         for (Iterator i=treeModelListeners.iterator(); i.hasNext(); ) {
156             ((TreeModelListener)i.next()).treeNodesInserted(e);
157         }
158     }
159     
160     public void treeNodesRemoved(TreeModelEvent e) {
161         // FIXME, WIRED-390 check if we need to recreate/modify the tree
162         for (Iterator i=treeModelListeners.iterator(); i.hasNext(); ) {
163             ((TreeModelListener)i.next()).treeNodesRemoved(e);
164         }
165     }   
166 
167     public void treeStructureChanged(TreeModelEvent e) {
168         // FIXME, WIRED-390 check if we want to do this...
169         root = null;
170         for (Iterator i=treeModelListeners.iterator(); i.hasNext(); ) {
171             ((TreeModelListener)i.next()).treeStructureChanged(e);
172         }
173     }
174 }