1 package net.argius.stew.ui.window;
3 import static net.argius.stew.ui.window.Menu.Item.*;
4 import static net.argius.stew.ui.window.Utilities.getImageIcon;
5 import static net.argius.stew.ui.window.Utilities.getMenuShortcutKeyMask;
8 import java.awt.event.*;
11 import java.util.List;
15 import net.argius.stew.*;
20 final class Menu extends JMenuBar implements PropertyChangeListener {
22 private static final ResourceManager res = ResourceManager.getInstance(Menu.class);
50 autoAdjustModeHeaderAndValue,
73 private List<JMenuItem> lockingTargets;
74 private List<JMenuItem> unlockingTargets;
75 private EnumMap<Item, JMenuItem> itemToCompMap;
76 private Map<JMenuItem, Item> compToItemMap;
78 Menu(final AnyActionListener anyActionListener) {
79 this.lockingTargets = new ArrayList<JMenuItem>();
80 this.unlockingTargets = new ArrayList<JMenuItem>();
81 this.itemToCompMap = new EnumMap<Item, JMenuItem>(Item.class);
82 this.compToItemMap = new HashMap<JMenuItem, Item>();
83 final boolean autoMnemonic = res.getInt("auto-mnemonic") == 1;
84 AnyAction aa = new AnyAction(anyActionListener);
85 for (final String groupId : res.get("groups").split(",", -1)) {
86 final String groupKey = "group." + groupId;
87 JMenu group = add(buildGroup(groupId, autoMnemonic));
88 for (final String itemId : res.get(groupKey + ".items").split(",", -1)) {
89 if (itemId.length() == 0) {
90 group.add(new JSeparator());
93 JMenuItem m = group.add(buildItem(itemId, autoMnemonic));
96 item = Item.valueOf(itemId);
97 } catch (Exception ex) {
98 assert false : ex.toString();
101 m.addActionListener(aa);
102 itemToCompMap.put(item, m);
103 compToItemMap.put(m, item);
104 final String shortcutId = "item." + itemId + ".shortcut";
105 if (res.containsKey(shortcutId)) {
106 KeyStroke shortcutKey = KeyStroke.getKeyStroke(res.get(shortcutId));
107 if (shortcutKey != null) {
108 setAccelerator(item, shortcutKey);
121 case widenColumnWidth:
122 case narrowColumnWidth:
123 case adjustColumnWidth:
130 case postProcessMode:
133 lockingTargets.add(m);
136 unlockingTargets.add(m);
142 for (final Item item : EnumSet.of(autoAdjustModeNone,
143 autoAdjustModeHeader,
145 autoAdjustModeHeaderAndValue,
148 postProcessModeFocus,
149 postProcessModeShake,
150 postProcessModeBlink)) {
151 itemToCompMap.get(item).addActionListener(aa);
153 setEnabledStates(false);
156 private static JMenu buildGroup(String groupId, boolean autoMnemonic) {
157 final String key = (res.containsKey("group." + groupId) ? "group" : "item") + '.' + groupId;
158 final char mn = res.getChar(key + ".mnemonic");
159 final String groupString = res.get(key) + (autoMnemonic ? "(" + mn + ")" : "");
160 JMenu group = new JMenu(groupString);
161 group.setMnemonic(mn);
165 private JMenuItem buildItem(String itemId, boolean autoMnemonic) {
166 final String itemKey = "item." + itemId;
167 final char mn = res.getChar(itemKey + ".mnemonic");
169 if (res.isTrue(itemKey + ".checkbox")) {
170 m = new JCheckBoxMenuItem();
171 } else if (res.isTrue(itemKey + ".subgroup")) {
172 m = buildGroup(itemId, autoMnemonic);
173 ButtonGroup buttonGroup = new ButtonGroup();
174 boolean selected = false;
175 for (final String id : res.get(itemKey + ".items").split(",", -1)) {
176 final JMenuItem sub = buildItem(itemId + id, autoMnemonic);
178 buttonGroup.add(sub);
180 sub.setSelected(true);
183 Item subItem = Item.valueOf(itemId + id);
184 itemToCompMap.put(subItem, sub);
185 compToItemMap.put(sub, subItem);
190 m.setText(res.get(itemKey) + (autoMnemonic ? "(" + mn + ")" : ""));
192 m.setActionCommand(itemId);
193 m.setIcon(getImageIcon(String.format("menu-%s.png", itemId)));
194 m.setDisabledIcon(getImageIcon(String.format("menu-disabled-%s.png", itemId)));
199 public void propertyChange(PropertyChangeEvent e) {
200 final String propertyName = e.getPropertyName();
201 final Object source = e.getSource();
202 if (source instanceof JLabel && propertyName.equals("ancestor")) {
203 itemToCompMap.get(showStatusBar).setSelected(((JLabel)source).isVisible());
204 } else if (source instanceof ResultSetTable && propertyName.equals("showNumber")) {
205 itemToCompMap.get(showColumnNumber).setSelected((Boolean)e.getNewValue());
206 } else if (source instanceof DatabaseInfoTree) {
207 itemToCompMap.get(showInfoTree).setSelected(((Component)source).isEnabled());
208 } else if (source instanceof JFrame && propertyName.equals("alwaysOnTop")) {
209 itemToCompMap.get(showAlwaysOnTop).setSelected((Boolean)e.getNewValue());
210 } else if (source instanceof ResultSetTable && propertyName.equals("autoAdjustMode")) {
211 final String itemName = e.getNewValue().toString();
212 if (!itemName.matches("[A-Z_]+")) { // ignore old version
213 itemToCompMap.get(Item.valueOf(itemName)).setSelected(true);
215 } else if (source instanceof WindowOutputProcessor && propertyName.equals("postProcessMode")) {
216 final String itemName = e.getNewValue().toString();
217 if (!itemName.matches("[A-Z_]+")) { // ignore old version
218 itemToCompMap.get(Item.valueOf(itemName)).setSelected(true);
224 * Sets a Accelerator (shortcut key).
228 void setAccelerator(Item item, KeyStroke ks) {
230 final String s = ks.toString();
231 if (s.contains("ctrl")) {
232 m |= getMenuShortcutKeyMask();
234 if (s.contains("alt")) {
235 m |= InputEvent.ALT_DOWN_MASK;
237 if (s.contains("shift")) {
238 m |= InputEvent.SHIFT_DOWN_MASK;
240 itemToCompMap.get(item).setAccelerator(KeyStroke.getKeyStroke(ks.getKeyCode(), m));
244 * Sets the state that command was started or not.
245 * @param commandStarted
247 void setEnabledStates(boolean commandStarted) {
248 final boolean lockingTargetsState = !commandStarted;
249 for (JMenuItem item : lockingTargets) {
250 item.setEnabled(lockingTargetsState);
252 final boolean unlockingTargetsState = commandStarted;
253 for (JMenuItem item : unlockingTargets) {
254 item.setEnabled(unlockingTargetsState);