Source code: org/altara/util/ContextMenuSupport.java
1 /* Altara Utility Classes
2 Copyright (C) 2001,2002 Brian H. Trammell
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, it is available at
16 http://www.gnu.org/copyleft/lesser.html, or by writing to the
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 Boston, MA 02111-1307 USA
19 */
20
21 package org.altara.util;
22
23 import java.util.*;
24 import java.awt.*;
25 import java.awt.event.*;
26 import javax.swing.*;
27 import javax.swing.tree.*;
28 import javax.swing.event.*;
29
30 public abstract class ContextMenuSupport {
31
32 protected HashMap actionListMap;
33 protected HashMap defaultActionMap;
34 protected HashMap menuMap;
35 private Component source;
36 private Object invoked;
37
38 protected ContextMenuSupport(Component source) {
39 actionListMap = new HashMap();
40 defaultActionMap = new HashMap();
41 menuMap = new HashMap();
42
43 // bind the mouse listener to the source
44 this.source = source;
45 source.addMouseListener(new MouseAdapter() {
46 public void mousePressed(MouseEvent me) {
47 if ((InputEvent.BUTTON3_MASK & me.getModifiers()) != 0) {
48 // invoke action menu on right click
49 invokeActionMenu(me);
50 } else if (((InputEvent.BUTTON1_MASK & me.getModifiers()) != 0)
51 && ((InputEvent.CTRL_MASK & me.getModifiers()) != 0)) {
52 // invoke action menu on control-click
53 invokeActionMenu(me);
54 } else if (((InputEvent.BUTTON1_MASK & me.getModifiers()) != 0)
55 && me.getClickCount() == 2) {
56 // invoke default action on double-click
57 invokeDefaultAction(me);
58 }
59 }
60 });
61 }
62
63 public synchronized void addClassAction(Class clazz, Action action) {
64 LinkedList actionList = (LinkedList)actionListMap.get(clazz);
65 if (actionList == null) actionList = new LinkedList();
66 actionList.add(action);
67 actionListMap.put(clazz,actionList);
68 // signal rebuild of menus
69 menuMap = null;
70 }
71
72 public synchronized void addDefaultClassAction(Class clazz, Action action) {
73 addClassAction(clazz, action);
74 defaultActionMap.put(clazz, action);
75 }
76
77 private synchronized void rebuildMenuMap() {
78 menuMap = new HashMap();
79 Iterator classIter = actionListMap.keySet().iterator();
80 while (classIter.hasNext()) {
81 Class clazz = (Class)classIter.next();
82 JPopupMenu thisMenu = new JPopupMenu();
83 thisMenu.setInvoker(source);
84 Iterator actionIter =
85 ((Collection)actionListMap.get(clazz)).iterator();
86 while (actionIter.hasNext()) {
87 thisMenu.add((Action)actionIter.next());
88 }
89 menuMap.put(clazz,thisMenu);
90 }
91 }
92
93 protected synchronized void invokeActionMenu(MouseEvent me) {
94 // rebuild the menu map if it's been invalidated
95 if (menuMap == null) rebuildMenuMap();
96 // find the invoked class
97 invoked = findInvoked(me);
98 // check for null invoke
99 if (invoked == null) return;
100 // retrieve the appropriate menu
101 JPopupMenu menu = (JPopupMenu)menuMap.get(invoked.getClass());
102 // display it
103 if (menu != null) {
104 menu.show(me.getComponent(),me.getX(),me.getY());
105 }
106 }
107
108 protected synchronized void invokeDefaultAction(MouseEvent me) {
109 // find the invoked class
110 invoked = findInvoked(me);
111 // check for null invoke
112 if (invoked == null) return;
113 // retrieve the approrpriate action
114 Action action = (Action)defaultActionMap.get(invoked.getClass());
115 // perform it
116 if (action != null && action.isEnabled())
117 action.actionPerformed(new ActionEvent(source,0,"DefaultInvoke"));
118 }
119
120 protected abstract Object findInvoked(MouseEvent me);
121
122 protected synchronized Object getLastInvoked() {
123 return invoked;
124 }
125 }