1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.lf5.viewer.categoryexplorer;
18
19 import java.awt.Component;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.ActionListener;
22 import java.awt.event.MouseAdapter;
23 import java.awt.event.MouseEvent;
24 import java.util.ArrayList;
25 import java.util.Enumeration;
26
27 import javax.swing.JCheckBox;
28 import javax.swing.JMenuItem;
29 import javax.swing.JOptionPane;
30 import javax.swing.JPopupMenu;
31 import javax.swing.JTree;
32 import javax.swing.tree.TreePath;
33
34
35
36
37
38
39
40
41
42
43 public class CategoryNodeEditor extends CategoryAbstractCellEditor {
44
45
46
47
48
49
50
51 protected CategoryNodeEditorRenderer _renderer;
52 protected CategoryNode _lastEditedNode;
53 protected JCheckBox _checkBox;
54 protected CategoryExplorerModel _categoryModel;
55 protected JTree _tree;
56
57
58
59
60
61
62
63
64
65 public CategoryNodeEditor(CategoryExplorerModel model) {
66 _renderer = new CategoryNodeEditorRenderer();
67 _checkBox = _renderer.getCheckBox();
68 _categoryModel = model;
69
70 _checkBox.addActionListener(new ActionListener() {
71 public void actionPerformed(ActionEvent e) {
72 _categoryModel.update(_lastEditedNode, _checkBox.isSelected());
73 stopCellEditing();
74 }
75 });
76
77 _renderer.addMouseListener(new MouseAdapter() {
78 public void mousePressed(MouseEvent e) {
79 if ((e.getModifiers() & MouseEvent.BUTTON3_MASK) != 0) {
80 showPopup(_lastEditedNode, e.getX(), e.getY());
81 }
82 stopCellEditing();
83 }
84 });
85 }
86
87
88
89
90
91 public Component getTreeCellEditorComponent(JTree tree, Object value,
92 boolean selected, boolean expanded,
93 boolean leaf, int row) {
94 _lastEditedNode = (CategoryNode) value;
95 _tree = tree;
96
97 return _renderer.getTreeCellRendererComponent(tree,
98 value, selected, expanded,
99 leaf, row, true);
100
101 }
102
103 public Object getCellEditorValue() {
104 return _lastEditedNode.getUserObject();
105 }
106
107
108
109
110 protected JMenuItem createPropertiesMenuItem(final CategoryNode node) {
111 JMenuItem result = new JMenuItem("Properties");
112 result.addActionListener(new ActionListener() {
113 public void actionPerformed(ActionEvent e) {
114 showPropertiesDialog(node);
115 }
116 });
117 return result;
118 }
119
120 protected void showPropertiesDialog(CategoryNode node) {
121 JOptionPane.showMessageDialog(
122 _tree,
123 getDisplayedProperties(node),
124 "Category Properties: " + node.getTitle(),
125 JOptionPane.PLAIN_MESSAGE
126 );
127 }
128
129 protected Object getDisplayedProperties(CategoryNode node) {
130 ArrayList result = new ArrayList();
131 result.add("Category: " + node.getTitle());
132 if (node.hasFatalRecords()) {
133 result.add("Contains at least one fatal LogRecord.");
134 }
135 if (node.hasFatalChildren()) {
136 result.add("Contains descendants with a fatal LogRecord.");
137 }
138 result.add("LogRecords in this category alone: " +
139 node.getNumberOfContainedRecords());
140 result.add("LogRecords in descendant categories: " +
141 node.getNumberOfRecordsFromChildren());
142 result.add("LogRecords in this category including descendants: " +
143 node.getTotalNumberOfRecords());
144 return result.toArray();
145 }
146
147 protected void showPopup(CategoryNode node, int x, int y) {
148 JPopupMenu popup = new JPopupMenu();
149 popup.setSize(150, 400);
150
151
152
153 if (node.getParent() == null) {
154 popup.add(createRemoveMenuItem());
155 popup.addSeparator();
156 }
157 popup.add(createSelectDescendantsMenuItem(node));
158 popup.add(createUnselectDescendantsMenuItem(node));
159 popup.addSeparator();
160 popup.add(createExpandMenuItem(node));
161 popup.add(createCollapseMenuItem(node));
162 popup.addSeparator();
163 popup.add(createPropertiesMenuItem(node));
164 popup.show(_renderer, x, y);
165 }
166
167 protected JMenuItem createSelectDescendantsMenuItem(final CategoryNode node) {
168 JMenuItem selectDescendants =
169 new JMenuItem("Select All Descendant Categories");
170 selectDescendants.addActionListener(
171 new ActionListener() {
172 public void actionPerformed(ActionEvent e) {
173 _categoryModel.setDescendantSelection(node, true);
174 }
175 }
176 );
177 return selectDescendants;
178 }
179
180 protected JMenuItem createUnselectDescendantsMenuItem(final CategoryNode node) {
181 JMenuItem unselectDescendants =
182 new JMenuItem("Deselect All Descendant Categories");
183 unselectDescendants.addActionListener(
184
185 new ActionListener() {
186 public void actionPerformed(ActionEvent e) {
187 _categoryModel.setDescendantSelection(node, false);
188 }
189 }
190
191 );
192 return unselectDescendants;
193 }
194
195 protected JMenuItem createExpandMenuItem(final CategoryNode node) {
196 JMenuItem result = new JMenuItem("Expand All Descendant Categories");
197 result.addActionListener(new ActionListener() {
198 public void actionPerformed(ActionEvent e) {
199 expandDescendants(node);
200 }
201 });
202 return result;
203 }
204
205 protected JMenuItem createCollapseMenuItem(final CategoryNode node) {
206 JMenuItem result = new JMenuItem("Collapse All Descendant Categories");
207 result.addActionListener(new ActionListener() {
208 public void actionPerformed(ActionEvent e) {
209 collapseDescendants(node);
210 }
211 });
212 return result;
213 }
214
215
216
217
218
219
220
221
222
223
224 protected JMenuItem createRemoveMenuItem() {
225 JMenuItem result = new JMenuItem("Remove All Empty Categories");
226 result.addActionListener(new ActionListener() {
227 public void actionPerformed(ActionEvent e) {
228 while (removeUnusedNodes() > 0) ;
229 }
230 });
231 return result;
232 }
233
234 protected void expandDescendants(CategoryNode node) {
235 Enumeration descendants = node.depthFirstEnumeration();
236 CategoryNode current;
237 while (descendants.hasMoreElements()) {
238 current = (CategoryNode) descendants.nextElement();
239 expand(current);
240 }
241 }
242
243 protected void collapseDescendants(CategoryNode node) {
244 Enumeration descendants = node.depthFirstEnumeration();
245 CategoryNode current;
246 while (descendants.hasMoreElements()) {
247 current = (CategoryNode) descendants.nextElement();
248 collapse(current);
249 }
250 }
251
252
253
254
255 protected int removeUnusedNodes() {
256 int count = 0;
257 CategoryNode root = _categoryModel.getRootCategoryNode();
258 Enumeration enumeration = root.depthFirstEnumeration();
259 while (enumeration.hasMoreElements()) {
260 CategoryNode node = (CategoryNode) enumeration.nextElement();
261 if (node.isLeaf() && node.getNumberOfContainedRecords() == 0
262 && node.getParent() != null) {
263 _categoryModel.removeNodeFromParent(node);
264 count++;
265 }
266 }
267
268 return count;
269 }
270
271 protected void expand(CategoryNode node) {
272 _tree.expandPath(getTreePath(node));
273 }
274
275 protected TreePath getTreePath(CategoryNode node) {
276 return new TreePath(node.getPath());
277 }
278
279 protected void collapse(CategoryNode node) {
280 _tree.collapsePath(getTreePath(node));
281 }
282
283
284
285
286
287
288
289
290
291 }