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.event.ActionEvent;
23
24 import java.util.ArrayList;
25 import java.util.Iterator;
26
27 import javax.swing.AbstractAction;
28 import javax.swing.Action;
29 import javax.swing.Icon;
30
31
32 /**
33 * <p>
34 * An action which holds a list of other <code>Action</code> objects.
35 * Convenient for containment of functionally similar actions.
36 * </p>
37 *
38 * <p>
39 * With asotiation with <code>Action</code> can be used for creation of menus.
40 * Set <code>putValue(MENU_CONTEXT,MENU_CONTEXT_RADIO)</code> to produce group
41 * of radio menu items.
42 * </p>
43 *
44 * <p>
45 * <code>Action</code> will use separator menu item, where null
46 * actionitemisplaced or Action has <code>SEPARATOR</code> boolean attribute.
47 * </p>
48 *
49 * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
50 * @version $id$
51 */
52 public class ActionList extends AbstractAction
53 {
54 private static final long serialVersionUID = 1L;
55
56 /**
57 * Key name for a Boolean value indicating that the added action should be
58 * represented in the GUI as a separator.
59 */
60 public static final String SEPARATOR = "_group_separator_";
61
62 /**
63 * Key name for a String value indicating if this list is to be presented
64 * in menu with buttons or radio buttons.
65 *
66 * @see javax.swing.Action#getValue(java.lang.String)
67 */
68 public static final String MENU_CONTEXT = "menuContext";
69
70 /** DOCUMENT ME! */
71 public static final String MENU_CONTEXT_BUTTON = "button";
72
73 /** DOCUMENT ME! */
74 public static final String MENU_CONTEXT_RADIO = "radio";
75
76 /** DOCUMENT ME! */
77 public static String ACTIONS = "actions";
78 private ArrayList<Action> actions = null;
79
80 /**
81 * Creates a new ActionList object.
82 */
83 public ActionList()
84 {
85 this(null, null);
86 }
87
88 /**
89 * Creates a new ActionList object.
90 *
91 * @param name
92 */
93 public ActionList(String name)
94 {
95 this(name, null);
96 }
97
98 /**
99 * Creates a new ActionList object.
100 *
101 * @param name
102 * @param icon
103 */
104 public ActionList(String name, Icon icon)
105 {
106 this(name, icon, null);
107 }
108
109 /**
110 * Creates a new ActionList object.
111 *
112 * @param name
113 * @param icon
114 * @param actions
115 */
116 public ActionList(String name, Icon icon, Action[] actions)
117 {
118 super(name, icon);
119 this.actions = new ArrayList<Action>();
120
121 if (actions != null) {
122 for (int i = 0; i < actions.length; i++) {
123 this.actions.add(actions[i]);
124 }
125
126 putValue(ACTIONS, this.actions.toArray(new Action[size()]));
127 }
128
129 putValue(MENU_CONTEXT, MENU_CONTEXT_BUTTON);
130 }
131
132 /**
133 * Adds Action to end of the list.
134 *
135 * @param action Action to be added
136 */
137 public void addAction(Action action)
138 {
139 addAction(size(), action);
140 }
141
142 /**
143 * Checks if this list contains the given action.
144 *
145 * @param action
146 *
147 * @return true if action exists in the list
148 */
149 public boolean contains(Action action)
150 {
151 return actions.contains(action);
152 }
153
154 /**
155 * Checks if the list containes action with the given name.
156 *
157 * @param name name of the action
158 *
159 * @return true if action is present in the list
160 */
161 public boolean containsActionWithName(String name)
162 {
163 return (firstIndexOfActionWithName(name) < 0);
164 }
165
166 /**
167 * Returns the index of the first action with the given name.
168 *
169 * @param name name of the action
170 *
171 * @return index of the action in the list
172 */
173 public int firstIndexOfActionWithName(String name)
174 {
175 for (Iterator iter = actions.iterator(); iter.hasNext();) {
176 Action element = (Action)iter.next();
177
178 if ((element != null) && element.getValue(NAME).equals(name)) {
179 return actions.indexOf(element);
180 }
181 }
182
183 return -1;
184 }
185
186 /**
187 * Adds all actions from ActionList to end of the this list in specified
188 * order.
189 *
190 * @param action actions to be added
191 */
192 public void addAll(ActionList action)
193 {
194 Action[] a = action.toArray();
195
196 for (int i = 0; i < a.length; i++) {
197 addAction(a[i]);
198 }
199 }
200
201 /* (non-Javadoc)
202 * @see com.cosylab.gui.components.util.ActionList#addAction(javax.swing.Action, int)
203 */
204 public synchronized void addAction(int index, Action action)
205 {
206 actions.add(index, action);
207 putValue(ACTIONS, actions.toArray(new Action[size()]));
208 }
209
210 /**
211 * Returns Action under provided index.
212 *
213 * @param index the index of requested action
214 *
215 * @return the action
216 */
217 public synchronized Action getAction(int index)
218 {
219 return (Action)actions.get(index);
220 }
221
222 /**
223 * Returns Action which command ID corresponds to the provided parameter.
224 *
225 * @param ID the command key string of action
226 *
227 * @return Action which command ID corresponds to the provided parameter
228 *
229 * @see Action#ACTION_COMMAND_KEY
230 */
231 public synchronized Action getAction(String ID)
232 {
233 Iterator it = actions.iterator();
234
235 while (it.hasNext()) {
236 Action a = (Action)it.next();
237
238 if (ID.equals(a.getValue(ACTION_COMMAND_KEY))) {
239 return a;
240 }
241 }
242
243 return null;
244 }
245
246 /* (non-Javadoc)
247 * @see com.cosylab.gui.components.util.ActionList#indexOf(javax.swing.Action)
248 */
249 public int indexOf(Action action)
250 {
251 return actions.indexOf(action);
252 }
253
254 /* (non-Javadoc)
255 * @see com.cosylab.gui.components.util.ActionList#removeAction(javax.swing.Action)
256 */
257 public void removeAction(Action action)
258 {
259 actions.remove(action);
260 putValue(ACTIONS, actions.toArray(new Action[size()]));
261 }
262
263 /* (non-Javadoc)
264 * @see com.cosylab.gui.components.util.ActionList#removeAction(int)
265 */
266 public Action removeAction(int index)
267 {
268 Action a = (Action)actions.remove(index);
269 putValue(ACTIONS, actions.toArray(new Action[size()]));
270
271 return a;
272 }
273
274 /**
275 * Returns the size of this list (number of actions in the list).
276 *
277 * @return the size
278 */
279 public int size()
280 {
281 return actions.size();
282 }
283
284 /*
285 * (non-Javadoc)
286 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
287 */
288 public void actionPerformed(ActionEvent e)
289 {
290 }
291
292 /**
293 * Returns all contained actions in an array.
294 *
295 * @return returns all contained actions in an array
296 */
297 public Action[] toArray()
298 {
299 return (Action[])actions.toArray(new Action[actions.size()]);
300 }
301
302 /**
303 * Returns iterator over contained actions.
304 *
305 * @return iterator over contained actions
306 */
307 public Iterator iterator()
308 {
309 return actions.iterator();
310 }
311
312 /**
313 * Removes all actions from this list.
314 *
315 */
316 public void clear()
317 {
318 actions.clear();
319 }
320 }
321
322 /* __oOo__ */