1 /*
2 * Copyright (c) 2003-2008 by Cosylab d. d.
3 *
4 * This file is part of CosyBeans-Common.
5 *
6 * CosyBeans-Common is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CosyBeans-Common is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CosyBeans-Common. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package com.cosylab.gui.components.util;
21
22 import java.awt.Component;
23 import java.awt.Point;
24 import java.awt.event.MouseAdapter;
25 import java.awt.event.MouseEvent;
26
27 import javax.swing.Action;
28 import javax.swing.JComponent;
29 import javax.swing.JPopupMenu;
30 import javax.swing.SwingUtilities;
31
32
33 /**
34 * <code>PopupManager</code> helps simple GUI widget to handle popup menu
35 * in transparent and extensible way.
36 *
37 * @author <a href="mailto:igor.kriznar@cosylab.com">Igor Kriznar</a>
38 * @version $id$
39 */
40 public class PopupManager {
41 private JComponent owner;
42 private ActionList list = new ActionList();
43 private JPopupMenu popup;
44 private boolean enabled=true;
45
46 /**
47 * Constructs a new PopupManager which belongs to the given component.
48 */
49 public PopupManager(JComponent owner) {
50 super();
51 this.owner = owner;
52 }
53
54 /**
55 * Creates manager, which can automatically show a popup menu.
56 * @param owner owner, for which manager manages popup menu
57 * @param auto <code>true</code> if menu popups automatically
58 */
59 public PopupManager(JComponent owner, boolean auto) {
60 super();
61 this.owner = owner;
62
63 if (auto) {
64 owner.addMouseListener(getMouseHook());
65 }
66 }
67
68
69
70 /**
71 * Returns owner of this manager. Usually it it GUI widgets which uses
72 * this manager to manage popup menu.
73 * @return owner of this manager
74 */
75 public JComponent getOwner() {
76 return owner;
77 }
78
79 /**
80 * Adds action to this manager. If action added is null, action is translateed to manu separator.
81 * @param a action to be added, if null, action is translateed to manu separator.
82 */
83 public void addAction(Action a) {
84 list.addAction(a);
85 popup = null;
86 }
87 /**
88 * Adds action to this manager. If action added is null, action is translateed to manu separator.
89 * @param a action to be added, if null, action is translateed to manu separator.
90 */
91 public void addActions(Action[] a) {
92 for (int i = 0; i < a.length; i++) {
93 list.addAction(a[i]);
94 }
95 popup = null;
96 }
97
98 /**
99 * Checks in the manager contains the specified action.
100 *
101 * @param a
102 * @return true if action exists
103 */
104 public boolean containsAction(Action a) {
105 return list.contains(a);
106 }
107
108 /**
109 * Checks if the manager containes action with the specified name.
110 *
111 * @param name the name of the action
112 * @return true if action exists
113 */
114 public boolean containsActionForName(String name) {
115 return list.containsActionWithName(name);
116 }
117
118 /**
119 * Returns the first index of the action in the manager.
120 *
121 * @param a
122 * @return index of action
123 */
124 public int firstIndexOf(Action a) {
125 return list.indexOf(a);
126 }
127
128 /**
129 * Returns the first index of the action with the given name.
130 *
131 * @param name the name of the action
132 * @return index of the action
133 */
134 public int firstIndexOfName(String name) {
135 return list.firstIndexOfActionWithName(name);
136 }
137
138 /**
139 * Returns the action at the given index.
140 *
141 * @param index index of action
142 * @return the action
143 */
144 public Action getAction(int index) {
145 return list.getAction(index);
146 }
147
148 /**
149 * Removes the specified action from the manager.
150 *
151 * @param a the action to be removed
152 */
153 public void removeAction(Action a) {
154 list.removeAction(a);
155 popup = null;
156 }
157
158 /**
159 * Removes the action under the index.
160 *
161 * @param index index at which the action should be removed
162 * @return the removed action
163 */
164 public Action removeAction(int index) {
165 popup = null;
166
167 return list.removeAction(index);
168 }
169
170 /**
171 * Removes the specified actions from the manager
172 *
173 * @param a actions to be removed
174 */
175 public void removeActions(Action[] a) {
176 popup = null;
177
178 for (int i = 0; i < a.length; i++) {
179 list.removeAction(a[i]);
180 }
181 }
182
183 /**
184 * Removes all actions from the manager.
185 *
186 * @return removed actions
187 */
188 public Action[] removeAllActions() {
189 popup = null;
190 Action[] a= list.toArray();
191 list.clear();
192 return a;
193 }
194
195 /**
196 * Returns the number of actions.
197 *
198 * @return
199 */
200 public int actionCount() {
201 return list.size();
202 }
203
204 /**
205 * Returns an array of all action in the manager.
206 *
207 * @return
208 */
209 public Action[] getActions() {
210 return list.toArray();
211 }
212
213 /**
214 * Returns popup menu constructed from actions registered at the manager.
215 * @return popup menu
216 */
217 public JPopupMenu getJPopupMenu() {
218 if (popup == null) {
219 popup = Actions.createPopupMenu(list);
220 }
221
222 return popup;
223 }
224
225 /**
226 * Shows popup menu at given location.
227 * @param x
228 * @param y
229 * @param c
230 */
231 public void showPopup(Component c, int x, int y) {
232 if (list.size() > 0) {
233 getJPopupMenu().show(c, x, y);
234 }
235 }
236
237 /**
238 * Convenience method for creating mouse listener, which fires
239 * this manager to produce popup
240 * @return new mouse listener, which shows popup
241 */
242 private MouseHook mouseHook;
243 public MouseHook getMouseHook() {
244 if (mouseHook == null) {
245 mouseHook = new MouseHook();
246 }
247
248 return mouseHook;
249 }
250
251 private class MouseHook extends MouseAdapter {
252 private Point lastPoint;
253 private Object source;
254
255 /**
256 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
257 */
258 public void mousePressed(MouseEvent e) {
259 if (SwingUtilities.isRightMouseButton(e)) {
260 lastPoint = e.getPoint();
261 source = e.getSource();
262 } else {
263 source = null;
264 lastPoint = null;
265 }
266 }
267
268 /**
269 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
270 */
271 public void mouseReleased(MouseEvent e) {
272 if (SwingUtilities.isRightMouseButton(e)) {
273 if ((e.getSource() == source) && (lastPoint != null)) {
274 //if (lastPoint.distance(e.getPoint()) < 20) {
275 if (enabled) showPopup(e.getComponent(), e.getPoint().x, e.getPoint().y);
276
277 //}
278 }
279
280 lastPoint = null;
281 }
282 }
283 }
284 /**
285 * Returns <code>true</code> if popup manager is enabled and shows popup menu.
286 * @return
287 */
288 public boolean isEnabled() {
289 return enabled;
290 }
291
292 /**
293 * Enambes or disables popup manager.
294 * @param b
295 */
296 public void setEnabled(boolean b) {
297 enabled= b;
298 }
299 }