File Source: TreeFrameManager.java
/*
P/P * Method: com.dmdirc.addons.ui_swing.framemanager.tree.TreeFrameManager__static_init
*/
1 /*
2 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22 package com.dmdirc.addons.ui_swing.framemanager.tree;
23
24 import com.dmdirc.FrameContainer;
25 import com.dmdirc.config.IdentityManager;
26 import com.dmdirc.interfaces.ConfigChangeListener;
27 import com.dmdirc.interfaces.IconChangeListener;
28 import com.dmdirc.interfaces.NotificationListener;
29 import com.dmdirc.interfaces.SelectionListener;
30 import com.dmdirc.logger.ErrorLevel;
31 import com.dmdirc.logger.Logger;
32 import com.dmdirc.ui.interfaces.FrameManager;
33 import com.dmdirc.ui.interfaces.Window;
34 import com.dmdirc.addons.ui_swing.UIUtilities;
35
36 import java.awt.Color;
37 import java.awt.Rectangle;
38 import java.awt.event.AdjustmentEvent;
39 import java.awt.event.AdjustmentListener;
40 import java.awt.event.MouseEvent;
41 import java.io.Serializable;
42 import java.util.Collection;
43 import java.util.HashMap;
44 import java.util.Map;
45
46 import javax.swing.Icon;
47 import javax.swing.JComponent;
48 import javax.swing.JScrollBar;
49 import javax.swing.JScrollPane;
50 import javax.swing.JTree;
51 import javax.swing.SwingUtilities;
52 import javax.swing.tree.DefaultMutableTreeNode;
53 import javax.swing.tree.DefaultTreeModel;
54 import javax.swing.tree.TreeNode;
55 import javax.swing.tree.TreePath;
56
57 import net.miginfocom.swing.MigLayout;
58
59 /**
60 * Manages open windows in the application in a tree style view.
61 */
/*
P/P * Method: TreeViewModel access$300(TreeFrameManager)
*
* Preconditions:
* x0 != null
*
* Postconditions:
* return_value == x0.model
* init'ed(return_value)
*/
62 public final class TreeFrameManager implements FrameManager,
63 AdjustmentListener, Serializable,
64 ConfigChangeListener, SelectionListener,
65 NotificationListener, IconChangeListener {
66
67 /**
68 * A version number for this class. It should be changed whenever the class
69 * structure is changed (or anything else that would prevent serialized
70 * objects being unserialized with the new class).
71 */
72 private static final long serialVersionUID = 5;
73 /** display tree. */
74 private final Tree tree;
75 /** data model. */
76 private final TreeViewModel model;
77 /** node storage, used for adding and deleting nodes correctly. */
78 private final Map<FrameContainer, TreeViewNode> nodes;
79
80 /** creates a new instance of the TreeFrameManager. */
/*
P/P * Method: void com.dmdirc.addons.ui_swing.framemanager.tree.TreeFrameManager()
*
* Preconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
*
* Presumptions:
* getGlobalConfig(...).listeners != null
*
* Postconditions:
* com/dmdirc/config/IdentityManager.globalconfig != null
* java.lang.StringBuilder:toString(...)._tainted == 0
* new ArrayList(getSources#1) num objects == 0
* new ConfigManager(getGlobalConfig#1) num objects == 0
* new MapList(ConfigManager#1) num objects == 0
* this.model == &new TreeViewModel(TreeFrameManager#2)
* this.nodes == &new HashMap(TreeFrameManager#1)
* this.tree == &new Tree(TreeFrameManager#4)
* not_init'ed(new ConfigManager(getGlobalConfig#1).channel)
* init'ed(new ConfigManager(getGlobalConfig#1).channel)
* ...
*/
81 public TreeFrameManager() {
82 nodes = new HashMap<FrameContainer, TreeViewNode>();
83 model = new TreeViewModel(new TreeViewNode(null, null));
84 tree = new Tree(this, model);
85
86 tree.setCellRenderer(new TreeViewTreeCellRenderer(this));
87 tree.setVisible(true);
88
89 IdentityManager.getGlobalConfig().addChangeListener("treeview", this);
90 IdentityManager.getGlobalConfig().addChangeListener("ui",
91 "backgroundcolour", this);
92 IdentityManager.getGlobalConfig().addChangeListener("ui",
93 "foregroundcolour", this);
94 }
95
96 /** {@inheritDoc} */
97 @Override
98 public boolean canPositionVertically() {
/*
P/P * Method: bool canPositionVertically()
*
* Postconditions:
* return_value == 1
*/
99 return true;
100 }
101
102 /** {@inheritDoc} */
103 @Override
104 public boolean canPositionHorizontally() {
/*
P/P * Method: bool canPositionHorizontally()
*
* Postconditions:
* return_value == 0
*/
105 return false;
106 }
107
108 /** {@inheritDoc} */
109 @Override
110 public void setParent(final JComponent parent) {
/*
P/P * Method: void setParent(JComponent)
*/
111 SwingUtilities.invokeLater(new Runnable() {
112
113 /** {@inheritDoc} */
114 @Override
115 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* this.tree != null
* this.val$parent != null
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
*
* Presumptions:
* javax.swing.JScrollPane:getHorizontalScrollBar(...)@119 != null
*
* Postconditions:
* com/dmdirc/config/IdentityManager.globalconfig != null
* java.lang.StringBuilder:toString(...)._tainted == 0
* new ArrayList(getSources#1) num objects == 0
* new ConfigManager(getGlobalConfig#1) num objects == 0
* new MapList(ConfigManager#1) num objects == 0
* init'ed(new ConfigManager(getGlobalConfig#1).channel)
* init'ed(new ConfigManager(getGlobalConfig#1).file)
* init'ed(new ConfigManager(getGlobalConfig#1).ircd)
* init'ed(new ConfigManager(getGlobalConfig#1).listeners)
* init'ed(new ConfigManager(getGlobalConfig#1).network)
* ...
*/
116 final JScrollPane scrollPane = new JScrollPane(tree);
117 scrollPane.setAutoscrolls(true);
118 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
119 scrollPane.getHorizontalScrollBar().addAdjustmentListener(TreeFrameManager.this);
120
121 parent.setLayout(new MigLayout("ins 0, fill"));
122 parent.add(scrollPane, "grow");
123 parent.setFocusable(false);
124
125 setColours();
126 }
127 });
128 }
129
130 /** {@inheritDoc} */
131 @Override
132 public void addWindow(final FrameContainer window) {
/*
P/P * Method: void addWindow(FrameContainer)
*
* Preconditions:
* this.model != null
*/
133 addWindow(model.getRootNode(), window);
134 }
135
136 /** {@inheritDoc} */
137 @Override
138 public void addWindow(final FrameContainer parent,
139 final FrameContainer window) {
/*
P/P * Method: void addWindow(FrameContainer, FrameContainer)
*
* Preconditions:
* this.nodes != null
*/
140 addWindow(nodes.get(parent), window);
141 }
142
143 /** {@inheritDoc} */
144 @Override
145 public void delWindow(final FrameContainer parent,
146 final FrameContainer window) {
/*
P/P * Method: void delWindow(FrameContainer, FrameContainer)
*/
147 delWindow(window);
148 }
149
150 /** {@inheritDoc} */
151 @Override
152 public void delWindow(final FrameContainer window) {
/*
P/P * Method: void delWindow(FrameContainer)
*/
153 UIUtilities.invokeLater(new Runnable() {
154
155 /** {@inheritDoc} */
156 @Override
157 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* (soft) this.model != null
* (soft) this.val$window != null
*
* Presumptions:
* init'ed(com.dmdirc.logger.ErrorLevel.MEDIUM)
* java.util.Map:get(...)@161 != null
*
* Test Vectors:
* this.nodes: Addr_Set{null}, Inverse{null}
* java.util.Map:get(...)@158: Inverse{null}, Addr_Set{null}
* javax.swing.tree.DefaultMutableTreeNode:getLevel(...)@163: {-231..-1, 1..232-1}, {0}
*/
158 if (nodes == null || nodes.get(window) == null) {
159 return;
160 }
161 final DefaultMutableTreeNode node =
162 nodes.get(window);
163 if (node.getLevel() == 0) {
164 Logger.appError(ErrorLevel.MEDIUM,
165 "delServer triggered for root node" +
166 node.toString(),
167 new IllegalArgumentException());
168 } else {
169 model.removeNodeFromParent(nodes.get(window));
170 }
171 nodes.remove(window);
172 window.removeSelectionListener(TreeFrameManager.this);
173 window.removeIconChangeListener(TreeFrameManager.this);
174 window.removeNotificationListener(TreeFrameManager.this);
175 }
176 });
177 }
178
179 /**
180 * Adds a window to the frame container.
181 *
182 * @param parent Parent node
183 * @param window Window to add
184 */
185 public void addWindow(final TreeViewNode parent,
186 final FrameContainer window) {
/*
P/P * Method: void addWindow(TreeViewNode, FrameContainer)
*/
187 UIUtilities.invokeLater(new Runnable() {
188
189 /** {@inheritDoc} */
190 @Override
191 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* this.model != null
* this.nodes != null
* this.tree != null
* this.val$window != null
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
* (soft) init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* (soft) this.model.comparator != null
* (soft) init'ed(this.model.root)
*
* Presumptions:
* (int) (java.awt.Rectangle:getY(...)@205) in {-231..232-1}
* com.dmdirc.addons.ui_swing.framemanager.tree.TreeViewModel:getRoot(...)@147 != null
*
* Postconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* java.lang.StringBuilder:toString(...)._tainted == 0
* init'ed(new ArrayList(getSources#1) num objects)
* init'ed(new ConfigManager(getGlobalConfig#1) num objects)
* possibly_updated(new ConfigManager(getGlobalConfig#1).channel)
* possibly_updated(new ConfigManager(getGlobalConfig#1).file)
* possibly_updated(new ConfigManager(getGlobalConfig#1).ircd)
* possibly_updated(new ConfigManager(getGlobalConfig#1).listeners)
* possibly_updated(new ConfigManager(getGlobalConfig#1).network)
* possibly_updated(new ConfigManager(getGlobalConfig#1).server)
* ...
*
* Test Vectors:
* this.val$parent: Inverse{null}, Addr_Set{null}
* com.dmdirc.addons.ui_swing.framemanager.tree.Tree:getRowBounds(...)@202: Addr_Set{null}, Inverse{null}
*/
192 final TreeViewNode node =
193 new TreeViewNode(new NodeLabel(window.getFrame()),
194 window);
195 nodes.put(window, node);
196 if (parent == null) {
197 model.insertNodeInto(node, model.getRootNode());
198 } else {
199 model.insertNodeInto(node, parent);
200 }
201 tree.expandPath(new TreePath(node.getPath()).getParentPath());
202 final Rectangle view =
203 tree.getRowBounds(tree.getRowForPath(new TreePath(node.getPath())));
204 if (view != null) {
205 tree.scrollRectToVisible(new Rectangle(0, (int) view.getY(), 0, 0));
206 }
207 window.addSelectionListener(TreeFrameManager.this);
208 window.addIconChangeListener(TreeFrameManager.this);
209 window.addNotificationListener(TreeFrameManager.this);
210 }
211 });
212 }
213
214 /**
215 * Returns the tree for this frame manager.
216 *
217 * @return Tree for the manager
218 */
219 public JTree getTree() {
/*
P/P * Method: JTree getTree()
*
* Postconditions:
* return_value == this.tree
* init'ed(return_value)
*/
220 return tree;
221 }
222
223 /**
224 * {@inheritDoc}
225 *
226 * @param e Adjustment event
227 */
228 @Override
229 public void adjustmentValueChanged(final AdjustmentEvent e) {
230 //HACK Disregard all scrolling events
/*
P/P * Method: void adjustmentValueChanged(AdjustmentEvent)
*
* Preconditions:
* e != null
*
* Presumptions:
* java.awt.event.AdjustmentEvent:getSource(...)@231 != null
*/
231 ((JScrollBar) e.getSource()).setValue(0);
232 }
233
234 /**
235 * Checks for and sets a rollover node.
236 *
237 * @param event event to check
238 */
239 protected void checkRollover(final MouseEvent event) {
/*
P/P * Method: void checkRollover(MouseEvent)
*
* Preconditions:
* this.nodes != null
* this.tree != null
*
* Presumptions:
* java.util.Iterator:next(...)@250 != null
* java.util.Map:values(...)@250 != null
* treeNode.label@250 != null
*
* Test Vectors:
* event: Inverse{null}, Addr_Set{null}
* java.util.Iterator:hasNext(...)@250: {1}, {0}
*/
240 NodeLabel node = null;
241
242 if (event == null) {
243 node = null;
244 } else if (tree.getNodeForLocation(event.getX(), event.getY()) != null) {
245 node =
246 tree.getNodeForLocation(event.getX(), event.getY()).getLabel();
247 }
248
249 synchronized (nodes) {
250 for (TreeViewNode treeNode : nodes.values()) {
251 final NodeLabel label = treeNode.getLabel();
252 label.setRollover(node == null ? false : label == node);
253 }
254 }
255 tree.repaint();
256 }
257
258 /** Sets treeview colours. */
259 private void setColours() {
/*
P/P * Method: void setColours()
*
* Preconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* this.tree != null
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
*
* Presumptions:
* getGlobalConfig(...).sources != null
*
* Postconditions:
* com/dmdirc/config/IdentityManager.globalconfig != null
* java.lang.StringBuilder:toString(...)._tainted == 0
* new ArrayList(getSources#1) num objects == 0
* new ConfigManager(getGlobalConfig#1) num objects == 0
* new MapList(ConfigManager#1) num objects == 0
* new ArrayList(getSources#1) num objects <= 1
* new ConfigManager(getGlobalConfig#1) num objects == new ArrayList(getSources#1) num objects
* new MapList(ConfigManager#1) num objects == new ArrayList(getSources#1) num objects
* new ConfigManager(getGlobalConfig#1).channel == &java.lang.StringBuilder:toString(...)
* init'ed(new ConfigManager(getGlobalConfig#1).channel)
* ...
*/
260 tree.setBackground(IdentityManager.getGlobalConfig().getOptionColour(
261 "treeview", "backgroundcolour",
262 "ui", "backgroundcolour"));
263 tree.setForeground(IdentityManager.getGlobalConfig().getOptionColour(
264 "treeview", "foregroundcolour",
265 "ui", "foregroundcolour"));
266
267 tree.repaint();
268 }
269
270 /** {@inheritDoc} */
271 @Override
272 public void configChanged(final String domain, final String key) {
/*
P/P * Method: void configChanged(String, String)
*
* Preconditions:
* init'ed(com/dmdirc/config/IdentityManager.globalconfig)
* this.tree != null
* (soft) init'ed(com.dmdirc.config.ConfigManager$1__static_init.new int[](ConfigManager$1__static_init#1)[...])
*
* Postconditions:
* com/dmdirc/config/IdentityManager.globalconfig != null
* java.lang.StringBuilder:toString(...)._tainted == 0
* new ArrayList(getSources#1) num objects == 0
* new ConfigManager(getGlobalConfig#1) num objects == 0
* new MapList(ConfigManager#1) num objects == 0
* init'ed(new ConfigManager(getGlobalConfig#1).channel)
* init'ed(new ConfigManager(getGlobalConfig#1).file)
* init'ed(new ConfigManager(getGlobalConfig#1).ircd)
* init'ed(new ConfigManager(getGlobalConfig#1).listeners)
* init'ed(new ConfigManager(getGlobalConfig#1).network)
* ...
*/
273 setColours();
274 }
275
276 /** {@inheritDoc} */
277 @Override
278 public void selectionChanged(final Window window) {
/*
P/P * Method: void selectionChanged(Window)
*
* Preconditions:
* this.nodes != null
* (soft) this.tree != null
*
* Presumptions:
* com.dmdirc.addons.ui_swing.framemanager.tree.Tree:getModel(...)@288 != null
* java.util.Iterator:next(...)@281 != null
* java.util.Map:values(...)@280 != null
* treeNode.label@281 != null
*
* Postconditions:
* this.tree.path == One-of{old this.tree.path, &new TreePath(selectionChanged#1)}
* new TreePath(selectionChanged#1) num objects <= 1
*
* Test Vectors:
* window: Addr_Set{null}, Inverse{null}
* java.util.Iterator:hasNext(...)@281: {1}, {0}
* javax.swing.tree.DefaultTreeModel:getPathToRoot(...)@288: Addr_Set{null}, Inverse{null}
* treePath.length@288: {0}, {1..+Inf}
*/
279 synchronized (nodes) {
280 final Collection<TreeViewNode> collection = nodes.values();
281 for (TreeViewNode treeNode : collection) {
282 final NodeLabel label = treeNode.getLabel();
283 label.selectionChanged(window);
284 }
285 }
286
287 if (window != null) {
288 final TreeNode[] treePath =
289 ((DefaultTreeModel) tree.getModel()).getPathToRoot(nodes.get(window.getContainer()));
290 if (treePath != null && treePath.length > 0) {
291 final TreePath path = new TreePath(treePath);
292 if (path != null) {
293 tree.setTreePath(path);
294 }
295 }
296 }
297 }
298
299 /** {@inheritDoc} */
300 @Override
301 public void notificationSet(final Window window, final Color colour) {
/*
P/P * Method: void notificationSet(Window, Color)
*/
302 SwingUtilities.invokeLater(new Runnable() {
303
304 /** {@inheritDoc} */
305 @Override
306 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* this.nodes != null
* this.val$window != null
* (soft) this.tree != null
*/
307 synchronized (nodes) {
308 final FrameContainer container = window.getContainer();
309 final TreeViewNode node = nodes.get(container);
310 if (container != null && node != null) {
311 final NodeLabel label = node.getLabel();
312 if (label != null) {
313 label.notificationSet(window, colour);
314 tree.repaint();
315 }
316 }
317 }
318 }
319 });
320 }
321
322 /** {@inheritDoc} */
323 @Override
324 public void notificationCleared(final Window window) {
/*
P/P * Method: void notificationCleared(Window)
*/
325 SwingUtilities.invokeLater(new Runnable() {
326
327 /** {@inheritDoc} */
328 @Override
329 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* this.nodes != null
* this.val$window != null
* (soft) this.tree != null
*/
330 synchronized (nodes) {
331 final FrameContainer container = window.getContainer();
332 final TreeViewNode node = nodes.get(container);
333 if (container != null && node != null) {
334 final NodeLabel label = node.getLabel();
335 if (label != null) {
336 label.notificationCleared(window);
337 tree.repaint();
338 }
339 }
340 }
341 }
342 });
343 }
344
345 /** {@inheritDoc} */
346 @Override
347 public void iconChanged(final Window window, final Icon icon) {
/*
P/P * Method: void iconChanged(Window, Icon)
*/
348 SwingUtilities.invokeLater(new Runnable() {
349
350 /** {@inheritDoc} */
351 @Override
352 public void run() {
/*
P/P * Method: void run()
*
* Preconditions:
* this.nodes != null
* this.val$window != null
* (soft) this.tree != null
*/
353 synchronized (nodes) {
354 final TreeViewNode node = nodes.get(window.getContainer());
355 if (node != null) {
356 final NodeLabel label = node.getLabel();
357 if (label != null) {
358 label.iconChanged(window, icon);
359 tree.repaint();
360 }
361 }
362 }
363 }
364 });
365 }
366 }
SofCheck Inspector Build Version : 2.17854
| TreeFrameManager.java |
2009-Jun-25 01:54:24 |
| TreeFrameManager.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$1.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$2.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$3.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$4.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$5.class |
2009-Sep-02 17:04:16 |
| TreeFrameManager$6.class |
2009-Sep-02 17:04:16 |