001: /*
002: #IFNDEF ALT_LICENSE
003: ThinWire(R) RIA Ajax Framework
004: Copyright (C) 2003-2007 Custom Credit Systems
005:
006: This library is free software; you can redistribute it and/or modify it under
007: the terms of the GNU Lesser General Public License as published by the Free
008: Software Foundation; either version 2.1 of the License, or (at your option) any
009: later version.
010:
011: This library is distributed in the hope that it will be useful, but WITHOUT ANY
012: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013: PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
014:
015: You should have received a copy of the GNU Lesser General Public License along
016: with this library; if not, write to the Free Software Foundation, Inc., 59
017: Temple Place, Suite 330, Boston, MA 02111-1307 USA
018:
019: Users who would rather have a commercial license, warranty or support should
020: contact the following company who invented, built and supports the technology:
021:
022: Custom Credit Systems, Richardson, TX 75081, USA.
023: email: info@thinwire.com ph: +1 (888) 644-6405
024: http://www.thinwire.com
025: #ENDIF
026: [ v1.2_RC2 ]
027: */
028: package thinwire.ui;
029:
030: import thinwire.ui.event.ActionEvent;
031: import thinwire.ui.event.KeyPressEvent;
032:
033: /**
034: * A component that displays a set of hierarchical data as a menu.
035: * <p>
036: * <b>Example:</b> <br>
037: * <img src="doc-files/Menu-1.png"> <br>
038: *
039: * <pre>
040: * Dialog dlg = new Dialog("Menu Test");
041: * dlg.setBounds(25, 25, 200, 200);
042: *
043: * Menu mainMenu = new Menu();
044: * Menu.Item fileItem = new Menu.Item("File");
045: * Menu.Item newItem = new Menu.Item("New");
046: * newItem.setUserObject("You clicked on the File->New menu item");
047: * Menu.Item openItem = new Menu.Item("Open");
048: * openItem.setUserObject("You clicked on the File->Open menu item");
049: *
050: * mainMenu.addActionListener(Menu.ACTION_CLICK, new ActionListener() {
051: * public void actionPerformed(ActionEvent ev) {
052: * Menu.Item selectedItem = (Menu.Item) ev.getSource();
053: * MessageBox.confirm("resources/ngLF/system.png", "Menu Test", (String) selectedItem.getUserObject());
054: * }
055: * });
056: *
057: * dlg.setMenu(mainMenu);
058: * mainMenu.getRootItem().getChildren().add(fileItem);
059: * fileItem.getChildren().add(newItem);
060: * fileItem.getChildren().add(openItem);
061: * dlg.setVisible(true);
062: * </pre>
063: *
064: * </p>
065: * <p>
066: * <b>Keyboard Navigation:</b><br>
067: * <table border="1">
068: * <tr>
069: * <td>KEY</td>
070: * <td>RESPONSE</td>
071: * <td>NOTE</td>
072: * </tr>
073: * </table>
074: * </p>
075: *
076: * @author Joshua J. Gertzen
077: */
078: public class Menu extends AbstractHierarchyComponent<Menu.Item> {
079: /**
080: * An object that represents an item in a <code>Menu</code> component.
081: */
082: public static class Item extends
083: AbstractHierarchyComponent.Item<Menu, Menu.Item> {
084: public static final String PROPERTY_ITEM_ENABLED = "itemEnabled";
085: public static final String PROPERTY_ITEM_KEY_PRESS_COMBO = "itemKeyPressCombo";
086:
087: private String keyPressCombo = "";
088: private boolean enabled = true;
089:
090: /**
091: * Constructs a new Item with no text and no image.
092: */
093: public Item() {
094: this (null, null, null);
095: }
096:
097: /**
098: * Constructs a new Item with the specified text and no image.
099: * @param text the text to display for the item.
100: */
101: public Item(String text) {
102: this (text, null, null);
103: }
104:
105: /**
106: * Constructs a new Item with the specified text and image.
107: * @param text the text to display for the item.
108: * @param image the image to display to the left of the text of the item.
109: */
110: public Item(String text, String image) {
111: this (text, image, null);
112: }
113:
114: /**
115: * Constructs a new Item with the specified text and image.
116: * @param text the text to display for the item.
117: * @param image the image to display to the left of the text of the item.
118: * @param keyPressCombo the key combination to associate to this Menu.Item.
119: */
120: public Item(String text, String image, String keyPressCombo) {
121: if (text != null)
122: setText(text);
123: if (image != null)
124: setImage(image);
125: if (keyPressCombo != null)
126: setKeyPressCombo(keyPressCombo);
127: }
128:
129: /**
130: * Returns whether the item is selectable (enabled).
131: * @return true if the field is enabled (Default = true)
132: */
133: public final boolean isEnabled() {
134: return this .enabled;
135: }
136:
137: /**
138: * Sets the enabled property of the item
139: * @param enabled True to make editable, false to disable the component (Default = true)
140: */
141: public final void setEnabled(boolean enabled) {
142: boolean oldEnabled = this .enabled;
143: this .enabled = enabled;
144: Menu menu = getHierarchy();
145: if (menu != null)
146: menu.firePropertyChange(this , PROPERTY_ITEM_ENABLED,
147: oldEnabled, enabled);
148: }
149:
150: /**
151: * Get a text representation of the key combo that will activate this item.
152: * @return the text representation of the key combo that will activate this item,
153: * or an empty string if no key combo is set for this item.
154: */
155: public String getKeyPressCombo() {
156: return keyPressCombo;
157: }
158:
159: /**
160: * Set the key combo / shortcut that will activate this item.
161: * Once a key press combo is set, pressing the key combination
162: * within the window that this menu is attached to will cause
163: * the fireAction method to be called with the action set to "click".
164: * @param keyPressCombo key combo to assign to this item.
165: * @see thinwire.ui.event.KeyPressEvent#encodeKeyPressCombo(boolean, boolean, boolean, String)
166: */
167: public void setKeyPressCombo(String keyPressCombo) {
168: String oldKeyPressCombo = this .keyPressCombo;
169: keyPressCombo = keyPressCombo == null
170: || keyPressCombo.length() == 0 ? "" : KeyPressEvent
171: .normalizeKeyPressCombo(keyPressCombo);
172: this .keyPressCombo = keyPressCombo;
173: Menu menu = getHierarchy();
174: if (menu != null)
175: menu.firePropertyChange(this ,
176: PROPERTY_ITEM_KEY_PRESS_COMBO,
177: oldKeyPressCombo, keyPressCombo);
178: }
179:
180: public String toString() {
181: return "Menu.Item{" + super .toString() + ",enabled:"
182: + this .isEnabled() + ",keyPressCombo:"
183: + this .getKeyPressCombo() + "}";
184: }
185: }
186:
187: /**
188: * Constructs a new Menu.
189: */
190: public Menu() {
191: super (new Item(), new EventListenerImpl.SubTypeValidator() {
192: public Object validate(Object subType) {
193: return subType != null
194: && (subType.equals(ACTION_CLICK)) ? subType
195: : null;
196: }
197: });
198: }
199:
200: public void fireAction(ActionEvent ev) {
201: if (ev == null)
202: throw new IllegalArgumentException("ev == null");
203: if (!ev.getAction().equals(ACTION_CLICK))
204: throw new IllegalArgumentException(
205: "!ev.getAction().equals(ACTION_CLICK)");
206: super .fireAction(ev);
207: }
208:
209: public int getHeight() {
210: Container cont = getContainer();
211:
212: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
213: return AbstractWindow.MENU_BAR_HEIGHT;
214: } else {
215: return super .getHeight();
216: }
217: }
218:
219: public void setHeight(int height) {
220: Container cont = getContainer();
221:
222: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
223: throw new UnsupportedOperationException(
224: getStandardPropertyUnsupportedMsg(PROPERTY_HEIGHT,
225: false));
226: } else {
227: super .setHeight(height);
228: }
229: }
230:
231: public int getWidth() {
232: Container cont = getContainer();
233:
234: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
235: return cont.getInnerWidth();
236: } else {
237: return super .getWidth();
238: }
239: }
240:
241: public void setWidth(int width) {
242: Container cont = getContainer();
243:
244: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
245: throw new UnsupportedOperationException(
246: getStandardPropertyUnsupportedMsg(PROPERTY_WIDTH,
247: false));
248: } else {
249: super .setWidth(width);
250: }
251: }
252:
253: public int getX() {
254: Container cont = getContainer();
255:
256: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
257: return 0;
258: } else {
259: return super .getX();
260: }
261: }
262:
263: public void setX(int x) {
264: Container cont = getContainer();
265:
266: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
267: throw new UnsupportedOperationException(
268: getStandardPropertyUnsupportedMsg(PROPERTY_X, false));
269: } else {
270: super .setX(x);
271: }
272: }
273:
274: public int getY() {
275: Container cont = getContainer();
276:
277: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
278: return 0;
279: } else {
280: return super .getY();
281: }
282: }
283:
284: public void setY(int y) {
285: Container cont = getContainer();
286:
287: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
288: throw new UnsupportedOperationException(
289: getStandardPropertyUnsupportedMsg(PROPERTY_Y, false));
290: } else {
291: super .setY(y);
292: }
293: }
294:
295: public boolean isVisible() {
296: Container cont = getContainer();
297:
298: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
299: return true;
300: } else {
301: return super .isVisible();
302: }
303: }
304:
305: public void setVisible(boolean visible) {
306: Container cont = getContainer();
307:
308: if (cont instanceof Window && ((Window) cont).getMenu() == this ) {
309: throw new UnsupportedOperationException(
310: getStandardPropertyUnsupportedMsg(PROPERTY_VISIBLE,
311: false));
312: } else {
313: super.setVisible(visible);
314: }
315: }
316: }
|