]> ruin.nu Git - moosique.git/blob - MooDialog.java
*** empty log message ***
[moosique.git] / MooDialog.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 import javax.sound.midi.*;
5 import java.io.*;
6 import java.beans.*;
7
8 /**
9  * A generator class for the application's dialogs.
10  *
11  * @author Björn Lanneskog
12  */
13  
14 public class MooDialog extends JDialog {
15
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,
22                                 DELETE_TRACK = 2,
23                                 COPY_TRACK = 3,
24                                 MOVE_TRACK = 4,
25                                 SET_POSITION = 5,
26                                 MANUAL = 6,
27                                 INSERT_MEASURE = 7,
28                                 DELETE_MEASURE = 8,
29                                 SET_TEMPO = 9,
30                                 PREFERENCES = 10;
31         
32         /**
33          * Constructor of the dialogs.
34          */
35          public MooDialog(int type) {
36                 super(Moosique.getGUI(), false);
37                         
38                 Container pane = getContentPane();
39                 pane.setLayout(null);
40                 
41                 Track[] tracks = Moosique.getSequence().getTracks();
42
43                 switch (type) {
44                         case ADD_TRACK:         makeAddDialog(pane, tracks); break;
45                         case DELETE_TRACK:      makeDelDialog(pane, tracks); break;
46                         case COPY_TRACK:        makeCopyDialog(pane, tracks); break;
47                         case MOVE_TRACK:        makeMoveDialog(pane, tracks); break;
48                         case SET_POSITION:      makeSetPositionDialog(pane); break;
49                         case MANUAL:            makeTextDialog(pane, "Manual.txt"); break;
50                         case INSERT_MEASURE:    makeInsertMeasureDialog(pane); break;
51                         case DELETE_MEASURE:    makeDeleteMeasureDialog(pane); break;
52                         case SET_TEMPO:         makeSetTempoDialog(pane); break;
53                         case PREFERENCES:       makePrefsDialog(pane); break;
54                 }
55          }
56         
57         /**
58          * Builds the add track popupdialog.
59          * @param pane          The container to put the dialog in.
60          * @param tracks        A array containing miditracks.
61          */
62         private void makeAddDialog(Container pane, Track[] tracks) {
63         
64                 setTitle("Add track");
65                 labelA = new JLabel("Name of track", JLabel.CENTER);
66                 pane.add(labelA);
67                 textFieldA = new JTextField();  
68                 pane.add(textFieldA);
69                 labelB = new JLabel("Add after", JLabel.CENTER);
70                 pane.add(labelB);
71                 trackListA = new JComboBox();
72                 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
73                 pane.add(trackListA);
74                 cancelButton = new JButton("Cancel");
75                 pane.add(cancelButton);
76                 okButton = new JButton("OK");
77                 pane.add(okButton);
78         
79                 labelA.setBounds(50, 10, 100, 20);
80                 textFieldA.setBounds(40, 35, 120, 20);
81                 labelB.setBounds(50, 70, 100, 20);
82                 trackListA.setBounds(40, 95, 120, 20);
83                 cancelButton.setBounds(10, 150, 80, 30);
84                 okButton.setBounds(120, 150, 60, 30);
85         
86                 setResizable(false);
87                 pack();
88                 setSize(200,220);
89                 setLocationRelativeTo(Moosique.getGUI());
90                 setVisible(true);
91         }
92         
93         /**
94          * Builds the delete track popupdialog.
95          * @param pane          The container to put the dialog in.
96          * @param tracks        A array containing miditracks.
97          */
98         private void makeDelDialog(Container pane, Track[] tracks) {
99         
100                 setTitle("Delete track");
101                 labelB = new JLabel("Delete track", JLabel.CENTER);
102                 pane.add(labelB);
103                 trackListA = new JComboBox();
104                 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
105                 pane.add(trackListA);
106                 cancelButton = new JButton("Cancel");
107                 pane.add(cancelButton);
108                 okButton = new JButton("OK");
109                 pane.add(okButton);
110                         
111                 labelB.setBounds(50, 10, 100, 20);
112                 trackListA.setBounds(40, 35, 120, 20);
113                 cancelButton.setBounds(10, 90, 80, 30);
114                 okButton.setBounds(120, 90, 60, 30);
115         
116                 setResizable(false);
117                 pack();
118                 setSize(200,165);
119                 setLocationRelativeTo(Moosique.getGUI());
120                 setVisible(true);
121         }
122         
123         /**
124          * Builds the copy track popupdialog.
125          * @param pane          The container to put the dialog in.
126          * @param tracks        A array containing miditracks.
127          */
128         private void makeCopyDialog(Container pane, Track[] tracks) {
129         
130                 setTitle("Copy Track");
131                 labelA = new JLabel("Track to copy", JLabel.CENTER);
132                 pane.add(labelA);
133                 trackListA = new JComboBox();
134                 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
135                 pane.add(trackListA);
136                 labelB = new JLabel("Insert after", JLabel.CENTER);
137                 pane.add(labelB);
138                 trackListB = new JComboBox();
139                 for (int i = 1; i <= tracks.length; i++) trackListB.addItem("Track " + i);
140                 pane.add(trackListB);
141                 cancelButton = new JButton("Cancel");
142                 pane.add(cancelButton);
143                 okButton = new JButton("OK");
144                 pane.add(okButton);
145                 
146                 labelA.setBounds(50, 10, 100, 20);
147                 trackListA.setBounds(40, 35, 120, 20);
148                 labelB.setBounds(50, 70, 100, 20);
149                 trackListB.setBounds(40, 95, 120, 20);
150                 cancelButton.setBounds(10, 150, 80, 30);
151                 okButton.setBounds(120, 150, 60, 30);
152         
153                 setResizable(false);
154                 pack();
155                 setSize(200,220);
156                 setLocationRelativeTo(Moosique.getGUI());
157                 setVisible(true);
158         }
159         
160         /**
161          * Builds the move track popupdialog
162          * @param pane          The container to put the dialog in.
163          * @param tracks        A array containing miditracks.
164          */
165         private void makeMoveDialog(Container pane, Track[] tracks) {
166         
167                 setTitle("Move track");
168                 labelA = new JLabel("Track to move", JLabel.CENTER);
169                 pane.add(labelA);
170                 trackListA = new JComboBox();
171                 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
172                 pane.add(trackListA);
173                 labelB = new JLabel("Insert after", JLabel.CENTER);
174                 pane.add(labelB);
175                 trackListB = new JComboBox();
176                 for (int i = 1; i <= tracks.length; i++) trackListB.addItem("Track " + i);
177                 pane.add(trackListB);
178                 cancelButton = new JButton("Cancel");
179                 pane.add(cancelButton);
180                 okButton = new JButton("OK");
181                 pane.add(okButton);
182                 
183                 labelA.setBounds(40, 10, 120, 20);
184                 trackListA.setBounds(40, 35, 120, 20);
185                 labelB.setBounds(50, 70, 100, 20);
186                 trackListB.setBounds(40, 95, 120, 20);
187                 cancelButton.setBounds(10, 150, 80, 30);
188                 okButton.setBounds(120, 150, 60, 30);
189         
190                 setResizable(false);
191                 pack();
192                 setSize(200,220);
193                 setLocationRelativeTo(Moosique.getGUI());
194                 setVisible(true);
195         }
196         
197         /**
198          * Builds the set position dialog.
199          * @param pane          The container to put the dialog in.
200          * @param tracks        A array containing miditracks.
201          */
202         private void makeSetPositionDialog(Container pane) {
203                 
204                 setTitle("Set edit position");
205                 labelA = new JLabel("Measure", JLabel.CENTER);
206                 pane.add(labelA);
207                 labelB = new JLabel("Beat", JLabel.CENTER);
208                 pane.add(labelB);
209                 labelC = new JLabel("Tick", JLabel.CENTER);
210                 pane.add(labelC);
211                 textFieldA = new JTextField();
212                 pane.add(textFieldA);
213                 textFieldB = new JTextField();
214                 pane.add(textFieldB);
215                 textFieldC = new JTextField();
216                 pane.add(textFieldC);
217                 cancelButton = new JButton("Cancel");
218                 pane.add(cancelButton);
219                 okButton = new JButton("OK");
220                 pane.add(okButton);
221                 
222                 labelA.setBounds(40, 25, 50, 20);
223                 labelB.setBounds(105, 25, 50, 20);
224                 labelC.setBounds(170, 25, 50, 20);
225                 textFieldA.setBounds(40, 45, 50, 20);
226                 textFieldB.setBounds(105, 45, 50, 20);
227                 textFieldC.setBounds(170, 45, 50, 20);
228                 cancelButton.setBounds(35, 90, 80, 30);
229                 okButton.setBounds(155, 90, 60, 30);
230                 
231                 setResizable(false);
232                 pack();
233                 setSize(260,165);
234                 setLocationRelativeTo(Moosique.getGUI());
235                 setVisible(true);
236         }
237         
238         /**
239          * Builds the insert measure popupdialog.
240          * @param pane          The container to put the dialog in.
241          */
242         private void makeInsertMeasureDialog(Container pane){
243         
244                 setTitle("Insert Measure");
245                 labelA = new JLabel("Insert at:", JLabel.RIGHT);
246                 pane.add(labelA);
247                 labelB = new JLabel("Measure count:", JLabel.RIGHT);
248                 pane.add(labelB);
249                 textFieldA = new JTextField();
250                 pane.add(textFieldA);
251                 textFieldB = new JTextField();
252                 pane.add(textFieldB);
253                 cancelButton = new JButton("Cancel");
254                 pane.add(cancelButton);
255                 okButton = new JButton("OK");
256                 pane.add(okButton);
257                 
258                 labelA.setBounds(20, 20, 110 ,20);
259                 labelB.setBounds(20, 50, 110, 20);
260                 textFieldA.setBounds(140 ,20 , 40, 20);
261                 textFieldB.setBounds(140,50, 40, 20);
262                 cancelButton.setBounds(20 ,95 , 80, 30);
263                 okButton.setBounds(120, 95, 60, 30);
264                 
265                 setResizable(false);
266                 pack();
267                 setSize(210,175);
268                 setLocationRelativeTo(Moosique.getGUI());
269                 setVisible(true);
270         }
271         
272         /**
273          * Builds the delete measure popupdialog.
274          * @param pane          The container to put the dialog in.
275          */
276         private void makeDeleteMeasureDialog(Container pane) {
277         
278                 setTitle("Delete Measure");
279                 labelA = new JLabel("Delete at:", JLabel.RIGHT);
280                 pane.add(labelA);
281                 labelB = new JLabel("Measure count:", JLabel.RIGHT);
282                 pane.add(labelB);
283                 textFieldA = new JTextField();
284                 pane.add(textFieldA);
285                 textFieldB = new JTextField();
286                 pane.add(textFieldB);
287                 cancelButton = new JButton("Cancel");
288                 pane.add(cancelButton);
289                 okButton = new JButton("OK");
290                 pane.add(okButton);
291                 
292                 labelA.setBounds(20, 20, 110 ,20);
293                 labelB.setBounds(20, 50, 110, 20);
294                 textFieldA.setBounds(140 ,20 , 40, 20);
295                 textFieldB.setBounds(140,50, 40, 20);
296                 cancelButton.setBounds(20 ,95 , 80, 30);
297                 okButton.setBounds(120, 95, 60, 30);
298                 
299                 setResizable(false);
300                 pack();
301                 setSize(210,175);
302                 setLocationRelativeTo(Moosique.getGUI());
303                 setVisible(true);
304         }
305         
306         /**
307          * Builds the set tempo dialog.
308          * @param pane          The container to put the dialog in.
309          * @param tracks        A array containing miditracks.
310          */
311         private void makeSetTempoDialog(Container pane) {
312                 
313                 setTitle("Set tempo");
314                 // creating labels and adding them to a container
315                 labelA = new JLabel("Measure", JLabel.CENTER);
316                 pane.add(labelA);
317                 labelB = new JLabel("Beat", JLabel.CENTER);
318                 pane.add(labelB);
319                 labelC = new JLabel("Tick", JLabel.CENTER);
320                 pane.add(labelC);
321                 labelD = new JLabel("Start at:", JLabel.RIGHT);
322                 pane.add(labelD);
323                 labelE = new JLabel("End at:", JLabel.RIGHT);
324                 pane.add(labelE);
325                 labelF = new JLabel("to", JLabel.CENTER);
326                 pane.add(labelF);
327                  
328                 // the starting textfields and adding them to the container
329                 textFieldA = new JTextField();
330                 pane.add(textFieldA);
331                 textFieldB = new JTextField();
332                 pane.add(textFieldB);
333                 textFieldC = new JTextField();
334                 pane.add(textFieldC);
335                 // ending textfields and adding them to the container
336                 textFieldD = new JTextField();
337                 pane.add(textFieldD);
338                 textFieldE = new JTextField();
339                 pane.add(textFieldE);
340                 textFieldF = new JTextField();
341                 pane.add(textFieldF);
342                 // the amount to edit textfields and adding them to a container
343                 textFieldG = new JTextField();
344                 pane.add(textFieldG);
345                 textFieldH = new JTextField();
346                 pane.add(textFieldH);
347                 textFieldI = new JTextField();
348                 pane.add(textFieldI);
349                 textFieldJ = new JTextField();
350                 pane.add(textFieldJ);
351                 textFieldK = new JTextField();
352                 pane.add(textFieldK);
353
354                 // creating the buttons and adding them to the container
355                 JRadioButton constant = new JRadioButton("Set constant tempo of:");
356                 constant.setSelected(true);
357                 pane.add(constant);
358                 JRadioButton change = new JRadioButton("Gradually change tempo:");
359                 pane.add(change);
360                 JRadioButton scale = new JRadioButton("Scale tempo in %:");
361                 pane.add(scale);
362                 JRadioButton add = new JRadioButton("Add to current tempo:");
363                 pane.add(add);
364                 
365                 // creating a buttongroup and adding the buttons above
366                 ButtonGroup group = new ButtonGroup();
367                 group.add(constant);
368                 group.add(change);
369                 group.add(scale);
370                 group.add(add);
371                 
372                 // creating the cancel and ok button
373                 cancelButton = new JButton("Cancel");
374                 pane.add(cancelButton);
375                 okButton = new JButton("OK");
376                 pane.add(okButton);
377                 
378                 
379                 labelA.setBounds(80, 25, 50, 20);
380                 labelB.setBounds(145, 25, 50, 20);
381                 labelC.setBounds(210, 25, 50, 20);
382                 labelD.setBounds(20, 45, 60, 20);
383                 labelE.setBounds(20, 65, 60, 20);
384                 labelF.setBounds(255, 125, 20 ,20);
385       
386                 textFieldA.setBounds(80, 45, 50, 20);
387                 textFieldB.setBounds(145, 45, 50, 20);
388                 textFieldC.setBounds(210, 45, 50, 20);
389                 textFieldD.setBounds(80, 65, 50, 20);
390                 textFieldE.setBounds(145, 65, 50, 20);
391                 textFieldF.setBounds(210, 65, 50, 20);
392                 
393                 textFieldG.setBounds(205, 100, 35, 20);
394                 textFieldH.setBounds(220, 125, 35, 20);
395                 textFieldI.setBounds(280, 125, 35, 20);
396                 textFieldJ.setBounds(170, 150, 35, 20);
397                 textFieldK.setBounds(200, 175, 35, 20);
398                 
399                 constant.setBounds(20, 100, 180, 20);
400                 change.setBounds(20, 125, 200, 20);
401                 scale.setBounds(20, 150, 150, 20);
402                 add.setBounds(20, 175, 175, 20);
403                 
404                 cancelButton.setBounds(75, 215, 80, 30);
405                 okButton.setBounds(195, 215, 60, 30);
406                 
407                 setResizable(false);
408                 pack();
409                 setSize(340,300);
410                 setLocationRelativeTo(Moosique.getGUI());
411                 setVisible(true);
412         }
413         
414         
415         private void makeTextDialog(Container pane, String filename) {
416                 setTitle("User Manual");
417                 pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
418                 File manual = new File(filename);
419                 String s;
420                 try {
421                         BufferedReader br = new BufferedReader(new FileReader(manual));
422                         char[] chars = new char[(int)manual.length()];
423                         br.read(chars, 0, (int)manual.length());
424                         s = new String(chars);
425                 } catch (Exception ex) {
426                         s = "Manual not found";
427                 }
428                 pane.add(new JScrollPane(new JTextArea(s, 30, 95)));
429                 Action close = new AbstractAction("Close") {
430                         public void actionPerformed(ActionEvent ae) {
431                                 setVisible(false);
432                         }};
433                 JButton closeButton = new JButton(close);
434                 closeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
435                 pane.add(closeButton);
436                 setResizable(false);
437                 pack();
438                 setLocationRelativeTo(Moosique.getGUI());
439                 setVisible(true);
440         }
441
442         private void makePrefsDialog(Container pane) {
443                 /*              
444                 MidiDevice.Info[] devInfo = MidiSystem.getMidiDeviceInfo();
445                 for (int i = 0; i < devInfo.length; i++) {
446                         if (MidiSystem.getMidiDevice(devInfo[i]) instanceof Sequencer) {
447                         
448                         } else if (MidiSystem.getMidiDevice(devInfo[i]) instanceof Synthesizer) {
449                         
450                         }
451                 }
452                 String[] seqNames, synthNames;
453                 JPanel pane = (JPanel) this.getContentPane();
454                 pane.add(new JLabel("Sequencer"));
455                 JComboBox seqBox = new JComboBox(seqNames);
456                 pane.add(new JLabel("Synthesizer"));
457                 JComboBox synthBox = new JComboBox(synthNames);
458                 */
459         }
460
461         private MooNote note;
462         private JOptionPane optionPane;
463         private JTextField pitch;
464         private JTextField velocity;
465         private JTextField length;
466         
467         /** 
468          * Creates a new note preference dialog.
469          * @param mn    the note that will be graphically represented
470          */
471         public MooDialog(MooNote mn) {
472                 super(Moosique.getGUI(), "Note properties", true);
473                 JPanel panel = new JPanel();
474                 panel.setLayout(new GridLayout(3,2));
475                 note = mn;
476                 pitch = new JTextField(new Integer(note.getPitch()).toString(),3);
477                 panel.add(new Label("Pitch: "));
478                 panel.add(pitch);
479
480                 velocity = new JTextField(new Integer(note.getVelocity()).toString(),3);
481                 panel.add(new Label("Velocity: "));
482                 panel.add(velocity);
483
484                 length = new JTextField(new Integer(note.getDuration()).toString(),5);
485                 panel.add(new Label("Length: "));
486                 panel.add(length);
487
488                 Object[] array = {"Set the note properties",
489                                 panel};
490         
491                 final String btnString1 = "Apply changes";
492                 final String btnString2 = "Cancel";
493                 Object[] options = {btnString1, btnString2};
494         
495                 optionPane = new JOptionPane(array, 
496                                             JOptionPane.QUESTION_MESSAGE,
497                                             JOptionPane.YES_NO_OPTION,
498                                             null,
499                                             options,
500                                             options[0]);
501                 setContentPane(optionPane);
502                 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
503         
504                 ActionListener intValidator = new ActionListener() {
505                     public void actionPerformed(ActionEvent e) {
506                                         if (e.getSource() instanceof JTextField){
507                                                 JTextField s = (JTextField)e.getSource();
508                                                 int num = Integer.parseInt(s.getText());
509                                                 if (num < 0)
510                                                         num = 0;
511                                                 else if (num > 127 && s != length)
512                                                         num = 127;
513                                                 s.setText(new Integer(num).toString());
514                                         }
515                     }
516                 };
517                 pitch.addActionListener(intValidator);
518                 velocity.addActionListener(intValidator);
519                 length.addActionListener(intValidator);
520
521                 optionPane.addPropertyChangeListener(new PropertyChangeListener() {
522                     public void propertyChange(PropertyChangeEvent e) {
523                         String prop = e.getPropertyName();
524         
525                         if (isVisible() 
526                          && (e.getSource() == optionPane)
527                          && (prop.equals(JOptionPane.VALUE_PROPERTY) ||
528                              prop.equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
529                             Object value = optionPane.getValue();
530         
531                             if (value == JOptionPane.UNINITIALIZED_VALUE) {
532                                 //ignore reset
533                                 return;
534                             }
535         
536                             // Reset the JOptionPane's value.
537                             // If you don't do this, then if the user
538                             // presses the same button next time, no
539                             // property change event will be fired.
540                             optionPane.setValue(
541                                     JOptionPane.UNINITIALIZED_VALUE);
542         
543                             if (value.equals(btnString1)) {
544                                                         note.setPitch(Integer.parseInt(pitch.getText()));
545                                                         note.setVelocity(Integer.parseInt(velocity.getText()));
546                                                         note.setDuration(Integer.parseInt(length.getText()));
547                                                         Moosique.setEdited();
548                                                         setVisible(false);
549                             } else { // user closed dialog or clicked cancel
550                                 setVisible(false);
551                             }
552                         }
553                     }
554                 });
555                 pack();
556                 setVisible(true);
557         }
558 }