3 import java.awt.event.*;
4 import javax.sound.midi.*;
9 * A generator class for the application's dialogs.
11 * @author Björn Lanneskog
14 public class MooDialog extends JDialog {
16 private JLabel labelA, labelB, labelC, labelD, labelE, labelF;
17 private JTextField textFieldA, textFieldB, textFieldC, textFieldD, textFieldE, textFieldF;
18 private JTextField textFieldG, textFieldH, textFieldI, textFieldJ, textFieldK;
19 private JComboBox trackListA, trackListB;
20 private JButton okButton, cancelButton;
21 public static final int ADD_TRACK = 1,
32 * Constructor of the dialogs.
34 public MooDialog(int type) {
35 super(Moosique.getGUI(), false);
37 Container pane = getContentPane();
40 Track[] tracks = Moosique.getSequence().getTracks();
43 case ADD_TRACK: makeAddDialog(pane, tracks); break;
44 case DELETE_TRACK: makeDelDialog(pane, tracks); break;
45 case COPY_TRACK: makeCopyDialog(pane, tracks); break;
46 case MOVE_TRACK: makeMoveDialog(pane, tracks); break;
47 case SET_POSITION: makeSetPositionDialog(pane); break;
48 case MANUAL: makeTextDialog(pane, "Manual.txt"); break;
49 case INSERT_MEASURE: makeInsertMeasureDialog(pane); break;
50 case DELETE_MEASURE: makeDeleteMeasureDialog(pane); break;
51 case SET_TEMPO: makeSetTempoDialog(pane); break;
56 * Builds the add track popupdialog.
57 * @param pane The container to put the dialog in.
58 * @param tracks A array containing miditracks.
60 private void makeAddDialog(Container pane, Track[] tracks) {
62 setTitle("Add track");
63 labelA = new JLabel("Name of track", JLabel.CENTER);
65 textFieldA = new JTextField();
67 labelB = new JLabel("Add after", JLabel.CENTER);
69 trackListA = new JComboBox();
70 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
72 cancelButton = new JButton("Cancel");
73 pane.add(cancelButton);
74 okButton = new JButton("OK");
77 labelA.setBounds(50, 10, 100, 20);
78 textFieldA.setBounds(40, 35, 120, 20);
79 labelB.setBounds(50, 70, 100, 20);
80 trackListA.setBounds(40, 95, 120, 20);
81 cancelButton.setBounds(10, 150, 80, 30);
82 okButton.setBounds(120, 150, 60, 30);
87 setLocationRelativeTo(Moosique.getGUI());
92 * Builds the delete track popupdialog.
93 * @param pane The container to put the dialog in.
94 * @param tracks A array containing miditracks.
96 private void makeDelDialog(Container pane, Track[] tracks) {
98 setTitle("Delete track");
99 labelB = new JLabel("Delete track", JLabel.CENTER);
101 trackListA = new JComboBox();
102 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
103 pane.add(trackListA);
104 cancelButton = new JButton("Cancel");
105 pane.add(cancelButton);
106 okButton = new JButton("OK");
109 labelB.setBounds(50, 10, 100, 20);
110 trackListA.setBounds(40, 35, 120, 20);
111 cancelButton.setBounds(10, 90, 80, 30);
112 okButton.setBounds(120, 90, 60, 30);
117 setLocationRelativeTo(Moosique.getGUI());
122 * Builds the copy track popupdialog.
123 * @param pane The container to put the dialog in.
124 * @param tracks A array containing miditracks.
126 private void makeCopyDialog(Container pane, Track[] tracks) {
128 setTitle("Copy Track");
129 labelA = new JLabel("Track to copy", JLabel.CENTER);
131 trackListA = new JComboBox();
132 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
133 pane.add(trackListA);
134 labelB = new JLabel("Insert after", JLabel.CENTER);
136 trackListB = new JComboBox();
137 for (int i = 1; i <= tracks.length; i++) trackListB.addItem("Track " + i);
138 pane.add(trackListB);
139 cancelButton = new JButton("Cancel");
140 pane.add(cancelButton);
141 okButton = new JButton("OK");
144 labelA.setBounds(50, 10, 100, 20);
145 trackListA.setBounds(40, 35, 120, 20);
146 labelB.setBounds(50, 70, 100, 20);
147 trackListB.setBounds(40, 95, 120, 20);
148 cancelButton.setBounds(10, 150, 80, 30);
149 okButton.setBounds(120, 150, 60, 30);
154 setLocationRelativeTo(Moosique.getGUI());
159 * Builds the move track popupdialog
160 * @param pane The container to put the dialog in.
161 * @param tracks A array containing miditracks.
163 private void makeMoveDialog(Container pane, Track[] tracks) {
165 setTitle("Move track");
166 labelA = new JLabel("Track to move", JLabel.CENTER);
168 trackListA = new JComboBox();
169 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
170 pane.add(trackListA);
171 labelB = new JLabel("Insert after", JLabel.CENTER);
173 trackListB = new JComboBox();
174 for (int i = 1; i <= tracks.length; i++) trackListB.addItem("Track " + i);
175 pane.add(trackListB);
176 cancelButton = new JButton("Cancel");
177 pane.add(cancelButton);
178 okButton = new JButton("OK");
181 labelA.setBounds(40, 10, 120, 20);
182 trackListA.setBounds(40, 35, 120, 20);
183 labelB.setBounds(50, 70, 100, 20);
184 trackListB.setBounds(40, 95, 120, 20);
185 cancelButton.setBounds(10, 150, 80, 30);
186 okButton.setBounds(120, 150, 60, 30);
191 setLocationRelativeTo(Moosique.getGUI());
196 * Builds the set position dialog.
197 * @param pane The container to put the dialog in.
198 * @param tracks A array containing miditracks.
200 private void makeSetPositionDialog(Container pane) {
202 setTitle("Set edit position");
203 labelA = new JLabel("Measure", JLabel.CENTER);
205 labelB = new JLabel("Beat", JLabel.CENTER);
207 labelC = new JLabel("Tick", JLabel.CENTER);
209 textFieldA = new JTextField();
210 pane.add(textFieldA);
211 textFieldB = new JTextField();
212 pane.add(textFieldB);
213 textFieldC = new JTextField();
214 pane.add(textFieldC);
215 cancelButton = new JButton("Cancel");
216 pane.add(cancelButton);
217 okButton = new JButton("OK");
220 labelA.setBounds(40, 25, 50, 20);
221 labelB.setBounds(105, 25, 50, 20);
222 labelC.setBounds(170, 25, 50, 20);
223 textFieldA.setBounds(40, 45, 50, 20);
224 textFieldB.setBounds(105, 45, 50, 20);
225 textFieldC.setBounds(170, 45, 50, 20);
226 cancelButton.setBounds(35, 90, 80, 30);
227 okButton.setBounds(155, 90, 60, 30);
232 setLocationRelativeTo(Moosique.getGUI());
237 * Builds the insert measure popupdialog.
238 * @param pane The container to put the dialog in.
240 private void makeInsertMeasureDialog(Container pane){
242 setTitle("Insert Measure");
243 labelA = new JLabel("Insert at:", JLabel.RIGHT);
245 labelB = new JLabel("Measure count:", JLabel.RIGHT);
247 textFieldA = new JTextField();
248 pane.add(textFieldA);
249 textFieldB = new JTextField();
250 pane.add(textFieldB);
251 cancelButton = new JButton("Cancel");
252 pane.add(cancelButton);
253 okButton = new JButton("OK");
256 labelA.setBounds(20, 20, 110 ,20);
257 labelB.setBounds(20, 50, 110, 20);
258 textFieldA.setBounds(140 ,20 , 40, 20);
259 textFieldB.setBounds(140,50, 40, 20);
260 cancelButton.setBounds(20 ,95 , 80, 30);
261 okButton.setBounds(120, 95, 60, 30);
266 setLocationRelativeTo(Moosique.getGUI());
271 * Builds the delete measure popupdialog.
272 * @param pane The container to put the dialog in.
274 private void makeDeleteMeasureDialog(Container pane) {
276 setTitle("Delete Measure");
277 labelA = new JLabel("Delete at:", JLabel.RIGHT);
279 labelB = new JLabel("Measure count:", JLabel.RIGHT);
281 textFieldA = new JTextField();
282 pane.add(textFieldA);
283 textFieldB = new JTextField();
284 pane.add(textFieldB);
285 cancelButton = new JButton("Cancel");
286 pane.add(cancelButton);
287 okButton = new JButton("OK");
290 labelA.setBounds(20, 20, 110 ,20);
291 labelB.setBounds(20, 50, 110, 20);
292 textFieldA.setBounds(140 ,20 , 40, 20);
293 textFieldB.setBounds(140,50, 40, 20);
294 cancelButton.setBounds(20 ,95 , 80, 30);
295 okButton.setBounds(120, 95, 60, 30);
300 setLocationRelativeTo(Moosique.getGUI());
305 * Builds the set tempo dialog.
306 * @param pane The container to put the dialog in.
307 * @param tracks A array containing miditracks.
309 private void makeSetTempoDialog(Container pane) {
311 setTitle("Set tempo");
312 // creating labels and adding them to a container
313 labelA = new JLabel("Measure", JLabel.CENTER);
315 labelB = new JLabel("Beat", JLabel.CENTER);
317 labelC = new JLabel("Tick", JLabel.CENTER);
319 labelD = new JLabel("Start at:", JLabel.RIGHT);
321 labelE = new JLabel("End at:", JLabel.RIGHT);
323 labelF = new JLabel("to", JLabel.CENTER);
326 // the starting textfields and adding them to the container
327 textFieldA = new JTextField();
328 pane.add(textFieldA);
329 textFieldB = new JTextField();
330 pane.add(textFieldB);
331 textFieldC = new JTextField();
332 pane.add(textFieldC);
333 // ending textfields and adding them to the container
334 textFieldD = new JTextField();
335 pane.add(textFieldD);
336 textFieldE = new JTextField();
337 pane.add(textFieldE);
338 textFieldF = new JTextField();
339 pane.add(textFieldF);
340 // the amount to edit textfields and adding them to a container
341 textFieldG = new JTextField();
342 pane.add(textFieldG);
343 textFieldH = new JTextField();
344 pane.add(textFieldH);
345 textFieldI = new JTextField();
346 pane.add(textFieldI);
347 textFieldJ = new JTextField();
348 pane.add(textFieldJ);
349 textFieldK = new JTextField();
350 pane.add(textFieldK);
352 // creating the buttons and adding them to the container
353 JRadioButton constant = new JRadioButton("Set constant tempo of:");
354 constant.setSelected(true);
356 JRadioButton change = new JRadioButton("Gradually change tempo:");
358 JRadioButton scale = new JRadioButton("Scale tempo in %:");
360 JRadioButton add = new JRadioButton("Add to current tempo:");
363 // creating a buttongroup and adding the buttons above
364 ButtonGroup group = new ButtonGroup();
370 // creating the cancel and ok button
371 cancelButton = new JButton("Cancel");
372 pane.add(cancelButton);
373 okButton = new JButton("OK");
377 labelA.setBounds(80, 25, 50, 20);
378 labelB.setBounds(145, 25, 50, 20);
379 labelC.setBounds(210, 25, 50, 20);
380 labelD.setBounds(20, 45, 60, 20);
381 labelE.setBounds(20, 65, 60, 20);
382 labelF.setBounds(255, 125, 20 ,20);
384 textFieldA.setBounds(80, 45, 50, 20);
385 textFieldB.setBounds(145, 45, 50, 20);
386 textFieldC.setBounds(210, 45, 50, 20);
387 textFieldD.setBounds(80, 65, 50, 20);
388 textFieldE.setBounds(145, 65, 50, 20);
389 textFieldF.setBounds(210, 65, 50, 20);
391 textFieldG.setBounds(205, 100, 35, 20);
392 textFieldH.setBounds(220, 125, 35, 20);
393 textFieldI.setBounds(280, 125, 35, 20);
394 textFieldJ.setBounds(170, 150, 35, 20);
395 textFieldK.setBounds(200, 175, 35, 20);
397 constant.setBounds(20, 100, 180, 20);
398 change.setBounds(20, 125, 200, 20);
399 scale.setBounds(20, 150, 150, 20);
400 add.setBounds(20, 175, 175, 20);
402 cancelButton.setBounds(75, 215, 80, 30);
403 okButton.setBounds(195, 215, 60, 30);
408 setLocationRelativeTo(Moosique.getGUI());
413 private void makeTextDialog(Container pane, String filename) {
414 setTitle("User Manual");
415 pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
416 File manual = new File(filename);
419 BufferedReader br = new BufferedReader(new FileReader(manual));
420 char[] chars = new char[(int)manual.length()];
421 br.read(chars, 0, (int)manual.length());
422 s = new String(chars);
423 } catch (Exception ex) {
424 s = "Manual not found";
426 pane.add(new JScrollPane(new JTextArea(s, 30, 95)));
427 Action close = new AbstractAction("Close") {
428 public void actionPerformed(ActionEvent ae) {
431 JButton closeButton = new JButton(close);
432 closeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
433 pane.add(closeButton);
436 setLocationRelativeTo(Moosique.getGUI());
440 private MooNote note;
441 private JOptionPane optionPane;
442 private JTextField pitch;
443 private JTextField velocity;
444 private JTextField length;
447 * Creates a new note preference dialog.
448 * @param mn the note that will be graphically represented
450 public MooDialog(MooNote mn) {
451 super(Moosique.getGUI(), "Note properties", false);
453 pitch = new JTextField(new Integer(note.getPitch()).toString(),3);
454 JPanel pitchpanel = new JPanel();
455 pitchpanel.add(new Label("Pitch: "));
456 pitchpanel.add(pitch);
458 velocity = new JTextField(new Integer(note.getVelocity()).toString(),3);
459 JPanel velocitypanel = new JPanel();
460 velocitypanel.add(new Label("Velocity: "));
461 velocitypanel.add(velocity);
463 length = new JTextField(new Integer(note.getDuration()).toString(),5);
464 JPanel lengthpanel = new JPanel();
465 lengthpanel.add(new Label("Length: "));
466 lengthpanel.add(length);
468 Object[] array = {"Set the note properties",
473 final String btnString1 = "Apply changes";
474 final String btnString2 = "Cancel";
475 Object[] options = {btnString1, btnString2};
477 optionPane = new JOptionPane(array,
478 JOptionPane.QUESTION_MESSAGE,
479 JOptionPane.YES_NO_OPTION,
483 setContentPane(optionPane);
484 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
486 ActionListener intValidator = new ActionListener() {
487 public void actionPerformed(ActionEvent e) {
488 if (e.getSource() instanceof JTextField){
489 JTextField s = (JTextField)e.getSource();
490 int num = Integer.parseInt(s.getText());
493 else if (num > 127 && s != length)
495 s.setText(new Integer(num).toString());
499 pitch.addActionListener(intValidator);
500 velocity.addActionListener(intValidator);
501 length.addActionListener(intValidator);
503 optionPane.addPropertyChangeListener(new PropertyChangeListener() {
504 public void propertyChange(PropertyChangeEvent e) {
505 String prop = e.getPropertyName();
508 && (e.getSource() == optionPane)
509 && (prop.equals(JOptionPane.VALUE_PROPERTY) ||
510 prop.equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
511 Object value = optionPane.getValue();
513 if (value == JOptionPane.UNINITIALIZED_VALUE) {
518 // Reset the JOptionPane's value.
519 // If you don't do this, then if the user
520 // presses the same button next time, no
521 // property change event will be fired.
523 JOptionPane.UNINITIALIZED_VALUE);
525 if (value.equals(btnString1)) {
526 note.setPitch(Integer.parseInt(pitch.getText()));
527 note.setVelocity(Integer.parseInt(velocity.getText()));
528 note.setDuration(Integer.parseInt(length.getText()));
529 Moosique.setEdited();
531 } else { // user closed dialog or clicked cancel