1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.grinder.console.swingui;
23
24 import java.io.File;
25
26 import javax.swing.event.EventListenerList;
27 import javax.swing.event.TreeModelEvent;
28 import javax.swing.event.TreeModelListener;
29 import javax.swing.tree.TreeModel;
30 import javax.swing.tree.TreePath;
31
32 import net.grinder.console.editor.Buffer;
33 import net.grinder.console.editor.EditorModel;
34 import net.grinder.util.WeakValueHashMap;
35
36
37
38
39
40
41
42 final class BufferTreeModel implements TreeModel {
43
44 private final EditorModel m_editorModel;
45
46 private final Object m_rootNode = new Object();
47 private final EventListenerList m_listeners = new EventListenerList();
48 private final WeakValueHashMap<Buffer, BufferNode> m_buffersToNodes =
49 new WeakValueHashMap<Buffer, BufferNode>();
50
51 private BufferNode[] m_bufferNodes = new BufferNode[0];
52
53 BufferTreeModel(EditorModel editorModel) {
54
55 m_editorModel = editorModel;
56
57 m_editorModel.addListener(new EditorModel.AbstractListener() {
58
59 public void bufferAdded(Buffer buffer) {
60 bufferListChanged();
61 }
62
63 public void bufferRemoved(Buffer buffer) {
64 bufferListChanged();
65 }
66 });
67
68 bufferListChanged();
69 }
70
71 private void bufferListChanged() {
72 final Buffer[] buffers = m_editorModel.getBuffers();
73 m_bufferNodes = new BufferNode[buffers.length];
74
75 m_buffersToNodes.clear();
76
77 for (int i = 0; i < buffers.length; ++i) {
78 m_bufferNodes[i] = new BufferNode(buffers[i]);
79 m_buffersToNodes.put(buffers[i], m_bufferNodes[i]);
80 }
81
82 fireTreeStructureChanged();
83 }
84
85 public Object getRoot() {
86 return m_rootNode;
87 }
88
89 public Object getChild(Object parent, int index) {
90
91 if (parent.equals(getRoot())) {
92 if (index >= 0 && index < m_bufferNodes.length) {
93 return m_bufferNodes[index];
94 }
95 }
96
97 return null;
98 }
99
100 public int getChildCount(Object parent) {
101
102 if (parent.equals(getRoot())) {
103 return m_bufferNodes.length;
104 }
105
106 return 0;
107 }
108
109 public int getIndexOfChild(Object parent, Object child) {
110
111 if (parent == null || child == null) {
112
113 return -1;
114 }
115
116 if (parent.equals(getRoot())) {
117 for (int i = 0; i < m_bufferNodes.length; ++i) {
118 if (child.equals(m_bufferNodes[i])) {
119 return i;
120 }
121 }
122 }
123
124 return -1;
125 }
126
127 public boolean isLeaf(Object node) {
128 if (node instanceof BufferNode) {
129 final BufferNode bufferNode = (BufferNode)node;
130
131 if (bufferNode.belongsToModel(this)) {
132 return true;
133 }
134 }
135
136 return false;
137 }
138
139 public void addTreeModelListener(TreeModelListener listener) {
140 m_listeners.add(TreeModelListener.class, listener);
141 }
142
143 public void removeTreeModelListener(TreeModelListener listener) {
144 m_listeners.remove(TreeModelListener.class, listener);
145 }
146
147 private void fireTreeStructureChanged() {
148 final Object[] listeners = m_listeners.getListenerList();
149
150 final TreeModelEvent event =
151 new TreeModelEvent(this, new Object[] { getRoot() });
152
153 for (int i = listeners.length - 2; i >= 0; i -= 2) {
154 ((TreeModelListener)listeners[i + 1]).treeStructureChanged(event);
155 }
156 }
157
158 private void fireTreeNodesChanged(TreePath path) {
159 final Object[] listeners = m_listeners.getListenerList();
160
161 final TreeModelEvent event = new TreeModelEvent(this, path);
162
163 for (int i = listeners.length - 2; i >= 0; i -= 2) {
164 ((TreeModelListener)listeners[i + 1]).treeNodesChanged(event);
165 }
166 }
167
168 public void valueForPathChanged(TreePath path, Object newValue) {
169 fireTreeNodesChanged(path);
170 }
171
172 public void bufferChanged(Buffer buffer) {
173
174 final BufferTreeModel.BufferNode node = m_buffersToNodes.get(buffer);
175
176 if (node != null) {
177 valueForPathChanged(node.getPath(), node);
178 }
179 }
180
181
182
183
184 public final class BufferNode implements FileTree.Node {
185
186 private final Buffer m_buffer;
187 private final TreePath m_path;
188
189 protected BufferNode(Buffer buffer) {
190 m_buffer = buffer;
191 m_path = new TreePath(new Object[] { getRoot(), this });
192 }
193
194 public String toString() {
195 return m_buffer.getDisplayName();
196 }
197
198 public Buffer getBuffer() {
199 return m_buffer;
200 }
201
202 public TreePath getPath() {
203 return m_path;
204 }
205
206 public File getFile() {
207 return getBuffer().getFile();
208 }
209
210 public boolean canOpen() {
211 return true;
212 }
213
214 boolean belongsToModel(BufferTreeModel model) {
215 return BufferTreeModel.this == model;
216 }
217 }
218 }