001: /*
002: * Copyright Javelin Software, All rights reserved.
003: */
004:
005: package com.javelin.swinglets;
006:
007: /**
008: * A SMenu is a (popup) menu for adding SMenuItem's to.
009: *
010: * @author Robin Sharp
011: */
012:
013: import java.awt.*;
014: import java.awt.event.*;
015: import java.io.*;
016: import java.util.*;
017:
018: import com.javelin.swinglets.event.*;
019:
020: public class SMenu extends SMenuItem {
021: /**
022: * Construct a SMenu.
023: */
024: public SMenu() {
025: }
026:
027: /**
028: * Construct a SMenu.
029: */
030: public SMenu(String text) {
031: super (text);
032: }
033:
034: /**
035: * Returns the name of the L&F class that renders this component.
036: */
037: public Class getUIClass() {
038: return SMenu.class;
039: }
040:
041: /**
042: * Returns true if the Menu currently has a component selected
043: */
044: public boolean isSelected() {
045: return selectedIndex >= 0;
046: }
047:
048: /**
049: * Get the selected index
050: */
051: public int getSelectedIndex() {
052: return selectedIndex;
053: }
054:
055: /**
056: * Sets the currently selected component. If this is null,
057: * this will set unselect the menu, and all child menus.
058: */
059: public SMenu setSelected(SComponent component) {
060: if (component == null) {
061: if (selectedIndex >= 0) //Deselect any children
062: {
063: SMenuItem menuItem = getItem(selectedIndex);
064: if (menuItem != null && menuItem instanceof SMenu) {
065: ((SMenu) menuItem).setSelected(null);
066: }
067: }
068: selectedIndex = -1;
069: } else {
070: selectedIndex = menuItems.indexOf(component);
071: }
072:
073: return this ;
074: }
075:
076: /**
077: * Deselects this menu component, and all parent components.
078: */
079: public void deSelectToRoot() {
080: if (getParentMenu() != null) {
081: selectedIndex = -1;
082: ((SMenu) getParentMenu()).deSelectToRoot();
083: } else if (getParent() != null
084: && getParent() instanceof SMenuBar) {
085: ((SMenuBar) getParent()).setSelected(null);
086: }
087: }
088:
089: /**
090: * Returns the number of items on the menu, including separators.
091: */
092: public int getItemCount() {
093: return menuItems.size();
094: }
095:
096: /**
097: * Get the nth SComponent.
098: */
099: public SComponent getComponent(int index) {
100: return (SComponent) menuItems.elementAt(index);
101: }
102:
103: /**
104: * Get a sub menu by name. This will descend the menu
105: * hierarchy and return the SComponent, or null.
106: */
107: public SComponent getComponent(String name) {
108: if (getName().equals(name))
109: return this ;
110:
111: SComponent component = null;
112: for (int index = 0; index < getItemCount(); index++) {
113: if ((component = getComponent(index).getComponent(name)) != null) {
114: return component;
115: }
116: }
117:
118: return null;
119: }
120:
121: /**
122: * Get the index of this menu in its parents menu, or -1
123: */
124: public int getIndex() {
125: if (getParentMenu() != null) {
126: return getParentMenu().getComponentIndex(this );
127: } else if (getParent() != null
128: && getParent() instanceof SMenuBar) {
129: return ((SMenuBar) getParent()).getComponentIndex(this );
130: }
131:
132: return -1;
133:
134: }
135:
136: /**
137: * Get the index of this component, or -1.
138: */
139: public int getComponentIndex(SComponent c) {
140: return menuItems.indexOf(c);
141: }
142:
143: /**
144: * Returns the SMenuItem at the specified position, or
145: * null if it is a separator (SLabel)
146: */
147: public SMenuItem getItem(int index) {
148: if (index < 0 || index > getItemCount()) {
149: throw new IllegalArgumentException("Invalid index " + index);
150: }
151:
152: SComponent c = (SComponent) menuItems.elementAt(index);
153: if (c instanceof SMenuItem) {
154: SMenuItem menuItem = (SMenuItem) c;
155: return menuItem;
156: }
157:
158: return null;
159: }
160:
161: /**
162: * Appends a menuitem to the end of this menu.
163: * Returns the menuitem added.
164: */
165: public SMenuItem add(SMenuItem menuItem) {
166: menuItems.addElement(menuItem);
167:
168: menuItem.setParentMenu(this );
169:
170: return menuItem;
171: }
172:
173: /**
174: * Creates a new menuitem with the specified text and appends
175: * it to the end of this menu.
176: */
177: public SMenuItem add(String string) {
178: return add(new SMenuItem(string));
179: }
180:
181: /**
182: * Append a new separator to the end of the menu.
183: */
184: public void addSeparator() {
185: menuItems.addElement(new SLabel(""));
186: }
187:
188: /**
189: * Insert a new menuitem with the specified text at a
190: * given position.
191: */
192: public void insert(String text, int index) {
193: if (index < 0) {
194: throw new IllegalArgumentException("Invalid index " + index);
195: }
196:
197: if (index < menuItems.size()) {
198: menuItems.insertElementAt(new SMenuItem(text), index);
199: } else {
200: menuItems.addElement(new SMenuItem(text));
201: }
202:
203: }
204:
205: /**
206: * Insert the specified SMenuItem at a given position.
207: */
208: public SMenuItem insert(SMenuItem menuItem, int index) {
209: if (index < 0) {
210: throw new IllegalArgumentException("Invalid index " + index);
211: }
212:
213: if (index < menuItems.size()) {
214: menuItems.insertElementAt(menuItem, index);
215: } else {
216: menuItems.addElement(menuItem);
217: }
218:
219: menuItem.setParentMenu(this );
220:
221: return menuItem;
222: }
223:
224: /**
225: * Inserts a separator at the specified position, or at the end of the
226: * list if greater. A Separator is a SLabel.
227: */
228: public void insertSeparator(int index) {
229: if (index < 0) {
230: throw new IllegalArgumentException("Invalid index " + index);
231: }
232:
233: if (index < menuItems.size()) {
234: menuItems.insertElementAt(new SLabel(""), index);
235: } else {
236: menuItems.addElement(new SLabel(""));
237: }
238:
239: }
240:
241: /**
242: * Removes the specified menu item from this menu.
243: */
244: public void remove(SMenuItem menuItem) {
245: remove(menuItem);
246: }
247:
248: /**
249: * Removes the menu item at the specified index from this menu.
250: */
251: public void remove(int index) {
252: if (index < 0 || index > getItemCount()) {
253: throw new IllegalArgumentException("Invalid index " + index);
254: }
255:
256: remove((SComponent) menuItems.elementAt(index));
257: }
258:
259: /**
260: * Removes the SComponent from this menu.
261: */
262: public void remove(SComponent c) {
263: if (c instanceof SMenuItem) {
264: ((SMenuItem) c).setParentMenu(null);
265: }
266: menuItems.removeElement(c);
267: }
268:
269: /**
270: * Remove all menu items from this menu.
271: */
272: public void removeAll() {
273: for (int index = 0; index < menuItems.size(); index++) {
274: ((SMenuItem) menuItems.elementAt(index))
275: .setParentMenu(null);
276: }
277:
278: menuItems.removeAllElements();
279: }
280:
281: /**
282: * Processes events occurring on this component.
283: */
284: protected void processEvent(AWTEvent event) {
285: if (event instanceof FormEvent) {
286: processFormEvent((FormEvent) event);
287: }
288: }
289:
290: /**
291: * Process the FormEvent to compute which menu item has been
292: * selected.
293: * <p>
294: * If this is branch node the display the children, by updating
295: * the selected item value.
296: * <p>
297: * If this is a leaf node then notify the node that it has
298: * been selected through an action event.
299: */
300: protected void processFormEvent(FormEvent event) {
301: //System.out.println( "SMenu.processFormEvent\n" + event );
302: //Reset the selected index, unless otherwise stated.
303: selectedIndex = -1;
304:
305: //System.out.println( event );
306: for (Enumeration names = event.getParameterNames(); names
307: .hasMoreElements();) {
308: String name = (String) names.nextElement();
309: if (Character.isDigit(name.charAt(0))) {
310: int index = name.indexOf('.');
311: int menuIndex = -1;
312: if (index >= 0) {
313: menuIndex = Integer.parseInt(name.substring(0,
314: index));
315: } else {
316: menuIndex = Integer.parseInt(name);
317: }
318:
319: //Check to see if the selected index was a menu or a menuItem
320: //If it was a menu item then fire an action event and reset the
321: //selected index
322: Object menuItem = menuItems.elementAt(menuIndex);
323: if (menuItem != null) {
324: //System.out.println( getText() + "-" + menuItem.getClass().getName() +"-" + ((SMenuItem)menuItem).getText() );
325: if (menuItem instanceof SMenu) {
326: selectedIndex = menuIndex;
327: } else if (menuItem instanceof SMenuItem) {
328: //If this is a back icon
329: ((SMenuItem) menuItem)
330: .dispatchEvent(new ActionEvent(
331: menuItem,
332: ActionEvent.ACTION_PERFORMED,
333: null));
334: setSelected(null);
335: deSelectToRoot();
336: }
337: }
338: }
339: }
340: }
341:
342: // PRIVATE //////////////////////////////////////////////////////////
343:
344: protected Vector menuItems = new Vector();
345: protected int selectedIndex = -1;
346:
347: }
|