/******************************************************************************* * openDLX - A DLX/MIPS processor simulator. * Copyright (C) 2013 The openDLX project, University of Augsburg, Germany * Project URL: <https://sourceforge.net/projects/opendlx> * Development branch: <https://github.com/smetzlaff/openDLX> * * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program, see <LICENSE>. If not, see * <http://www.gnu.org/licenses/>. ******************************************************************************/ package openDLX.gui.menubar; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import java.util.Map; import javax.swing.ButtonGroup; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import openDLX.gui.GUI_CONST.OpenDLXSimState; import openDLX.gui.MainFrame; import openDLX.gui.Preference; import openDLX.gui.command.Command; import openDLX.gui.command.EventCommandLookUp; import openDLX.gui.command.userLevel.CommandChangeWindowVisibility; import openDLX.gui.command.userLevel.CommandClearAllPreferences; import openDLX.gui.command.userLevel.CommandDisplayTooltips; import openDLX.gui.command.userLevel.CommandDoCycle; import openDLX.gui.command.userLevel.CommandDoXCycles; import openDLX.gui.command.userLevel.CommandExitProgram; import openDLX.gui.command.userLevel.CommandForwarding; import openDLX.gui.command.userLevel.CommandLoadAndRunFile; import openDLX.gui.command.userLevel.CommandLoadFile; import openDLX.gui.command.userLevel.CommandLoadFileBelow; import openDLX.gui.command.userLevel.CommandLoadFrameConfigurationUsrLevel; import openDLX.gui.command.userLevel.CommandNewFile; import openDLX.gui.command.userLevel.CommandPerformEditorRedo; import openDLX.gui.command.userLevel.CommandPerformEditorUndo; import openDLX.gui.command.userLevel.CommandResetCurrentProgram; import openDLX.gui.command.userLevel.CommandRun; import openDLX.gui.command.userLevel.CommandRunFromConfigurationFile; import openDLX.gui.command.userLevel.CommandRunSlowly; import openDLX.gui.command.userLevel.CommandRunToAddressX; import openDLX.gui.command.userLevel.CommandSave; import openDLX.gui.command.userLevel.CommandSaveFrameConfigurationUsrLevel; import openDLX.gui.command.userLevel.CommandSetLaF; import openDLX.gui.command.userLevel.CommandShowAbout; import openDLX.gui.command.userLevel.CommandShowOptionDialog; import openDLX.gui.command.userLevel.CommandStopRunning; import openDLX.gui.internalframes.concreteframes.ClockCycleFrame; import openDLX.gui.internalframes.concreteframes.CodeFrame; import openDLX.gui.internalframes.concreteframes.LogFrame; import openDLX.gui.internalframes.concreteframes.MemoryFrame; import openDLX.gui.internalframes.concreteframes.RegisterFrame; import openDLX.gui.internalframes.concreteframes.StatisticsFrame; import openDLX.gui.internalframes.concreteframes.editor.EditorFrame; import openDLX.gui.internalframes.factories.InternalFrameFactory; public class MainFrameMenuBarFactory { private static final String STRING_MENU_FILE = "File"; public static final String STRING_MENU_SIMULATOR = "Simulator"; private static final String STRING_MENU_EDIT = "Edit"; private static final String STRING_MENU_WINDOW = "Window"; private static final String STRING_MENU_LAF = "Look & Feels"; private static final String STRING_MENU_HELP = "Help"; private static final String STRING_MENU_FILE_NEW = "New"; private static final String STRING_MENU_FILE_OPEN = "Open"; private static final String STRING_MENU_FILE_OPEN_AND_ASSEMBLE = "Open and Assemble"; private static final String STRING_MENU_FILE_ADD_CODE = "Add Code"; private static final String STRING_MENU_FILE_SAVE = "Save"; private static final String STRING_MENU_FILE_RUN_FROM_CONF = "Run from Configuration File"; private static final String STRING_MENU_FILE_EXIT = "Exit Program"; private static final KeyStroke KEY_MENU_FILE_NEW = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_FILE_OPEN = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_FILE_OPEN_AND_ASSEMBLE = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_FILE_ADD_CODE = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_FILE_SAVE = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_FILE_RUN_FROM_CONF = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.Event.ALT_MASK); private static final KeyStroke KEY_MENU_FILE_EXIT = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.Event.ALT_MASK); private static final String STRING_MENU_SIMULATOR_RUN_PROGRAM = "Run Program"; private static final String STRING_MENU_SIMULATOR_RUN_PROGRAM_SLOWLY = "Run Program Slowly"; private static final String STRING_MENU_SIMULATOR_STOP_RUNNING = "Stop Running"; private static final String STRING_MENU_SIMULATOR_DO_CYCLE = "Do Cycle"; private static final String STRING_MENU_SIMULATOR_DO_X_CYCLES = "Do X Cycles"; private static final String STRING_MENU_SIMULATOR_RUN_TO = "Run to Address X"; private static final String STRING_MENU_SIMULATOR_RESTART = "Restart Program"; private static final String STRING_MENU_SIMULATOR_OPTIONS = "Options"; public static final String STRING_MENU_SIMULATOR_FORWARDING = "Forwarding"; private static final KeyStroke KEY_MENU_SIMULATOR_RUN_PROGRAM = KeyStroke.getKeyStroke("F5"); private static final KeyStroke KEY_MENU_SIMULATOR_RUN_PROGRAM_SLOWLY = KeyStroke.getKeyStroke("F6"); private static final KeyStroke KEY_MENU_SIMULATOR_STOP_RUNNING = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_SIMULATOR_DO_CYCLE = KeyStroke.getKeyStroke("F7"); private static final KeyStroke KEY_MENU_SIMULATOR_DO_X_CYCLES = KeyStroke.getKeyStroke("F8"); private static final KeyStroke KEY_MENU_SIMULATOR_RUN_TO = KeyStroke.getKeyStroke("F9"); private static final KeyStroke KEY_MENU_SIMULATOR_RESTART = KeyStroke.getKeyStroke("F4"); private static final KeyStroke KEY_MENU_SIMULATOR_OPTIONS = null; private static final KeyStroke KEY_MENU_SIMULATOR_FORWARDING = null; private static final String STRING_MENU_EDIT_UNDO = "Undo"; private static final String STRING_MENU_EDIT_REDO = "Redo"; private static final KeyStroke KEY_MENU_EDIT_UNDO = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.Event.CTRL_MASK); private static final KeyStroke KEY_MENU_EDIT_REDO = KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Z, java.awt.Event.CTRL_MASK | java.awt.Event.SHIFT_MASK); private static final String STRING_MENU_WINDOW_SAVE = "Save Current Window Configuration"; private static final String STRING_MENU_WINDOW_LOAD = "Load Saved Window Configuration"; private static final String STRING_MENU_WINDOW_CLEAR = "Clear All Preferences"; private static final String STRING_MENU_WINDOW_DISPLAY_EDITOR = "Display Editor"; private static final String STRING_MENU_WINDOW_DISPLAY_LOG = "Display Log"; private static final String STRING_MENU_WINDOW_DISPLAY_CODE = "Display Code"; private static final String STRING_MENU_WINDOW_DISPLAY_RS = "Display Register Set"; private static final String STRING_MENU_WINDOW_DISPLAY_CC = "Display Clock Cycle Diagram"; private static final String STRING_MENU_WINDOW_DISPLAY_STATS = "Display Statistics"; private static final String STRING_MENU_WINDOW_DISPLAY_MEM = "Display Memory"; private static final KeyStroke KEY_MENU_WINDOW_SAVE = null; private static final KeyStroke KEY_MENU_WINDOW_LOAD = null; private static final KeyStroke KEY_MENU_WINDOW_CLEAR = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_EDITOR = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_LOG = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_CODE = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_RS = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_CC = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_STATS = null; private static final KeyStroke KEY_MENU_WINDOW_DISPLAY_MEM = null; private static final String STRING_MENU_HELP_TOOLTIPS = "Display Tooltips"; // currently unused: // private static final String STRING_MENU_HELP_TUTORIAL = "Tutorial"; private static final String STRING_MENU_HELP_ABOUT = "About"; private static final KeyStroke KEY_MENU_HELP_TOOLTIPS = null; // currently unused: // private static final KeyStroke KEY_MENU_HELP_TUTORIAL = null; private static final KeyStroke KEY_MENU_HELP_ABOUT = null; private MainFrame mf; private ActionListener al = null; private ItemListener il = null; protected JMenuBar jmb = new JMenuBar(); public MainFrameMenuBarFactory(ActionListener al, ItemListener il, MainFrame mf) { assert al != null && il != null; this.al = al; this.il = il; this.mf = mf; } public JMenuBar createJMenuBar(Map<String, JMenuItem> importantItems) { JMenu fileMenu = new JMenu(STRING_MENU_FILE); JMenu simulatorMenu = new JMenu(STRING_MENU_SIMULATOR); JMenu editMenu = new JMenu(STRING_MENU_EDIT); JMenu windowMenu = new JMenu(STRING_MENU_WINDOW); JMenu lookAndFeelMenu = new JMenu(STRING_MENU_LAF); JMenu helpMenu = new JMenu(STRING_MENU_HELP); jmb.add(fileMenu); jmb.add(simulatorMenu); jmb.add(editMenu); jmb.add(windowMenu); jmb.add(helpMenu); //if parameter command = null, command is not yet implemented and should be implemented soon addMenuItem(fileMenu, STRING_MENU_FILE_NEW, KEY_MENU_FILE_NEW, StateValidator.executingOrLazyStates, new CommandNewFile(mf)); addMenuItem(fileMenu, STRING_MENU_FILE_OPEN, KEY_MENU_FILE_OPEN, StateValidator.executingOrLazyStates, new CommandLoadFile(mf)); addMenuItem(fileMenu, STRING_MENU_FILE_OPEN_AND_ASSEMBLE, KEY_MENU_FILE_OPEN_AND_ASSEMBLE, StateValidator.executingOrLazyStates, new CommandLoadAndRunFile(mf)); addMenuItem(fileMenu, STRING_MENU_FILE_ADD_CODE, KEY_MENU_FILE_ADD_CODE, StateValidator.executingOrLazyStates, new CommandLoadFileBelow(mf)); addMenuItem(fileMenu, STRING_MENU_FILE_SAVE, KEY_MENU_FILE_SAVE, StateValidator.executingOrLazyStates, new CommandSave()); addMenuItem(fileMenu, STRING_MENU_FILE_RUN_FROM_CONF, KEY_MENU_FILE_RUN_FROM_CONF, StateValidator.executingOrLazyStates, new CommandRunFromConfigurationFile(mf)); addMenuItem(fileMenu, STRING_MENU_FILE_EXIT, KEY_MENU_FILE_EXIT, StateValidator.allStates, new CommandExitProgram(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_RUN_PROGRAM, KEY_MENU_SIMULATOR_RUN_PROGRAM, StateValidator.executingStates, new CommandRun(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_RUN_PROGRAM_SLOWLY, KEY_MENU_SIMULATOR_RUN_PROGRAM_SLOWLY, StateValidator.executingStates, new CommandRunSlowly(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_STOP_RUNNING, KEY_MENU_SIMULATOR_STOP_RUNNING, StateValidator.RunningStates, new CommandStopRunning(mf)); simulatorMenu.addSeparator(); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_DO_CYCLE, KEY_MENU_SIMULATOR_DO_CYCLE, StateValidator.executingStates, new CommandDoCycle(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_DO_X_CYCLES, KEY_MENU_SIMULATOR_DO_X_CYCLES, StateValidator.executingStates, new CommandDoXCycles(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_RUN_TO, KEY_MENU_SIMULATOR_RUN_TO, StateValidator.executingStates, new CommandRunToAddressX(mf)); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_RESTART, KEY_MENU_SIMULATOR_RESTART, StateValidator.executingStates, new CommandResetCurrentProgram(mf)); simulatorMenu.addSeparator(); addMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_OPTIONS, KEY_MENU_SIMULATOR_OPTIONS, StateValidator.executingOrLazyStates, new CommandShowOptionDialog()); { // update the menu entry for forwarding after changing it in the options dialog final OpenDLXSimCheckBoxMenuItem fw_checkitem = addCheckBoxMenuItem(simulatorMenu, STRING_MENU_SIMULATOR_FORWARDING, KEY_MENU_SIMULATOR_FORWARDING, StateValidator.executingOrLazyStates); EventCommandLookUp.put(fw_checkitem, new CommandForwarding(fw_checkitem)); fw_checkitem.setSelected(Preference.pref.getBoolean(Preference.forwardingPreferenceKey, true)); importantItems.put(STRING_MENU_SIMULATOR_FORWARDING, fw_checkitem); } addMenuItem(editMenu, STRING_MENU_EDIT_UNDO, KEY_MENU_EDIT_UNDO, StateValidator.executingOrLazyStates, new CommandPerformEditorUndo(mf.getEditorUndoManager())); addMenuItem(editMenu, STRING_MENU_EDIT_REDO, KEY_MENU_EDIT_REDO, StateValidator.executingOrLazyStates, new CommandPerformEditorRedo(mf.getEditorUndoManager())); addMenuItem(windowMenu, STRING_MENU_WINDOW_SAVE, KEY_MENU_WINDOW_SAVE, StateValidator.executingOrLazyStates, new CommandSaveFrameConfigurationUsrLevel(mf)); addMenuItem(windowMenu, STRING_MENU_WINDOW_LOAD, KEY_MENU_WINDOW_LOAD, StateValidator.executingOrLazyStates, new CommandLoadFrameConfigurationUsrLevel(mf)); addMenuItem(windowMenu, STRING_MENU_WINDOW_CLEAR, KEY_MENU_WINDOW_CLEAR, StateValidator.executingOrLazyStates, new CommandClearAllPreferences()); /*this is a submenu of windowMenu JMenu defaultWindowConfigurationMenu = new JMenu("Load default window configuration"); windowMenu.add(defaultWindowConfigurationMenu); addMenuItem(defaultWindowConfigurationMenu, "standard", null, null); addMenuItem(defaultWindowConfigurationMenu, "full", null, null); addMenuItem(defaultWindowConfigurationMenu, "edit only", null, null);*/ windowMenu.addSeparator(); createWindowCheckboxes(windowMenu); //see below windowMenu.addSeparator(); // add submenu for Look&Feels windowMenu.add(lookAndFeelMenu); // a group of radio buttons so only one L&F item can be selected ButtonGroup lookAndFeelOptionsGroup = new ButtonGroup(); // get current L&F class name final String currentLaF = UIManager.getLookAndFeel().getClass().getCanonicalName(); // add selector items for all available L&Fs for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { OpenDLXSimRadioButtonMenuItem item = addRadioButtonMenuItem(lookAndFeelMenu, info.getName(), null, lookAndFeelOptionsGroup, StateValidator.allStates); if (currentLaF.equals(info.getClassName())) item.setSelected(true); EventCommandLookUp.put(item, new CommandSetLaF(info.getClassName())); } //help OpenDLXSimCheckBoxMenuItem checkitem = addCheckBoxMenuItem(helpMenu, STRING_MENU_HELP_TOOLTIPS, KEY_MENU_HELP_TOOLTIPS, StateValidator.executingOrLazyStates); EventCommandLookUp.put(checkitem, new CommandDisplayTooltips(checkitem)); // get preference and set selected if tooltips are enabled checkitem.setSelected(Preference.pref.getBoolean(CommandDisplayTooltips.preferenceKey, true)); // currently unused: //addMenuItem(helpMenu, STRING_MENU_HELP_TUTORIAL, KEY_MENU_HELP_TUTORIAL, StateValidator.executingOrLazyStates, new CommandTutorial()); addMenuItem(helpMenu, STRING_MENU_HELP_ABOUT, KEY_MENU_HELP_ABOUT, StateValidator.executingOrLazyStates, new CommandShowAbout()); return jmb; } private void createWindowCheckboxes(JMenu windowMenu) { //box name = frame title String name = InternalFrameFactory.getFrameName(EditorFrame.class); OpenDLXSimMenuItem frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_EDITOR, KEY_MENU_WINDOW_DISPLAY_EDITOR, StateValidator.allStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(LogFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_LOG, KEY_MENU_WINDOW_DISPLAY_LOG, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(CodeFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_CODE, KEY_MENU_WINDOW_DISPLAY_CODE, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(RegisterFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_RS, KEY_MENU_WINDOW_DISPLAY_RS, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(ClockCycleFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_CC, KEY_MENU_WINDOW_DISPLAY_CC, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(StatisticsFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_STATS, KEY_MENU_WINDOW_DISPLAY_STATS, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); name = InternalFrameFactory.getFrameName(MemoryFrame.class); frame_item = addMenuItem(windowMenu, STRING_MENU_WINDOW_DISPLAY_MEM, KEY_MENU_WINDOW_DISPLAY_MEM, StateValidator.executingOrRunningStates); frame_item.setName(name); EventCommandLookUp.put(frame_item, new CommandChangeWindowVisibility(frame_item, mf)); } protected OpenDLXSimMenuItem addMenuItem(final JMenu parent, String name, KeyStroke accelerator, OpenDLXSimState state []) { final OpenDLXSimMenuItem item = new OpenDLXSimMenuItem(state,name); initializeMenuItem(item, parent, name, accelerator); item.addActionListener(al); return item; } protected OpenDLXSimMenuItem addMenuItem(final JMenu parent, String name, KeyStroke accelerator, OpenDLXSimState state [], Command eventCommand) { final OpenDLXSimMenuItem item = addMenuItem(parent, name, accelerator, state); EventCommandLookUp.put(item, eventCommand); return item; } protected OpenDLXSimCheckBoxMenuItem addCheckBoxMenuItem(JMenu father, String name, KeyStroke accelerator, OpenDLXSimState state []) { OpenDLXSimCheckBoxMenuItem jMenuItem = new OpenDLXSimCheckBoxMenuItem(state,name); jMenuItem.setState(false); initializeMenuItem(jMenuItem, father, name, accelerator); jMenuItem.addItemListener(il); return jMenuItem; } protected OpenDLXSimRadioButtonMenuItem addRadioButtonMenuItem(JMenu father, String name, KeyStroke accelerator, ButtonGroup group, OpenDLXSimState state []) { OpenDLXSimRadioButtonMenuItem jRadioButtonItem = new OpenDLXSimRadioButtonMenuItem(state,name); jRadioButtonItem.setSelected(true); jRadioButtonItem.addActionListener(al); group.add(jRadioButtonItem); initializeMenuItem(jRadioButtonItem, father, name, accelerator); return jRadioButtonItem; } protected void initializeMenuItem(JMenuItem jMenuItem, JMenu father, String name, KeyStroke accelerator) { jMenuItem.setAccelerator(accelerator); father.add(jMenuItem); } }