001: package net.suberic.util.gui;
002:
003: import javax.swing.*;
004: import net.suberic.util.VariableBundle;
005: import java.util.Hashtable;
006: import java.util.StringTokenizer;
007: import java.util.MissingResourceException;
008: import javax.swing.Action;
009:
010: /**
011: * This is a JMenu which implements the ConfigurableUI interface, and
012: * therefore may be dynamically created using a VariableBundle and key,
013: * and updated using an array of Actions.
014: */
015:
016: public class ConfigurableMenu extends JMenu implements ConfigurableUI {
017:
018: // the latest commands list. i'm storing this for now because i
019: // can't do a JButton.removeActionListeners().
020:
021: protected Hashtable commands = new Hashtable();
022:
023: public ConfigurableMenu() {
024: super ();
025: }
026:
027: /**
028: * This creates a new ConfigurableMenu using the menuID as the
029: * configuration key, and vars as the source for the values of all the
030: * properties.
031: *
032: * If menuID doesn't exist in vars, then this returns an empty
033: * Menu.
034: */
035:
036: public ConfigurableMenu(String menuID, VariableBundle vars) {
037: super ();
038:
039: configureComponent(menuID, vars);
040: }
041:
042: /**
043: * This configures the Menu using the given menuID and
044: * VariableBundle.
045: *
046: * As defined in interface net.suberic.util.gui.ConfigurableUI.
047: */
048:
049: public void configureComponent(String key, VariableBundle vars) {
050: StringTokenizer iKeys = null;
051: try {
052: iKeys = new StringTokenizer(vars.getProperty(key), ":");
053: } catch (MissingResourceException mre) {
054: mre.printStackTrace();
055: try {
056: System.err.println(vars
057: .getProperty("error.NoSuchResource")
058: + " " + mre.getKey());
059: } catch (MissingResourceException mretwo) {
060: System.err.println("Unable to load resource "
061: + mre.getKey());
062: return;
063: }
064: return;
065: }
066: String currentToken;
067:
068: try {
069: setText(vars.getProperty(key + ".Label"));
070: } catch (MissingResourceException mre) {
071: }
072:
073: while (iKeys.hasMoreTokens()) {
074: currentToken = iKeys.nextToken();
075: if (currentToken.equals("-")) {
076: this .addSeparator();
077: } else {
078: JMenuItem mi = createMenuItem(key, currentToken, vars);
079: this .add(mi);
080: }
081: }
082:
083: String keyBinding = vars.getProperty(key + ".KeyBinding", "");
084: if (!keyBinding.equals("")) {
085: this .setMnemonic(keyBinding.charAt(0));
086: }
087:
088: }
089:
090: /**
091: * And this actually creates the menu items themselves.
092: */
093: protected JMenuItem createMenuItem(String menuID,
094: String menuItemID, VariableBundle vars) {
095: // TODO: should also make these undo-able.
096:
097: if (vars.getProperty(menuID + "." + menuItemID + ".class", "") == "") {
098:
099: if (vars.getProperty(menuID + "." + menuItemID, "") != "") {
100: return new ConfigurableMenu(menuID + "." + menuItemID,
101: vars);
102: }
103:
104: JMenuItem mi;
105: try {
106: mi = new JMenuItem(vars.getProperty(menuID + "."
107: + menuItemID + ".Label"));
108: } catch (MissingResourceException mre) {
109: mi = new JMenuItem(menuItemID);
110: }
111:
112: java.net.URL url = null;
113:
114: try {
115: url = this .getClass().getResource(
116: vars.getProperty(menuID + "." + menuItemID
117: + ".Image"));
118: } catch (MissingResourceException mre) {
119: }
120:
121: if (url != null) {
122: mi.setHorizontalTextPosition(JButton.RIGHT);
123: mi.setIcon(new ImageIcon(url));
124: }
125:
126: String cmd = vars.getProperty(menuID + "." + menuItemID
127: + ".Action", menuItemID);
128:
129: mi.setActionCommand(cmd);
130:
131: String keyBinding = vars.getProperty(menuID + "."
132: + menuItemID + ".KeyBinding", "");
133: if (!keyBinding.equals(""))
134: mi.setMnemonic(keyBinding.charAt(0));
135:
136: String accelBinding = vars.getProperty(menuID + "."
137: + menuItemID + ".Accelerator", "");
138: if (!accelBinding.equals("")) {
139: mi.setAccelerator(KeyStroke.getKeyStroke(accelBinding));
140: }
141:
142: return mi;
143: } else {
144: // this means that we have a submenu.
145: ConfigurableMenu m;
146:
147: if (vars.getProperty(menuID + "." + menuItemID + ".class",
148: "").equals("")) {
149: m = new ConfigurableMenu(menuID + "." + menuItemID,
150: vars);
151:
152: } else {
153: // this means we're using a custom Menu.
154:
155: try {
156: Class menuClass = Class.forName(vars.getProperty(
157: menuID + "." + menuItemID + ".class",
158: "net.suberic.util.gui.ConfigurableMenu"));
159: m = (ConfigurableMenu) menuClass.newInstance();
160: m.configureComponent(menuID + "." + menuItemID,
161: vars);
162: } catch (Exception e) {
163: e.printStackTrace();
164: // if we get any errors, just create a plain
165: // ConfigurableMenu.
166: m = new ConfigurableMenu(menuID + "." + menuItemID,
167: vars);
168: }
169: }
170:
171: return m;
172:
173: }
174: }
175:
176: /**
177: * As defined in net.suberic.util.gui.ConfigurableUI
178: */
179: public void setActive(javax.swing.Action[] newActions) {
180: Hashtable tmpHash = new Hashtable();
181: if (newActions != null && newActions.length > 0) {
182: for (int i = 0; i < newActions.length; i++) {
183: String cmdName = (String) newActions[i]
184: .getValue(Action.NAME);
185: tmpHash.put(cmdName, newActions[i]);
186: }
187: }
188: setActive(tmpHash);
189: }
190:
191: /**
192: * As defined in net.suberic.util.gui.ConfigurableUI
193: */
194: public void setActive(Hashtable newCommands) {
195: clearListeners();
196: commands = newCommands;
197: setActiveMenuItems();
198: }
199:
200: protected void setActiveMenuItems() {
201: for (int j = 0; j < getItemCount(); j++) {
202: if (getItem(j) instanceof ConfigurableMenu) {
203: ((ConfigurableMenu) getItem(j)).setActive(commands);
204: } else {
205: JMenuItem mi = getItem(j);
206: Action a = getAction(mi.getActionCommand());
207: if (a != null) {
208: //mi.removeActionListener(a);
209: mi.addActionListener(a);
210: mi.setEnabled(true);
211: } else {
212: mi.setEnabled(false);
213: }
214: }
215: }
216: }
217:
218: /**
219: * This clears all of the current listeners on the Menu.
220: */
221:
222: private void clearListeners() {
223: for (int j = 0; j < getItemCount(); j++) {
224: if (getItem(j) instanceof ConfigurableMenu) {
225: // we don't have to clear the listeners here because
226: // it will be done in setActive().
227: ;
228: } else {
229: JMenuItem mi = getItem(j);
230: Action a = getAction(mi.getActionCommand());
231: if (a != null) {
232: mi.removeActionListener(a);
233: }
234: }
235: }
236: }
237:
238: /**
239: * This gets an action from the supported commands. If there is no
240: * supported action, it returns null
241: */
242:
243: public Action getAction(String command) {
244: return (Action) commands.get(command);
245: }
246:
247: }
|