1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22 package org.jboss.console.navtree;
23
24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
26 import java.awt.event.MouseAdapter;
27 import java.awt.event.MouseEvent;
28 import java.util.HashMap;
29
30 import javax.swing.JComponent;
31 import javax.swing.JMenuItem;
32 import javax.swing.JPopupMenu;
33 import javax.swing.JTree;
34 import javax.swing.ToolTipManager;
35 import javax.swing.event.TreeSelectionListener;
36 import javax.swing.tree.TreeModel;
37 import javax.swing.tree.TreePath;
38 import javax.swing.tree.TreeSelectionModel;
39
40 import org.jboss.console.manager.interfaces.SimpleTreeNodeMenuEntry;
41 import org.jboss.console.manager.interfaces.TreeAction;
42 import org.jboss.console.manager.interfaces.TreeNodeMenuEntry;
43 import org.jboss.console.manager.interfaces.impl.SeparatorTreeNodeMenuEntry;
44
45 /**
46 * Holder of the browser tree and associated handlers. Can then be embedded
47 * in any code such as applet code. Specific actions are handled
48 * through a TreeContext callback object used to communicate between this object
49 * and its container.
50 *
51 * @see org.jboss.console.navtree.TreeContext
52 * @see AppletBrowser
53 *
54 * @author <a href="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
55 * @version $Revision: 37459 $
56 *
57 */
58
59 public class AdminTreeBrowser
60 {
61 TreeContext ctx = null;
62
63 ConsoleTreeModel tm = null;
64 TreeCellRenderer cellRenderer = null;
65 TreeSelectionListener selectionListener = null;
66 OpenNodeAccounter openNodeAccounter = null;
67
68 String webHost = null;
69
70 public static final String RIGHT_FRAME_NAME = "right";
71
72 /** Creates new form AppletTreeBrowser */
73 public AdminTreeBrowser (TreeContext ctx) throws Exception
74 {
75 this.ctx = ctx;
76
77 tm = new ConsoleTreeModel (ctx);
78 cellRenderer = new TreeCellRenderer (ctx);
79 //selectionListener = new SelectionListener ();
80
81 initComponents ();
82
83 openNodeAccounter = new OpenNodeAccounter(getTree());
84
85 //getTree().addTreeSelectionListener (selectionListener);
86 getTree().addMouseListener (new PopupMenuMgr());
87 //getTree().addTreeExpansionListener (openNodeAccounter);
88 getTree().getSelectionModel().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION);
89 ToolTipManager.sharedInstance().registerComponent(getTree());
90 }
91
92 public void refreshTree (boolean force)
93 {
94 try
95 {
96 this.tm.refreshTree (force);
97 }
98 catch (Exception displayed)
99 {
100 displayed.printStackTrace();
101 }
102 }
103
104
105 /** This method is called from within the constructor to
106 * initialize the form.
107 * WARNING: Do NOT modify this code. The content of this method is
108 * always regenerated by the Form Editor.
109 */
110 private void initComponents()//GEN-BEGIN:initComponents
111 {
112 tree = new javax.swing.JTree();
113
114 tree.setCellRenderer(getCellRenderer());
115 tree.setModel(getTreeModel());
116 tree.setAutoscrolls(true);
117
118 }//GEN-END:initComponents
119
120
121 // Variables declaration - do not modify//GEN-BEGIN:variables
122 private javax.swing.JTree tree;
123 // End of variables declaration//GEN-END:variables
124
125 public TreeCellRenderer getCellRenderer ()
126 {
127 return this.cellRenderer;
128 }
129
130 public TreeModel getTreeModel ()
131 {
132 return this.tm;
133 }
134
135 public TreeSelectionListener getSelectionListener ()
136 {
137 return this.selectionListener;
138 }
139
140 public JTree getTree ()
141 {
142 return this.tree;
143 }
144
145 /*
146 * Don't use SelectionListener as I am not able to detect clicks on an
147 * already selected tree node i.e. no refresh is possible by clicking!
148 * => Instead I use the PopupMenuMgr below to do the work
149 *
150 public class SelectionListener implements TreeSelectionListener
151 {
152
153 public SelectionListener () {}
154
155 public void valueChanged (TreeSelectionEvent e)
156 {
157 System.out.println ("in valueChanged");
158 Object node = getTree ().getLastSelectedPathComponent ();
159
160 if (node == null) return;
161
162 if (node instanceof NodeWrapper)
163 {
164 NodeWrapper who = (NodeWrapper)node;
165 TreeAction act = who.getAssociatedAction ();
166 ctx.doAdminTreeAction (act);
167 }
168 }
169 }
170 */
171
172 // -----------------------------------
173
174 public class OpenNodeAccounter
175 implements javax.swing.event.TreeExpansionListener, javax.swing.event.TreeModelListener
176 {
177 protected java.util.TreeSet openNodes = new java.util.TreeSet ();
178
179 public OpenNodeAccounter (JTree tree)
180 {
181 tree.getModel ().addTreeModelListener (this);
182 }
183
184 public void treeExpanded(javax.swing.event.TreeExpansionEvent event)
185 {
186 openNodes.add (((NodeWrapper)(event.getSource ())).getPath ());
187 //System.out.println (event.getPath().getClass ().toString ());
188 //openNodes.add (event.getPath ());
189 }
190
191 public void treeCollapsed(javax.swing.event.TreeExpansionEvent event)
192 {
193 openNodes.remove (((NodeWrapper)(event.getSource ())).getPath ());
194 //openNodes.remove (event.getPath ());
195 }
196
197 public void treeNodesChanged (javax.swing.event.TreeModelEvent e)
198 {
199 /*
200 java.util.Iterator iter = openNodes.iterator ();
201 while (iter.hasNext ())
202 {
203 javax.swing.tree.TreePath path = (javax.swing.tree.TreePath)iter.next ();
204 tree.expandPath (path);
205 }
206 */
207 /*
208 RootWrapper root = (RootWrapper)tm.getRoot ();
209 int max = root.getChildCount ();
210 for (int i=0; i<max ; i++)
211 {
212 StdNodeWrapper son = (StdNodeWrapper)root.getChild (i);
213 if (openNodes.contains (son.getPath ()))
214 recursivelyOpen (son);
215 }
216 */
217
218 }
219
220 public void recursivelyOpen (NodeWrapper son)
221 {
222 }
223
224 public void treeNodesInserted (javax.swing.event.TreeModelEvent e){}
225 public void treeNodesRemoved (javax.swing.event.TreeModelEvent e){}
226 public void treeStructureChanged (javax.swing.event.TreeModelEvent e) { }
227
228 }
229
230 // -----------------------------------
231
232 public class PopupMenuMgr extends MouseAdapter
233 {
234 HashMap menus = new HashMap ();
235
236 public PopupMenuMgr (){}
237
238 public void mousePressed( MouseEvent e )
239 {
240 mouseReleased(e);
241 }
242
243 public void mouseReleased( MouseEvent e )
244 {
245 TreePath loc = getTree().getPathForLocation(e.getX(), e.getY());
246 if (loc == null)//Path not found because
247 return;//right click does not occur on a node or a leaf
248
249 getTree().setSelectionPath (loc);
250
251 if ( e.isPopupTrigger())
252 {
253 Object node = getTree ().getLastSelectedPathComponent ();
254 if (node == null) return;
255
256 JPopupMenu popup = null;
257 if (menus.containsKey (node))
258 {
259 popup = (JPopupMenu)menus.get (node);
260 }
261 else if (node instanceof NodeWrapper)
262 {
263 NodeWrapper who = (NodeWrapper)node;
264
265 TreeNodeMenuEntry[] entries = who.getMenuEntries ();
266
267 if (entries != null && entries.length > 0)
268 {
269 popup = new JPopupMenu();
270 popup.setOpaque(true);
271 popup.setLightWeightPopupEnabled(true);
272 menus.put (node, popup);
273
274 // we must lazy-create the menu
275 //
276 for (int i=0; i<entries.length; i++)
277 {
278 if (entries[i] instanceof SeparatorTreeNodeMenuEntry)
279 {
280 popup.addSeparator ();
281 }
282 else if (entries[i] instanceof SimpleTreeNodeMenuEntry)
283 {
284 final SimpleTreeNodeMenuEntry txt = (SimpleTreeNodeMenuEntry)entries[i];
285 JMenuItem mi = new JMenuItem(txt.getText ());
286 mi.addActionListener ( new ActionListener ()
287 {
288 public void actionPerformed(ActionEvent e)
289 {
290 ctx.doPopupMenuAction (txt);
291 }
292 }
293 );
294 popup.add(mi);
295 }
296 }
297 }
298
299 }
300
301 if (popup != null)
302 popup.show( (JComponent)e.getSource(), e.getX(), e.getY() );
303 }
304 else
305 {
306 Object node = getTree ().getLastSelectedPathComponent ();
307
308 if (node != null && node instanceof NodeWrapper)
309 {
310 NodeWrapper who = (NodeWrapper)node;
311 TreeAction act = who.getAssociatedAction ();
312 ctx.doAdminTreeAction (act);
313 }
314
315 }
316 }
317 }
318 }