1
2 package hep.wired.heprep.tree;
3
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.beans.*;
7 import java.util.*;
8 import java.util.List;
9 import javax.swing.*;
10 import javax.swing.event.*;
11 import javax.swing.tree.*;
12
13 import org.freehep.swing.layout.TableLayout;
14 import org.freehep.swing.popup.HasPopupItems;
15
16 import hep.graphics.heprep.HepRep;
17 import hep.graphics.heprep.HepRepType;
18 import hep.graphics.heprep.HepRepTypeTree;
19
20 import hep.wired.image.WiredBaseImage;
21 import hep.wired.plot.WiredPlot;
22 import hep.wired.services.GraphicsPanel;
23 import hep.wired.util.JTristateTree;
24 import hep.wired.util.TristateTreeCellEditor;
25 import hep.wired.util.TristateTreeNode;
26
27 import hep.wired.heprep.graphicspanel.HepRepPanel;
28 import hep.wired.heprep.graphicspanel.ControlPanel;
29 import hep.wired.heprep.util.WiredHepRepUtil;
30
31 /***
32 * TreePanel.
33 *
34 * @author Mark Donszelmann
35 * @version $Id: TreePanel.java 2115 2005-07-25 05:33:47Z duns $
36 */
37 public class TreePanel extends ControlPanel {
38
39 private TreePanelModel panelModel;
40
41 private TypeTristateTreeModel typeModel;
42 private TypeTreeCellRenderer typeTreeCellRenderer, typeTreeCellEditor;
43 private JTree typeTree;
44
45 private JCheckBox applyImmediately;
46 private JButton apply;
47
48 private JCheckBox hide;
49 private JSpinner hideLevel;
50
51 private ButtonModel dummyApplyImmediatelyModel, dummyApplyModel, dummyHideModel;
52 private SpinnerModel dummyHideLevelModel;
53 private TreeCellRenderer dummyCellRenderer;
54 private TreeCellEditor dummyCellEditor;
55
56 interface PathListener {
57 public void doAction(JTree tree, TreePath path);
58 }
59
60 class JTypeTree extends JTristateTree implements HasPopupItems {
61 public JTypeTree(TypeTristateTreeModel model) {
62 super(model);
63 }
64
65
66 private void doForPath(JTree tree, TreePath path, PathListener listener) {
67
68 TreeNode node = (TreeNode)path.getLastPathComponent();
69 if (node.getChildCount() >= 0) {
70 for (Enumeration e=node.children(); e.hasMoreElements(); ) {
71 TreeNode n = (TreeNode)e.nextElement();
72 TreePath childPath = path.pathByAddingChild(n);
73 doForPath(tree, childPath, listener);
74 }
75 }
76
77
78 listener.doAction(tree, path);
79 }
80
81 public JPopupMenu modifyPopupMenu(JPopupMenu menu, Component source, Point p) {
82 final TreePath path = getClosestPathForLocation(p.x, p.y);
83 if (getPathBounds(path) == null) return menu;
84
85 if (getPathBounds(path).contains(p)) {
86
87
88
89
90 if ( ! isPathSelected(path) ) {
91 removeSelectionPaths( getSelectionPaths() );
92 addSelectionPath(path);
93 }
94
95 menu.add(new JMenuItem("Expand all")).addActionListener(new ActionListener() {
96 public void actionPerformed(ActionEvent e) {
97 doForPath(typeTree, path, new PathListener() {
98 public void doAction(JTree tree, TreePath path) {
99 tree.expandPath(path);
100 }
101 });
102 }
103 });
104
105 menu.add(new JMenuItem("Collapse all")).addActionListener(new ActionListener() {
106 public void actionPerformed(ActionEvent e) {
107 doForPath(typeTree, path, new PathListener() {
108 public void doAction(JTree tree, TreePath path) {
109 tree.collapsePath(path);
110 }
111 });
112 }
113 });
114
115 menu.addSeparator();
116
117 menu.add(new JMenuItem("Show all")).addActionListener(new ActionListener() {
118 public void actionPerformed(ActionEvent e) {
119 doForPath(typeTree, path, new PathListener() {
120 public void doAction(JTree tree, TreePath path) {
121 Object object = path.getLastPathComponent();
122 if (object instanceof TristateTreeNode) {
123 TristateTreeNode node = (TristateTreeNode)object;
124 node.include(true);
125 node.select(true);
126 }
127 }
128 });
129 typeModel.treeNodesChanged(new TreeModelEvent(typeModel, path.getParentPath()));
130 panelModel.fireChangeEvent(false);
131 }
132 });
133
134 menu.add(new JMenuItem("Hide all")).addActionListener(new ActionListener() {
135 public void actionPerformed(ActionEvent e) {
136 doForPath(typeTree, path, new PathListener() {
137 public void doAction(JTree tree, TreePath path) {
138 Object object = path.getLastPathComponent();
139 if (object instanceof TristateTreeNode) {
140 TristateTreeNode node = (TristateTreeNode)object;
141 node.include(false);
142 node.select(false);
143 }
144 }
145 });
146 typeModel.treeNodesChanged(new TreeModelEvent(typeModel, path.getParentPath()));
147 panelModel.fireChangeEvent(false);
148 }
149 });
150
151 menu.addSeparator();
152
153 menu.add(new JMenuItem("Invert all")).addActionListener(new ActionListener() {
154 public void actionPerformed(ActionEvent e) {
155 doForPath(typeTree, path, new PathListener() {
156 public void doAction(JTree tree, TreePath path) {
157 Object object = path.getLastPathComponent();
158 if (object instanceof TristateTreeNode) {
159 TristateTreeNode node = (TristateTreeNode)object;
160 node.include(!node.isIncluded());
161 node.select(!node.isSelected());
162 }
163 }
164 });
165 typeModel.treeNodesChanged(new TreeModelEvent(typeModel, path.getParentPath()));
166 panelModel.fireChangeEvent(false);
167 }
168 });
169
170 }
171 return menu;
172 }
173 }
174
175 public TreePanel() {
176 super("Visibility Tree", "Set or Clear Visibility of Objects", WiredBaseImage.getIcon("Tree%w", 16), null);
177 setLayout(new TableLayout());
178
179 typeModel = null;
180
181 typeTree = new JTypeTree(typeModel);
182
183
184 typeTreeCellRenderer = new TypeTreeCellRenderer();
185 typeTree.setCellRenderer(typeTreeCellRenderer);
186 typeTreeCellEditor = new TypeTreeCellRenderer();
187 typeTree.setCellEditor(new TristateTreeCellEditor(typeTree, typeTreeCellEditor));
188
189 dummyCellRenderer = typeTree.getCellRenderer();
190 dummyCellEditor = typeTree.getCellEditor();
191
192 String insets = " [3 3 3 3] ";
193
194 JScrollPane treeScrollPane = new JScrollPane(typeTree, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
195 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
196 add(treeScrollPane, "0 1 2 1"+insets+"wh");
197
198 applyImmediately = new JCheckBox("Apply immediately");
199 add(applyImmediately, "0 2"+insets+"w");
200 applyImmediately.addPropertyChangeListener("enabled", new PropertyChangeListener() {
201 public void propertyChange(PropertyChangeEvent event) {
202 apply.setEnabled(applyImmediately.isEnabled() && !applyImmediately.isSelected());
203 }
204 });
205 applyImmediately.addActionListener(new ActionListener() {
206 public void actionPerformed(ActionEvent event) {
207 apply.setEnabled(!applyImmediately.isSelected());
208 }
209 });
210 dummyApplyImmediatelyModel = applyImmediately.getModel();
211
212 apply = new JButton("Apply");
213 add(apply, "1 2"+insets+"wr");
214 dummyApplyModel = apply.getModel();
215
216 hide = new JCheckBox("Hide below level: ");
217 add(hide, "0 3"+insets+"w");
218 hide.addActionListener(new ActionListener() {
219 public void actionPerformed(ActionEvent event) {
220 hideLevel.setEnabled(hide.isSelected());
221 if (panelModel != null) {
222 int maxDepth = panelModel.getMaxDepth();
223 typeTreeCellRenderer.setMaxDepth(maxDepth);
224 typeTreeCellEditor.setMaxDepth(maxDepth);
225 }
226 }
227 });
228 hide.addPropertyChangeListener("enabled", new PropertyChangeListener() {
229 public void propertyChange(PropertyChangeEvent event) {
230 hideLevel.setEnabled(hide.isEnabled() && hide.isSelected());
231 }
232 });
233 dummyHideModel = hide.getModel();
234
235 hideLevel = new JSpinner();
236 hideLevel.addChangeListener(new ChangeListener() {
237 public void stateChanged(ChangeEvent event) {
238 if (panelModel != null) {
239 int maxDepth = panelModel.getMaxDepth();
240 typeTreeCellRenderer.setMaxDepth(maxDepth);
241 typeTreeCellEditor.setMaxDepth(maxDepth);
242 }
243 }
244 });
245
246 add(hideLevel, "1 3"+insets+"wr");
247 hideLevel.setEnabled(false);
248 dummyHideLevelModel = hideLevel.getModel();
249 }
250
251 public void setTreeToPlot(WiredPlot plot) {
252 if (plot != null) {
253 GraphicsPanel panel = plot.getGraphicsPanel();
254
255 if (!(panel instanceof HepRepPanel)) return;
256
257 HepRepPanel heprepPanel = (HepRepPanel)panel;
258
259
260 if (panelModel != null) {
261 panelModel.setExpandedTypeNames(WiredHepRepUtil.getExpandedState(typeModel, typeTree));
262 }
263
264 panelModel = heprepPanel.getTreePanelModel();
265
266 typeModel = panelModel.getTypeTreeModel();
267 typeTree.setModel(typeModel);
268
269 applyImmediately.setModel(panelModel.getApplyImmediatelyModel());
270 apply.setModel(panelModel.getApplyModel());
271
272 hide.setModel(panelModel.getHideModel());
273 hideLevel.setModel(panelModel.getHideLevelModel());
274
275 int maxDepth = panelModel.getMaxDepth();
276 typeTreeCellRenderer.setMaxDepth(maxDepth);
277 typeTreeCellEditor.setMaxDepth(maxDepth);
278
279 WiredHepRepUtil.setExpandedState(panelModel.getExpandedTypeNames(), typeModel, typeTree);
280
281 setEnabled(true);
282 } else {
283 if (panelModel != null) {
284 panelModel.setExpandedTypeNames(WiredHepRepUtil.getExpandedState(typeModel, typeTree));
285 }
286
287 panelModel = null;
288 typeModel = null;
289 typeTree.setModel(typeModel);
290
291
292 applyImmediately.setModel(dummyApplyImmediatelyModel);
293 apply.setModel(dummyApplyModel);
294
295 hide.setModel(dummyHideModel);
296 hideLevel.setModel(dummyHideLevelModel);
297
298 setEnabled(false);
299 }
300 }
301
302 public void setEnabled(boolean state) {
303 applyImmediately.setEnabled(state);
304 hide.setEnabled(state);
305 }
306 }