1 import javax.sound.midi.*;
3 import javax.swing.filechooser.*;
5 import java.awt.event.*;
10 * Moosiques GUI representing a menubar, menus and menuitems
12 * @author Björn Lanneskog
14 public class MooMenu extends JMenuBar implements ActionListener {
16 private JMenu file, reopen, edit, keyboard, playback, music, help;
17 private JFileChooser chooser;
18 private File directory;
19 private ArrayList recentFiles;
22 * Creates the menu bar.
25 // Fetches last work directory, and recent files.
26 // directory = Moosique.getRecentDirectory();
27 ArrayList recentFiles = new ArrayList(); // ... = Moosique.getRecentFiles();
29 // Creates the sub-menus and their items.
30 file = createMenu("File", KeyEvent.VK_F);
33 addItem(file, "New", KeyEvent.VK_N, true);
34 addItem(file, "Open...", KeyEvent.VK_O, true);
35 reopen = createMenu("Reopen", KeyEvent.VK_R);
36 Iterator it = recentFiles.iterator();
37 while (it.hasNext()) {
38 JMenuItem recentFile = new JMenuItem((String)it.next());
39 recentFile.addActionListener(this);
40 reopen.add(recentFile);
43 addItem(file, "Save", KeyEvent.VK_S, true);
44 addItem(file, "Save as...", KeyEvent.VK_A, false);
46 addItem(file, "Exit", KeyEvent.VK_Q, true);
48 edit = createMenu("Edit", KeyEvent.VK_E);
51 addItem(edit, "Copy", KeyEvent.VK_C, true);
52 addItem(edit, "Cut", KeyEvent.VK_X, true);
53 addItem(edit, "Paste", KeyEvent.VK_V, true);
55 addItem(edit, "Select all", KeyEvent.VK_E, true);
56 addItem(edit, "Invert selection", KeyEvent.VK_I, true);
58 addItem(edit, "Preferences...", KeyEvent.VK_P, true);
60 playback = createMenu("Playback", KeyEvent.VK_P);
63 addItem(playback, "Play", "F5", KeyEvent.VK_P);
64 addItem(playback, "Pause", "F7", KeyEvent.VK_A);
65 addItem(playback, "Stop", "F6", KeyEvent.VK_S);
66 playback.addSeparator();
67 addItem(playback, "Set position...", KeyEvent.VK_E, false);
68 playback.addSeparator();
69 keyboard = createMenu("Set keyboard octave", KeyEvent.VK_K);
71 for (int i = 9; i >= 0; i--) addItem(keyboard, "Octave " + i, i + 48, false);
73 music = createMenu("Music", KeyEvent.VK_M);
76 addItem(music, "Add track...", KeyEvent.VK_A, true);
77 addItem(music, "Delete track...", KeyEvent.VK_D, true);
78 addItem(music, "Copy track...", KeyEvent.VK_Y, true);
79 addItem(music, "Move track...", KeyEvent.VK_M, true);
81 addItem(music, "Insert measure...", KeyEvent.VK_I, false);
82 addItem(music, "Delete measure...", KeyEvent.VK_E, false);
84 addItem(music, "Set time signature...", KeyEvent.VK_S, false);
85 addItem(music, "Set tempo...", KeyEvent.VK_M, false);
86 addItem(music, "Scale velocity...", KeyEvent.VK_V, false);
87 addItem(music, "Transpose...", KeyEvent.VK_T, false);
89 help = createMenu("Help", KeyEvent.VK_L);
92 addItem(help, "User manual", "F1", KeyEvent.VK_M);
94 addItem(help, "About", KeyEvent.VK_A, false);
97 * Creats a menu in the menubar.
98 * @param name The name of the menu.
99 * @param mnemnic The shortcut-key to access the menu.
100 * @return menu The menu created.
102 private JMenu createMenu(String name, int mnemonic) {
103 JMenu menu = new JMenu(name);
104 menu.setMnemonic(mnemonic);
109 * Creats a menuitem in the menu.
110 * @param menu The menu where to add the menuitem.
111 * @param name The name of the menuitem.
112 * @param mnemonic The keyboard mnemonic used to access this menuitem
113 * @param accelerate whether to create a keyboard accelerator for this item
114 * @return item The menuitem created.
116 private JMenuItem addItem(JMenu menu, String name, int mnemonic, boolean accelerate) {
117 JMenuItem item = new JMenuItem(name);
118 item.addActionListener(this);
119 item.setMnemonic(mnemonic);
120 if (accelerate) item.setAccelerator(KeyStroke.getKeyStroke(mnemonic, ActionEvent.CTRL_MASK));
126 * Creats a menuitem in the menu.
127 * @param menu The menu to where to add the menuitem.
128 * @param name The name of the menuitem.
129 * @param key The keystroke to access this menuitem.
130 * @param mnemonic The keyboard mnemonic used to access this menuitem
131 * @return item The menuitem created.
133 private JMenuItem addItem(JMenu menu, String name, String key, int mnemonic) {
134 JMenuItem item = new JMenuItem(name);
135 item.setMnemonic(mnemonic);
136 item.setAccelerator(KeyStroke.getKeyStroke(key));
137 item.addActionListener(this);
142 private boolean isMidiFile(File f) {
144 String extension = f.getName().substring(f.getName().lastIndexOf('.') + 1).toLowerCase().trim();
145 if (extension.equals("mid")) return true;
150 * Gets the users command of takes and properiate action
151 * @param e The action perfomed.
153 public void actionPerformed(ActionEvent e) {
154 String command = e.getActionCommand();
157 if(command == "New") {
158 if (!Moosique.promptOnUnsavedChanges()) Moosique.clearSequence();
159 } else if (command == "Open...") {
160 // Shows a file chooser. If shown previously, starts in the current directory.
161 if (directory != null) {
162 chooser = new JFileChooser(directory);
164 chooser = new JFileChooser();
166 chooser.addChoosableFileFilter(new MidiFileFilter());
167 int returnVal = chooser.showOpenDialog(this);
169 // Stores the current directory and loads the selected file.
170 File file = chooser.getSelectedFile();
171 if(returnVal == JFileChooser.APPROVE_OPTION && isMidiFile(file)) {
172 directory = file.getParentFile();
173 if (!Moosique.promptOnUnsavedChanges()) {
174 if (Moosique.load(file)) {
175 // Adds an item for this file to the reopen menu.
176 String filename = file.getAbsolutePath();
177 JMenuItem recentFile = new JMenuItem(filename);
178 for (int i = 0; i < reopen.getMenuComponentCount(); i++) {
179 if (filename.equals(((JMenuItem)reopen.getMenuComponent(i)).getText()))
182 reopen.insert(recentFile, 0);
183 if (reopen.getMenuComponentCount() > 5) reopen.remove(5);
187 } else if (command == "Save") {
188 if (!Moosique.save()) showSaveAsDialog();
189 } else if (command == "Save as...") {
191 } else if (command == "Exit") {
193 } else if (command == "Copy") {
195 } else if (command == "Cut") {
197 } else if (command == "Paste") {
199 } else if (command == "Select all") {
201 } else if (command == "Invert selection") {
203 } else if (command == "Preferences...") {
205 } else if (command == "Play") {
206 if (!Moosique.getSequencer().isRunning()) Moosique.play();
207 } else if (command == "Pause") {
208 if (Moosique.getSequencer().isRunning()) Moosique.pause();
209 } else if (command == "Stop") {
211 } else if (command == "Set position...") {
212 MooDialog newDialog = new MooDialog(MooDialog.SET_POSITION);
213 // Moosique.setPosition(???); Räkna ut från msr, beats, ticks, time sig.
214 } else if (command.startsWith("Octave")) {
215 MooKeyboard.setOctave(Integer.parseInt(command.substring(7,8)));
216 } else if (command == "Add track...") {
217 MooDialog newDialog = new MooDialog(MooDialog.ADD_TRACK);
218 Moosique.getSequence().createTrack();
219 } else if (command == "Delete track...") {
220 MooDialog newDialog = new MooDialog(MooDialog.DELETE_TRACK);
221 /* Let the user select a track from a list.
222 seq = Moosique.getSequence();
223 seq.deleteTrack(seq.getTracks()[NUMBER]);
225 } else if (command == "Copy track...") {
226 MooDialog newDialog = new MooDialog(MooDialog.COPY_TRACK);
227 } else if (command == "Move track...") {
228 MooDialog newDialog = new MooDialog(MooDialog.MOVE_TRACK);
229 } else if (command == "Insert measure...") {
230 MooDialog newDialog = new MooDialog(MooDialog.INSERT_MEASURE);
231 } else if (command == "Delete measure...") {
232 MooDialog newDialog = new MooDialog(MooDialog.DELETE_MEASURE);
233 } else if (command == "Set time signature...") {
235 } else if (command == "Set tempo...") {
236 MooDialog newDialog = new MooDialog(MooDialog.SET_TEMPO);
237 } else if (command == "Scale velocity...") {
238 MooDialog newDialog = new MooDialog(MooDialog.SCALE_VELOCITY);
239 } else if (command == "Transpose...") {
240 MooDialog newDialog = new MooDialog(MooDialog.TRANSPOSE);
241 } else if (command == "User manual") {
242 MooDialog manual = new MooDialog(MooDialog.MANUAL);
243 } else if (command == "About") {
244 JOptionPane.showMessageDialog(null,
245 "Moosique\nversion 1.0\n\n© 2003\nRoland Andersson\nMichael Andreen\nBjörn Lanneskog\nEinar Pehrson",
247 JOptionPane.INFORMATION_MESSAGE,
248 new ImageIcon(Moosique.getGUI().logo));
249 } else if (reopen.isMenuComponent((JMenuItem)e.getSource())) {
250 String recentFile = ((JMenuItem)e.getSource()).getText();
251 if (!Moosique.promptOnUnsavedChanges()) Moosique.load(new File(recentFile));
255 private void showSaveAsDialog() {
256 // Shows a file chooser. If shown previously, starts in the current directory.
257 if (directory != null) {
258 chooser = new JFileChooser(directory);
260 chooser = new JFileChooser();
262 chooser.addChoosableFileFilter(new MidiFileFilter());
263 int returnVal = chooser.showSaveDialog(this);
265 // Stores the current directory and loads the selected file.
266 File file = chooser.getSelectedFile();
267 if(returnVal == JFileChooser.APPROVE_OPTION && isMidiFile(file)) {
268 directory = file.getParentFile();
269 Moosique.saveAs(file);
273 class MidiFileFilter extends javax.swing.filechooser.FileFilter {
274 public boolean accept(File f) {
276 if (f.isDirectory() || isMidiFile(f)) return true;
282 * gets the description of the filetype
283 * @return "Midifiles the only filetyp compatibel with the program
285 public String getDescription() {