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;
10 import java.util.Map.Entry;
11 import java.util.List;
12 import java.util.regex.*;
16 import net.argius.stew.*;
21 final class Menu extends JMenuBar implements PropertyChangeListener {
23 private static final ResourceManager res = ResourceManager.getInstance(Menu.class);
51 autoAdjustModeHeaderAndValue,
73 static Item of(String name) {
76 } catch (IllegalArgumentException ex) {
82 private List<JMenuItem> lockingTargets;
83 private List<JMenuItem> unlockingTargets;
84 private EnumMap<Item, JMenuItem> itemToCompMap;
86 Menu(final AnyActionListener anyActionListener) {
87 this.lockingTargets = new ArrayList<JMenuItem>();
88 this.unlockingTargets = new ArrayList<JMenuItem>();
89 this.itemToCompMap = new EnumMap<Item, JMenuItem>(Item.class);
90 Map<String, JMenuItem> itemMap = new HashMap<String, JMenuItem>();
91 AnyAction aa = new AnyAction(anyActionListener);
92 for (final String groupId : res.get("groups").split(",", -1)) {
93 JMenu m = add(createJMenu(res, groupId));
94 for (final JMenuItem o : createJMenuItems(res, itemMap, "group." + groupId)) {
96 m.add(new JSeparator());
100 final String itemId = o.getActionCommand();
101 Item itemEnum = Item.of(itemId);
102 o.addActionListener(aa);
103 itemToCompMap.put(itemEnum, o);
114 case widenColumnWidth:
115 case narrowColumnWidth:
116 case adjustColumnWidth:
123 case postProcessMode:
126 lockingTargets.add(o);
129 unlockingTargets.add(o);
135 for (JMenuItem parent : Arrays.asList(itemToCompMap.get(autoAdjustMode),
136 itemToCompMap.get(postProcessMode))) {
137 for (MenuElement menuGroup : parent.getSubElements()) {
138 for (MenuElement child : menuGroup.getSubElements()) {
139 JMenuItem o = (JMenuItem)child;
140 itemToCompMap.put(Item.of(o.getActionCommand()), o);
144 refreshAllAccelerators(itemMap);
145 setEnabledStates(false);
149 public void propertyChange(PropertyChangeEvent e) {
150 final String propertyName = e.getPropertyName();
151 final Object source = e.getSource();
152 if (source instanceof JLabel && propertyName.equals("ancestor")) {
153 itemToCompMap.get(showStatusBar).setSelected(((JLabel)source).isVisible());
154 } else if (source instanceof ResultSetTable && propertyName.equals("showNumber")) {
155 itemToCompMap.get(showColumnNumber).setSelected((Boolean)e.getNewValue());
156 } else if (source instanceof DatabaseInfoTree) {
157 itemToCompMap.get(showInfoTree).setSelected(((Component)source).isEnabled());
158 } else if (source instanceof JFrame && propertyName.equals("alwaysOnTop")) {
159 itemToCompMap.get(showAlwaysOnTop).setSelected((Boolean)e.getNewValue());
160 } else if (source instanceof ResultSetTable && propertyName.equals("autoAdjustMode")) {
161 final String itemName = e.getNewValue().toString();
162 if (!itemName.matches("[A-Z_]+")) { // ignore old version
163 itemToCompMap.get(Item.of(itemName)).setSelected(true);
165 } else if (source instanceof WindowOutputProcessor && propertyName.equals("postProcessMode")) {
166 final String itemName = e.getNewValue().toString();
167 if (!itemName.matches("[A-Z_]+")) { // ignore old version
168 itemToCompMap.get(Item.of(itemName)).setSelected(true);
174 * Sets the state that command was started or not.
175 * @param commandStarted
177 void setEnabledStates(boolean commandStarted) {
178 final boolean lockingTargetsState = !commandStarted;
179 for (JMenuItem item : lockingTargets) {
180 item.setEnabled(lockingTargetsState);
182 final boolean unlockingTargetsState = commandStarted;
183 for (JMenuItem item : unlockingTargets) {
184 item.setEnabled(unlockingTargetsState);
188 // Menu factory utilities
190 private static JMenu createJMenu(ResourceManager rm, String groupId) {
191 final String key = (rm.containsKey("group." + groupId) ? "group" : "item") + '.' + groupId;
192 final char mn = rm.getChar(key + ".mnemonic");
193 final boolean autoMnemonic = rm.getInt("auto-mnemonic") == 1;
194 final String groupString = rm.get(key) + (autoMnemonic ? "(" + mn + ")" : "");
195 JMenu group = new JMenu(groupString);
196 group.setMnemonic(mn);
200 private static void refreshAllAccelerators(Map<String, JMenuItem> itemMap) {
201 // This method is called everytime menu and popup-menu is created.
202 File keyBindConf = Bootstrap.getSystemFile("keybind.conf");
203 if (!keyBindConf.exists()) {
206 Map<String, KeyStroke> keyMap = new HashMap<String, KeyStroke>();
208 Scanner r = new Scanner(keyBindConf);
210 final Pattern p = Pattern.compile("\\s*([^=\\s]+)\\s*=(.*)");
211 while (r.hasNextLine()) {
212 final String line = r.nextLine();
216 if (line.trim().length() == 0 || line.matches("\\s*#.*")) {
219 Matcher m = p.matcher(line);
221 keyMap.put(m.group(1), Utilities.getKeyStroke(m.group(2)));
227 } catch (FileNotFoundException ex) {
228 throw new RuntimeException(ex);
230 for (final Entry<String, KeyStroke> entry : keyMap.entrySet()) {
231 final String k = entry.getKey();
232 if (itemMap.containsKey(k)) {
233 itemMap.get(k).setAccelerator(entry.getValue());
238 static List<JMenuItem> createJMenuItems(ResourceManager rm, String groupKey) {
239 HashMap<String, JMenuItem> itemMap = new HashMap<String, JMenuItem>();
240 List<JMenuItem> a = createJMenuItems(rm, itemMap, groupKey);
241 refreshAllAccelerators(itemMap);
245 static List<JMenuItem> createJMenuItems(ResourceManager rm,
246 Map<String, JMenuItem> itemMap,
248 List<JMenuItem> a = new ArrayList<JMenuItem>();
249 for (final String itemId : rm.get(groupKey + ".items").split(",", -1)) {
250 if (itemId.length() == 0) {
253 JMenuItem o = createJMenuItem(rm, itemId);
255 itemMap.put(itemId, o);
261 static JMenuItem createJMenuItem(ResourceManager rm, String itemId) {
262 final boolean autoMnemonic = rm.getInt("auto-mnemonic") == 1;
263 final String itemKey = "item." + itemId;
264 final char mn = rm.getChar(itemKey + ".mnemonic");
265 final String shortcutKey = itemKey + ".shortcut";
267 if (rm.isTrue(itemKey + ".checkbox")) {
268 o = new JCheckBoxMenuItem();
269 } else if (rm.isTrue(itemKey + ".subgroup")) {
270 o = createJMenu(rm, itemId);
271 ButtonGroup buttonGroup = new ButtonGroup();
272 boolean selected = false;
273 for (final String id : rm.get(itemKey + ".items").split(",", -1)) {
274 final JMenuItem sub = createJMenuItem(rm, itemId + id);
276 buttonGroup.add(sub);
278 sub.setSelected(true);
285 if (rm.containsKey(shortcutKey)) {
286 KeyStroke ks = Utilities.getKeyStroke(rm.get(shortcutKey));
288 o.setAccelerator(ks);
291 o.setText(rm.get(itemKey) + (autoMnemonic ? "(" + mn + ")" : ""));
293 o.setActionCommand(itemId);
294 o.setIcon(getImageIcon(String.format("menu-%s.png", itemId)));
295 o.setDisabledIcon(getImageIcon(String.format("menu-disabled-%s.png", itemId)));