]> 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         
31         /**
32          * Constructor of the dialogs.
33          */
34          public MooDialog(int type) {
35                 super(Moosique.getGUI(), false);
36                         
37                 Container pane = getContentPane();
38                 pane.setLayout(null);
39                 
40                 Track[] tracks = Moosique.getSequence().getTracks();
41
42                 switch (type) {
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;
52                 }
53          }
54         
55         /**
56          * Builds the add track popupdialog.
57          * @param pane          The container to put the dialog in.
58          * @param tracks        A array containing miditracks.
59          */
60         private void makeAddDialog(Container pane, Track[] tracks) {
61         
62                 setTitle("Add track");
63                 labelA = new JLabel("Name of track", JLabel.CENTER);
64                 pane.add(labelA);
65                 textFieldA = new JTextField();  
66                 pane.add(textFieldA);
67                 labelB = new JLabel("Add after", JLabel.CENTER);
68                 pane.add(labelB);
69                 trackListA = new JComboBox();
70                 for (int i = 1; i <= tracks.length; i++) trackListA.addItem("Track " + i);
71                 pane.add(trackListA);
72                 cancelButton = new JButton("Cancel");
73                 pane.add(cancelButton);
74                 okButton = new JButton("OK");
75                 pane.add(okButton);
76         
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);
83         
84                 setResizable(false);
85                 pack();
86                 setSize(200,220);
87                 setLocationRelativeTo(Moosique.getGUI());
88                 setVisible(true);
89         }
90         
91         /**
92          * Builds the delete track popupdialog.
93          * @param pane          The container to put the dialog in.
94          * @param tracks        A array containing miditracks.
95          */
96         private void makeDelDialog(Container pane, Track[] tracks) {
97         
98                 setTitle("Delete track");
99                 labelB = new JLabel("Delete track", JLabel.CENTER);
100                 pane.add(labelB);
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");
107                 pane.add(okButton);
108                         
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);
113         
114                 setResizable(false);
115                 pack();
116                 setSize(200,165);
117                 setLocationRelativeTo(Moosique.getGUI());
118                 setVisible(true);
119         }
120         
121         /**
122          * Builds the copy track popupdialog.
123          * @param pane          The container to put the dialog in.
124          * @param tracks        A array containing miditracks.
125          */
126         private void makeCopyDialog(Container pane, Track[] tracks) {
127         
128                 setTitle("Copy Track");
129                 labelA = new JLabel("Track to copy", JLabel.CENTER);
130                 pane.add(labelA);
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);
135                 pane.add(labelB);
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");
142                 pane.add(okButton);
143                 
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);
150         
151                 setResizable(false);
152                 pack();
153                 setSize(200,220);
154                 setLocationRelativeTo(Moosique.getGUI());
155                 setVisible(true);
156         }
157         
158         /**
159          * Builds the move track popupdialog
160          * @param pane          The container to put the dialog in.
161          * @param tracks        A array containing miditracks.
162          */
163         private void makeMoveDialog(Container pane, Track[] tracks) {
164         
165                 setTitle("Move track");
166                 labelA = new JLabel("Track to move", JLabel.CENTER);
167                 pane.add(labelA);
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);
172                 pane.add(labelB);
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");
179                 pane.add(okButton);
180                 
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);
187         
188                 setResizable(false);
189                 pack();
190                 setSize(200,220);
191                 setLocationRelativeTo(Moosique.getGUI());
192                 setVisible(true);
193         }
194         
195         /**
196          * Builds the set position dialog.
197          * @param pane          The container to put the dialog in.
198          * @param tracks        A array containing miditracks.
199          */
200         private void makeSetPositionDialog(Container pane) {
201                 
202                 setTitle("Set edit position");
203                 labelA = new JLabel("Measure", JLabel.CENTER);
204                 pane.add(labelA);
205                 labelB = new JLabel("Beat", JLabel.CENTER);
206                 pane.add(labelB);
207                 labelC = new JLabel("Tick", JLabel.CENTER);
208                 pane.add(labelC);
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");
218                 pane.add(okButton);
219                 
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);
228                 
229                 setResizable(false);
230                 pack();
231                 setSize(260,165);
232                 setLocationRelativeTo(Moosique.getGUI());
233                 setVisible(true);
234         }
235         
236         /**
237          * Builds the insert measure popupdialog.
238          * @param pane          The container to put the dialog in.
239          */
240         private void makeInsertMeasureDialog(Container pane){
241         
242                 setTitle("Insert Measure");
243                 labelA = new JLabel("Insert at:", JLabel.RIGHT);
244                 pane.add(labelA);
245                 labelB = new JLabel("Measure count:", JLabel.RIGHT);
246                 pane.add(labelB);
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");
254                 pane.add(okButton);
255                 
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);
262                 
263                 setResizable(false);
264                 pack();
265                 setSize(210,175);
266                 setLocationRelativeTo(Moosique.getGUI());
267                 setVisible(true);
268         }
269         
270         /**
271          * Builds the delete measure popupdialog.
272          * @param pane          The container to put the dialog in.
273          */
274         private void makeDeleteMeasureDialog(Container pane) {
275         
276                 setTitle("Delete Measure");
277                 labelA = new JLabel("Delete at:", JLabel.RIGHT);
278                 pane.add(labelA);
279                 labelB = new JLabel("Measure count:", JLabel.RIGHT);
280                 pane.add(labelB);
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");
288                 pane.add(okButton);
289                 
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);
296                 
297                 setResizable(false);
298                 pack();
299                 setSize(210,175);
300                 setLocationRelativeTo(Moosique.getGUI());
301                 setVisible(true);
302         }
303         
304         /**
305          * Builds the set tempo dialog.
306          * @param pane          The container to put the dialog in.
307          * @param tracks        A array containing miditracks.
308          */
309         private void makeSetTempoDialog(Container pane) {
310                 
311                 setTitle("Set tempo");
312                 // creating labels and adding them to a container
313                 labelA = new JLabel("Measure", JLabel.CENTER);
314                 pane.add(labelA);
315                 labelB = new JLabel("Beat", JLabel.CENTER);
316                 pane.add(labelB);
317                 labelC = new JLabel("Tick", JLabel.CENTER);
318                 pane.add(labelC);
319                 labelD = new JLabel("Start at:", JLabel.RIGHT);
320                 pane.add(labelD);
321                 labelE = new JLabel("End at:", JLabel.RIGHT);
322                 pane.add(labelE);
323                 labelF = new JLabel("to", JLabel.CENTER);
324                 pane.add(labelF);
325                  
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);
351
352                 // creating the buttons and adding them to the container
353                 JRadioButton constant = new JRadioButton("Set constant tempo of:");
354                 constant.setSelected(true);
355                 pane.add(constant);
356                 JRadioButton change = new JRadioButton("Gradually change tempo:");
357                 pane.add(change);
358                 JRadioButton scale = new JRadioButton("Scale tempo in %:");
359                 pane.add(scale);
360                 JRadioButton add = new JRadioButton("Add to current tempo:");
361                 pane.add(add);
362                 
363                 // creating a buttongroup and adding the buttons above
364                 ButtonGroup group = new ButtonGroup();
365                 group.add(constant);
366                 group.add(change);
367                 group.add(scale);
368                 group.add(add);
369                 
370                 // creating the cancel and ok button
371                 cancelButton = new JButton("Cancel");
372                 pane.add(cancelButton);
373                 okButton = new JButton("OK");
374                 pane.add(okButton);
375                 
376                 
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);
383       
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);
390                 
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);
396                 
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);
401                 
402                 cancelButton.setBounds(75, 215, 80, 30);
403                 okButton.setBounds(195, 215, 60, 30);
404                 
405                 setResizable(false);
406                 pack();
407                 setSize(340,300);
408                 setLocationRelativeTo(Moosique.getGUI());
409                 setVisible(true);
410         }
411         
412         
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);
417                 String s;
418                 try {
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";
425                 }
426                 pane.add(new JScrollPane(new JTextArea(s, 30, 95)));
427                 Action close = new AbstractAction("Close") {
428                         public void actionPerformed(ActionEvent ae) {
429                                 setVisible(false);
430                         }};
431                 JButton closeButton = new JButton(close);
432                 closeButton.setAlignmentX(Component.CENTER_ALIGNMENT);
433                 pane.add(closeButton);
434                 setResizable(false);
435                 pack();
436                 setLocationRelativeTo(Moosique.getGUI());
437                 setVisible(true);
438         }
439
440         private MooNote note;
441         private JOptionPane optionPane;
442         private JTextField pitch;
443         private JTextField velocity;
444         private JTextField length;
445         
446         /** 
447          * Creates a new note preference dialog.
448          * @param mn    the note that will be graphically represented
449          */
450         public MooDialog(MooNote mn) {
451                 super(Moosique.getGUI(), "Note properties", false);
452                 note = mn;
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);
457
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);
462
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);
467
468                 Object[] array = {"Set the note properties",
469                                 pitchpanel,
470                                 velocitypanel,
471                                 lengthpanel};
472         
473                 final String btnString1 = "Apply changes";
474                 final String btnString2 = "Cancel";
475                 Object[] options = {btnString1, btnString2};
476         
477                 optionPane = new JOptionPane(array, 
478                                             JOptionPane.QUESTION_MESSAGE,
479                                             JOptionPane.YES_NO_OPTION,
480                                             null,
481                                             options,
482                                             options[0]);
483                 setContentPane(optionPane);
484                 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
485         
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());
491                                                 if (num < 0)
492                                                         num = 0;
493                                                 else if (num > 127 && s != length)
494                                                         num = 127;
495                                                 s.setText(new Integer(num).toString());
496                                         }
497                     }
498                 };
499                 pitch.addActionListener(intValidator);
500                 velocity.addActionListener(intValidator);
501                 length.addActionListener(intValidator);
502
503                 optionPane.addPropertyChangeListener(new PropertyChangeListener() {
504                     public void propertyChange(PropertyChangeEvent e) {
505                         String prop = e.getPropertyName();
506         
507                         if (isVisible() 
508                          && (e.getSource() == optionPane)
509                          && (prop.equals(JOptionPane.VALUE_PROPERTY) ||
510                              prop.equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
511                             Object value = optionPane.getValue();
512         
513                             if (value == JOptionPane.UNINITIALIZED_VALUE) {
514                                 //ignore reset
515                                 return;
516                             }
517         
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.
522                             optionPane.setValue(
523                                     JOptionPane.UNINITIALIZED_VALUE);
524         
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();
530                                                         setVisible(false);
531                             } else { // user closed dialog or clicked cancel
532                                 setVisible(false);
533                             }
534                         }
535                     }
536                 });
537                 pack();
538                 setVisible(true);
539         }
540 }