Chromesthesia.java
1    package chromesthesia2;
2    
3    import java.util.Scanner;
4    import javax.swing.JOptionPane;
5    import javax.swing.SwingUtilities;
6    import painter.SPainter;
7    
8    public class Chromesthesia {
9        public static void main(String[] args){
10           SwingUtilities.invokeLater(new ThreadForGUI());
11       }
12   
13       private static class ThreadForGUI implements Runnable {
14   
15           @Override
16           public void run() {
17               new Chromesthesia();
18           }
19   
20       }
21   
22       public Chromesthesia(){
23           interpreter();
24       }
25   
26       private static SPainter miro;
27       private static Pitch[] pitches;
28   
29       public static void interpreter(){
30   
31           initialization();
32   
33           String lastInput = "";
34           String thisInput = "";
35   
36           while (true){
37   
38               String input = getInput();
39   
40               if (input.equalsIgnoreCase("EXIT")){
41                   break;
42               } else if (input.equalsIgnoreCase("AGAIN")){
43                   lastInput = thisInput;
44                   try {
45                       playMelody(thisInput,pitches);
46                   } catch (Exception ex) {
47                       showErrorMessage(ex.toString());
48                   }
49               } else {
50                   lastInput = thisInput;
51                   thisInput = input;
52                   try {
53                       playMelody(input,pitches);
54                   } catch (Exception ex) {
55                       showErrorMessage(ex.toString());
56                   }
57               }
58           }
59   
60           cleanup();
61   
62       }
63   
64       private static Pitch[] establishPitches(SPainter painter){
65   
66           Pitch[] pitches = new Pitch[21];
67   
68           Pitch pitchMiddleC = new Pitch("C",painter);
69           pitches[0] = pitchMiddleC;
70           Pitch pitchLowC = new Pitch("C,",painter);
71           pitches[1] = pitchLowC;
72           Pitch pitchHighC = new Pitch("c",painter);
73           pitches[2] = pitchHighC;
74   
75           Pitch pitchMiddleD = new Pitch("D",painter);
76           pitches[3] = pitchMiddleD;
77           Pitch pitchLowD = new Pitch("D,",painter);
78           pitches[4] = pitchLowD;
79           Pitch pitchHighD = new Pitch("d",painter);
80           pitches[5] = pitchHighD;
81   
82           Pitch pitchMiddleE = new Pitch("E",painter);
83           pitches[6] = pitchMiddleE;
84           Pitch pitchLowE = new Pitch("E,",painter);
85           pitches[7] = pitchLowE;
86           Pitch pitchHighE = new Pitch("e",painter);
87           pitches[8] = pitchHighE;
88   
89           Pitch pitchMiddleF = new Pitch("F",painter);
90           pitches[9] = pitchMiddleF;
91           Pitch pitchLowF = new Pitch("F,",painter);
92           pitches[10] = pitchLowF;
93           Pitch pitchHighF = new Pitch("f",painter);
94           pitches[11] = pitchHighF;
95   
96           Pitch pitchMiddleG = new Pitch("G",painter);
97           pitches[12] = pitchMiddleG;
98           Pitch pitchLowG = new Pitch("G,",painter);
99           pitches[13] = pitchLowG;
100          Pitch pitchHighG = new Pitch("g",painter);
101          pitches[14] = pitchHighG;
102  
103          Pitch pitchMiddleA = new Pitch("A",painter);
104          pitches[15] = pitchMiddleA;
105          Pitch pitchLowA = new Pitch("A,",painter);
106          pitches[16] = pitchLowA;
107          Pitch pitchHighA = new Pitch("a",painter);
108          pitches[17] = pitchHighA;
109  
110          Pitch pitchMiddleB = new Pitch("B",painter);
111          pitches[18] = pitchMiddleB;
112          Pitch pitchLowB = new Pitch("B,",painter);
113          pitches[19] = pitchLowB;
114          Pitch pitchHighB = new Pitch("b",painter);
115          pitches[20] = pitchHighB;
116  
117          return pitches;
118      }
119  
120      private static Pitch find(String token, Pitch[] pitches) throws Exception{
121  
122          for (int i = 0; i < pitches.length; i = i + 1){
123              Pitch pitch = pitches[i];
124              if (pitch.abcName().equals(token)){
125                  return pitch;
126              }
127          }
128  
129          throw new Exception("### PITCH " + token + " NOT FOUND");
130  
131      }
132  
133      private static void display(Pitch[] pitches){
134          for (int i = 0; i < pitches.length; i = i + 1){
135              System.out.println(pitches[i].toString());
136          }
137      }
138  
139      private static void playMelody(String input, Pitch[] pitches) throws Exception {
140  
141          Scanner scanner = new Scanner(input);
142          while (scanner.hasNext()){
143              String token = scanner.next();
144              String pitchName;
145              String duration = "";
146              if (token.indexOf(",") < 0){
147                  pitchName = token.substring(0,1);
148                  duration = token.substring(1);
149              } else {
150                  pitchName = token.substring(0,2);
151                  duration = token.substring(2);
152              }
153              if (duration.length() == 0) {
154                  duration = "1";
155              }
156              Pitch pitch = find(pitchName,pitches);
157              pitch.play(duration);
158  
159          }
160  
161      }
162  
163      static private void showErrorMessage(String message){
164          miro.setVisible(false);
165          JOptionPane.showMessageDialog(null,message);
166      }
167  
168      private static void initialization(){
169  
170          miro = new SPainter("Chromesthesia",500,500);
171          miro.setVisible(false);
172          miro.setBrushWidth(7);
173  
174          pitches = establishPitches(miro);
175          display(pitches);
176  
177      }
178  
179      private static String getInput(){
180  
181          miro.setVisible(false);
182          String label = "Please enter a melody in ABC notation, AGAIN, or EXIT ...     ";
183          String input = JOptionPane.showInputDialog(null,label);
184          miro.setVisible(true);
185          if (input == null ) {input = "";}
186  
187          return input;
188  
189      }
190  
191      static private void cleanup(){
192          System.exit(0);
193      }
194  
195  }
196