package org.chesmapper.view.gui; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import java.util.Vector; import javax.swing.Action; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; import javax.swing.ToolTipManager; import org.chesmapper.map.main.ScreenSetup; import org.chesmapper.map.main.Settings; import org.chesmapper.view.cluster.ClusterController; import org.chesmapper.view.cluster.Clustering; import org.chesmapper.view.gui.ViewControler.HighlightMode; public class MenuBar extends JMenuBar { static interface MyMenuItem { public boolean isMenu(); public Action getAction(); } static class DefaultMyMenuItem implements MyMenuItem { Action action; public DefaultMyMenuItem(Action action) { this.action = action; } @Override public boolean isMenu() { return false; } @Override public Action getAction() { return action; } } static class MyMenu implements MyMenuItem { String name; Vector<MyMenuItem> items = new Vector<MyMenuItem>(); public MyMenu(String name, Action... actions) { this.name = name; for (Action action : actions) items.add(new DefaultMyMenuItem(action)); } public MyMenu(String name, MyMenuItem... items) { this.name = name; for (MyMenuItem item : items) this.items.add(item); } public MyMenu(String name, Action actions[], MyMenuItem... items) { this(name, actions, items, null); } public MyMenu(String name, Action actions[], MyMenuItem items[], int insertMenusAt[]) { this.name = name; if (insertMenusAt == null) { for (Action action : actions) this.items.add(new DefaultMyMenuItem(action)); for (MyMenuItem item : items) this.items.add(item); } else { int menuIndex = 0; int actionIndex = 0; for (int i = 0; i < actions.length + items.length; i++) { if (menuIndex < insertMenusAt.length && i == insertMenusAt[menuIndex]) { this.items.add(items[menuIndex]); menuIndex++; } else { this.items.add(new DefaultMyMenuItem(actions[actionIndex])); actionIndex++; } } } } @Override public boolean isMenu() { return true; } @Override public Action getAction() { return null; } } static class MyMenuBar { Vector<MyMenu> menus = new Vector<MyMenu>(); List<Action> actions = new ArrayList<Action>(); public MyMenuBar(MyMenu... menus) { for (MyMenu m : menus) this.menus.add(m); for (MyMenu m : menus) { for (MyMenuItem i : m.items) { if (!i.isMenu()) actions.add(i.getAction()); else for (MyMenuItem ii : ((MyMenu) i).items) actions.add(ii.getAction()); } } } } GUIControler guiControler; ViewControler viewControler; Clustering clustering; MyMenuBar menuBar; private final static String SPHERE_SETTINGS_MENU = Settings.text("action.highlight-sphere.settings"); private final static String DATA_MENU = "Dataset properties"; public MenuBar(GUIControler guiControler, ViewControler viewControler, ClusterController clusterControler, Clustering clustering) { this.guiControler = guiControler; this.viewControler = viewControler; this.clustering = clustering; Actions a = new Actions(guiControler, viewControler, clusterControler, clustering); MyMenu dataMenu = new MyMenu(DATA_MENU, a.getDataActions()); MyMenu fileMenu = new MyMenu("File", a.getFileActions(), new MyMenu[] { dataMenu }, new int[] { 1 }); MyMenu filterMenu = new MyMenu("Filter", a.getFilterActions()); MyMenu removeMenu = new MyMenu("Remove", a.getRemoveActions()); MyMenu exportMenu = new MyMenu("Export", a.getExportActions()); MyMenu editMenu = new MyMenu("Edit", a.getEditActions(), filterMenu, removeMenu, exportMenu); MyMenu viewMenu = new MyMenu("View", a.getViewActions()); MyMenu highlightSphereMenu = new MyMenu(SPHERE_SETTINGS_MENU, a.getHighlightSphereActions()); MyMenu highlightMenu = new MyMenu("Highlighting", a.getHighlightActions(), highlightSphereMenu); MyMenu helpMenu = new MyMenu("Help", a.getHelpActions()); menuBar = new MyMenuBar(fileMenu, editMenu, viewMenu, highlightMenu, helpMenu); buildMenu(); } private JMenuItem createItemFromAction(Action a) { JMenuItem m; if (a.getValue("is-radio-buttion") != null && (Boolean) a.getValue("is-radio-buttion")) m = new JRadioButtonMenuItem(a) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; else if (a.getValue(Action.SELECTED_KEY) instanceof Boolean) m = new JCheckBoxMenuItem(a) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; else m = new JMenuItem(a) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; m.setToolTipText((String) a.getValue(Actions.TOOLTIP)); m.setFont(m.getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); ToolTipManager.sharedInstance().setDismissDelay(10000); ToolTipManager.sharedInstance().registerComponent(m); return m; } private void createMenuListener(final JMenu m) { if (m.getText().equals(SPHERE_SETTINGS_MENU)) { m.setEnabled(viewControler.getHighlightMode() == HighlightMode.Spheres); viewControler.addViewListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(ViewControler.PROPERTY_HIGHLIGHT_MODE_CHANGED)) m.setEnabled(viewControler.getHighlightMode() == HighlightMode.Spheres); } }); } } private void buildMenu() { for (MyMenu m : menuBar.menus) { JMenu menu = new JMenu(m.name) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; for (MyMenuItem i : m.items) { if (!i.isMenu()) menu.add(createItemFromAction(i.getAction())); else if (i instanceof MyMenu) { JMenu mm = new JMenu(((MyMenu) i).name) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; ButtonGroup group = new ButtonGroup(); for (MyMenuItem ii : ((MyMenu) i).items) { JMenuItem item = createItemFromAction(ii.getAction()); if (item instanceof JRadioButtonMenuItem) group.add(item); mm.add(item); } createMenuListener(mm); menu.add(mm); } } add(menu); } } public JPopupMenu getPopup() { final List<JMenuItem> items = new ArrayList<JMenuItem>(); JPopupMenu p = new JPopupMenu() { public void updateUI() { super.updateUI(); for (JMenuItem m : items) m.updateUI(); } }; boolean first = true; for (MyMenu m : menuBar.menus) { if (!first) p.addSeparator(); else first = false; for (MyMenuItem i : m.items) { if (!i.isMenu()) { JMenuItem item = createItemFromAction(i.getAction()); items.add(item); p.add(item); } else { JMenu mm = new JMenu(((MyMenu) i).name) { @Override public void updateUI() { super.updateUI(); setFont(getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); } }; items.add(mm); mm.setFont(mm.getFont().deriveFont((float) ScreenSetup.INSTANCE.getFontSize())); for (MyMenuItem ii : ((MyMenu) i).items) { JMenuItem item = createItemFromAction(ii.getAction()); items.add(item); mm.add(item); } createMenuListener(mm); p.add(mm); } } } return p; } // /** // * somehow the accelerate key registration does not work reliably, do that manually // * // * @param e // */ // public void handleKeyEvent(KeyEvent e) // { // // Settings.LOGGER.warn("handle key event " + KeyEvent.getKeyText(e.getKeyCode()) + " " // // + KeyEvent.getKeyModifiersText(e.getModifiers()) + " " + e.getKeyCode() + " " + e.getModifiers()); // for (Action action : menuBar.actions) // { // if (((AbstractAction) action).isEnabled()) // { // KeyStroke k = (KeyStroke) action.getValue(Action.ACCELERATOR_KEY); // if (k != null) // { // if (e.getKeyCode() == k.getKeyCode() && ((k.getModifiers() & e.getModifiers()) != 0)) // { // // Settings.LOGGER.warn("perform " + action.toString()); // action.actionPerformed(new ActionEvent(this, -1, "")); // } // else // { // // Settings.LOGGER.warn("no match: " + KeyEvent.getKeyText(k.getKeyCode()) + " " // // + KeyEvent.getKeyModifiersText(k.getModifiers()) + " " + k.getKeyCode() + " " // // + k.getModifiers()); // } // } // } // } // } }