source: branches/2.2/jabberit_messenger/java_source/src/nu/fw/jeti/util/TreeModelFilter.java @ 3102

Revision 3102, 8.0 KB checked in by amuller, 14 years ago (diff)

Ticket #986 - Efetuado merge para o Branch 2.2( atualizacao do modulo)

  • Property svn:executable set to *
Line 
1package nu.fw.jeti.util;
2
3import java.util.ArrayList;
4import java.util.Hashtable;
5import java.util.LinkedList;
6
7import javax.swing.event.TreeModelEvent;
8import javax.swing.event.TreeModelListener;
9import javax.swing.tree.TreeModel;
10import javax.swing.tree.TreePath;
11
12/**
13 * Used to filter some nodes from a tree. That is nodes which the
14 * selector decides not to show does not seem to exist in the tree.
15 * The selector is assumed to not change behavior over time.
16 *
17 * @author Martin Forssen
18 */
19
20public class TreeModelFilter implements TreeModel, TreeModelListener {
21    private TreeModelSelector selector;
22    private TreeModel model;
23    private LinkedList listeners = new LinkedList();
24    private Hashtable nodes = new Hashtable(30);
25
26    public TreeModelFilter(TreeModel model, TreeModelSelector selector) {
27        this.model = model;
28        this.selector = selector;
29
30        model.addTreeModelListener(this);
31    }
32
33    /*
34     * TreeModel interface
35     */
36    public Object getRoot() {
37        return model.getRoot();
38    }
39
40    public Object getChild(Object parent, int index) {
41        int max = model.getChildCount(parent);
42        for (int i=0, v=0; i<max; i++) {
43            Object child = model.getChild(parent, i);
44            boolean isVisible = selector.isVisible(child);
45            nodes.put(child, Boolean.valueOf(isVisible));
46            if (isVisible && index == v++) {
47                return child;
48            }
49        }
50        return null;
51    }
52
53    public int getChildCount(Object parent) {
54        int max = model.getChildCount(parent);
55        int count = 0;
56
57        for (int i=0; i<max; i++) {
58            Object child = model.getChild(parent, i);
59            boolean isVisible = selector.isVisible(child);
60            nodes.put(child,Boolean.valueOf(isVisible));
61            if (isVisible) {
62                count++;
63            }
64        }
65        return count;
66    }
67
68    public boolean isLeaf(Object node) {
69        return model.isLeaf(node);
70    }
71
72    public void valueForPathChanged(TreePath path, Object newValue) {
73        // TODO
74    }
75
76    public int getIndexOfChild(Object parent, Object child) {
77        int max = model.getChildCount(parent);
78        for (int i=0, v=0; i<max; i++) {
79            Object mChild = model.getChild(parent, i);
80            if (mChild.equals(child)) {
81                return v;
82            }
83            if (selector.isVisible(child)) {
84                v++;
85            }
86        }
87        return -1;
88    }
89
90    public void addTreeModelListener(TreeModelListener l) {
91        listeners.add(l);
92    }
93
94    public void removeTreeModelListener(TreeModelListener l) {
95        listeners.remove(l);
96    }
97
98    /*
99     * TreeModelListener interface
100     */
101    public void treeNodesChanged(TreeModelEvent e) {
102        int indices[] = e.getChildIndices();
103        Object children[] = e.getChildren();
104
105        if (indices == null || indices.length == 0) {
106            TreeModelEvent e2 = new TreeModelEvent(this, e.getTreePath());
107            for (int i = 0; i < listeners.size(); i++) {
108                ((TreeModelListener)listeners.get(i)).treeNodesChanged(e2);
109            }
110        } else {
111            for (int i=0, v=0; i < indices.length; i++) {
112                nodeChanged(e.getTreePath(), indices[i], children[i]);
113            }
114        }
115    }
116
117    public void treeNodesInserted(TreeModelEvent e) {
118        ArrayList newIndices = new ArrayList();
119        ArrayList newChildren = new ArrayList();
120        Object parent = e.getTreePath().getLastPathComponent();
121        int indices[] = e.getChildIndices();
122        Object children[] = e.getChildren();
123       
124        for (int i=0, v=0; i < indices.length; i++) {
125            boolean vis = selector.isVisible(children[i]);
126            nodes.put(children[i], Boolean.valueOf(vis));
127            if (vis) {
128                newIndices.add(new Integer(upperIndex(parent, indices[i])));
129                newChildren.add(children[i]);
130            }
131        }
132        if (newIndices.size() > 0) {
133            TreeModelEvent e2 = createEvent(e.getTreePath(), newIndices,
134                                            newChildren);
135            for (int i = 0; i < listeners.size(); i++) {
136                ((TreeModelListener)listeners.get(i)).treeNodesInserted(e2);
137            }
138        }
139    }
140
141    public void treeNodesRemoved(TreeModelEvent e) {
142        ArrayList newIndices = new ArrayList();
143        ArrayList newChildren = new ArrayList();
144        Object parent = e.getTreePath().getLastPathComponent();
145        int indices[] = e.getChildIndices();
146        Object children[] = e.getChildren();
147       
148        for (int i=0, v=0; i < indices.length; i++) {
149            Boolean visible = (Boolean)nodes.get(children[i]);
150            if (visible != null && visible.booleanValue()) {
151                newIndices.add(new Integer(upperIndex(parent, indices[i])));
152                newChildren.add(children[i]);
153            }
154            nodes.remove(children[i]);
155        }
156
157        if (newIndices.size() > 0) {
158            TreeModelEvent e2 = createEvent(e.getTreePath(), newIndices,
159                                            newChildren);
160            for (int i = 0; i < listeners.size(); i++) {
161                ((TreeModelListener)listeners.get(i)).treeNodesRemoved(e2);
162            }
163        }
164    }
165
166    public void treeStructureChanged(TreeModelEvent e) {
167        TreePath path = e.getTreePath();
168        Object node = path.getLastPathComponent();
169        nodes.put(node, Boolean.valueOf(selector.isVisible(node)));
170        if (path.getPathCount() > 1) {
171            path = path.getParentPath();
172        }
173        TreeModelEvent e2 = new TreeModelEvent(this, path);
174        for (int i = 0; i < listeners.size(); i++) {
175            ((TreeModelListener)listeners.get(i)).treeStructureChanged(e2);
176        }
177    }
178
179    private TreeModelEvent createEvent(TreePath path,
180                                       ArrayList indices,
181                                       ArrayList children) {
182        int intIndices[] = new int[indices.size()];
183        for (int i=0; i<indices.size(); i++) {
184            intIndices[i] = ((Integer)indices.get(i)).intValue();
185        }
186        return new TreeModelEvent(
187            this, path, intIndices,
188            children.toArray(new Object[children.size()]));
189    }
190
191    private int upperIndex(Object parent, int index) {
192        int vIndex = 0;
193        for (int i=0; i < index; i++) {
194            if (selector.isVisible(model.getChild(parent, i))) {
195                vIndex++;
196            }
197        }
198        return vIndex;
199    }
200
201    private void nodeChanged(TreePath path, int index, Object node) {
202        Object parent = path.getLastPathComponent();
203
204        boolean newVis = selector.isVisible(node);
205        Boolean oldVis = (Boolean)nodes.get(node);
206        if (newVis && (oldVis == null || !oldVis.booleanValue())) {
207            int indices[] = {upperIndex(parent, index)};
208            Object children[] = {node};
209            TreeModelEvent e = new TreeModelEvent(this, path,indices,children);
210            for (int i = 0; i < listeners.size(); i++) {
211                ((TreeModelListener)listeners.get(i)).treeNodesInserted(e);
212            }
213        } else if (!newVis && oldVis != null && oldVis.booleanValue()) {
214            int indices[] = {upperIndex(parent, index)};
215            Object children[] = {node};
216            TreeModelEvent e = new TreeModelEvent(this, path,indices,children);
217            for (int i = 0; i < listeners.size(); i++) {
218                ((TreeModelListener)listeners.get(i)).treeNodesRemoved(e);
219            }
220        } else if (newVis && oldVis != null && oldVis.booleanValue()) {
221            int vIndex = upperIndex(path.getLastPathComponent(), index);
222            TreeModelEvent e = new TreeModelEvent(this, path,
223                                                  new int[] {vIndex},
224                                                  new Object[] {node});
225            for (int i = 0; i < listeners.size(); i++) {
226                ((TreeModelListener)listeners.get(i)).treeNodesChanged(e);
227            }
228        }
229        nodes.put(node, Boolean.valueOf(newVis));
230    }
231}
232
233/*
234 * Overrides for emacs
235 * Local variables:
236 * tab-width: 4
237 * End:
238 */
Note: See TracBrowser for help on using the repository browser.