Source code: jm/gui/sketch/SketchScore.java
1 /*
2
3 <This Java Class is part of the jMusic API version 1.4, February 2003.>
4
5 Copyright (C) 2000 Andrew Sorensen & Andrew Brown
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or any
10 later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23 package jm.gui.sketch;
24
25 import java.awt.*;
26 import java.awt.event.*;
27 import java.util.Vector;
28 import java.util.Enumeration;
29 import jm.JMC;
30 import jm.music.data.*;
31 import jm.util.Write;
32 import jm.midi.*;
33
34 /**
35 * A jMusic tool which displays a score as a simple
36 * 'piano roll' display in a window.
37 * The tool displays a jMusic class as a simple piano roll view. To use it write:
38 * new ViewScore(scoreName);
39 * Where scoreName is the jMusic Score object.
40 * Alternately:
41 * new ViewScore(scoreName, xpos, ypos);
42 * Where xpos and ypos are intergers specifying the topleft position of the window.
43 * This is useful if you want to use ViewScore in conjunction with some other GUI interface
44 * which is already positioned in the top left corner of the screen.
45 * @author Andrew Brown and Andrew Troedson
46 * @version 1.0,Sun Feb 25 18:43
47 */
48
49 public class SketchScore extends Frame implements WindowListener, ActionListener {
50 //attributes
51 private static int maxWidth;
52 private static int maxParts;
53 protected static Score score;
54 protected double beatWidth = 10.0;
55 private Panel pan;
56 private SketchScoreArea sketchScoreArea;
57 private SketchRuler ruler;
58 private MenuItem play, speedUp, slowDown, clear, saveMIDI, quit, openMIDI, openXML, saveXML;
59
60 //--------------
61 //constructors
62 //--------------
63 public SketchScore(Score score) {
64 this(score, 0, 0);
65 }
66
67 public SketchScore(Score score, int xPos, int yPos) {
68 super("jMusic Sketch: '" + score.getTitle() + "'");
69 this.score = score;
70 this.getWidthAndParts();
71
72 //register the closebox event
73 this.addWindowListener(this);
74
75 pan = new Panel();
76 pan.setLayout(new BorderLayout());
77 sketchScoreArea = new SketchScoreArea(score, maxWidth, beatWidth);
78 sketchScoreArea.setSketchScore(this);
79 pan.add("Center", sketchScoreArea);
80
81 //add a ruler
82 ruler = new SketchRuler(this);
83 pan.add("South", ruler);
84
85 //add a scroll pane
86 ScrollPane sp = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
87 sp.getHAdjustable().setUnitIncrement(20); //set scroll speed
88 sp.add(pan);
89 this.add(sp);
90
91 // menus
92 MenuBar menus = new MenuBar();
93 Menu fileMenu = new Menu("Sketch", true);
94
95 play = new MenuItem("Play @ "+score.getTempo()+" bpm", new MenuShortcut(112));
96 play.addActionListener(this);
97 fileMenu.add(play);
98
99 speedUp = new MenuItem("Speed Up");
100 speedUp.addActionListener(this);
101 fileMenu.add(speedUp);
102
103 slowDown = new MenuItem("Slow Down");
104 slowDown.addActionListener(this);
105 fileMenu.add(slowDown);
106
107 clear = new MenuItem("Clear notes");
108 clear.addActionListener(this);
109 fileMenu.add(clear);
110
111 MenuItem dash = new MenuItem("-");
112 fileMenu.add(dash);
113
114 openMIDI = new MenuItem("Open a MIDI file...", new MenuShortcut(112));
115 openMIDI.addActionListener(this);
116 fileMenu.add(openMIDI);
117
118 openXML = new MenuItem("Open a jMusic XML file...");
119 openXML.addActionListener(this);
120 fileMenu.add(openXML);
121
122 saveMIDI = new MenuItem("Save as MIDI file", new MenuShortcut(115));
123 saveMIDI.addActionListener(this);
124 fileMenu.add(saveMIDI);
125
126 saveXML = new MenuItem("Save as a jMusic XML file");
127 saveXML.addActionListener(this);
128 fileMenu.add(saveXML);
129
130 quit = new MenuItem("Quit", new MenuShortcut(113));
131 quit.addActionListener(this);
132 fileMenu.add(quit);
133
134 menus.add(fileMenu);
135 this.setMenuBar(menus);
136
137 //construct and display
138 //this.pack();
139 this.setSize(650, sketchScoreArea.getHeight() + ruler.getHeight());
140 this.setLocation(xPos,yPos);
141 this.show();
142 }
143
144 //--------------
145 // Class Methods
146 //--------------
147
148
149 public SketchScoreArea getSketchScoreArea() {
150 return sketchScoreArea;
151 }
152
153 // Deal with the window closebox
154 public void windowClosing(WindowEvent we) {
155 this.dispose(); //System.exit(0);
156 }
157 //other WindowListener interface methods
158 //They do nothing but are required to be present
159 public void windowActivated(WindowEvent we) {};
160 public void windowClosed(WindowEvent we) {};
161 public void windowDeactivated(WindowEvent we) {};
162 public void windowIconified(WindowEvent we) {};
163 public void windowDeiconified(WindowEvent we) {};
164 public void windowOpened(WindowEvent we) {};
165
166 /**
167 * recalulate and draw the sketch
168 */
169 public void update() {
170 sketchScoreArea.setScore(score);
171 pan.repaint();
172 sketchScoreArea.setSize( (int)Math.round( score.getEndTime()*beatWidth), sketchScoreArea.getHeight());
173 sketchScoreArea.setBeatWidth(beatWidth);
174 sketchScoreArea.repaint();
175 ruler.repaint();
176 //this.repaint();
177 this.setSize(this.getSize().width, sketchScoreArea.getHeight() + ruler.getHeight());
178 this.pack();
179 }
180
181 private void getWidthAndParts() {
182 Enumeration enum = score.getPartList().elements();
183 while(enum.hasMoreElements()){
184 Part part = (Part) enum.nextElement();
185 maxParts++;
186 Enumeration enum2 = part.getPhraseList().elements();
187 while(enum2.hasMoreElements()){
188 Phrase phrase = (Phrase) enum2.nextElement();
189 Enumeration enum3 = phrase.getNoteList().elements();
190 maxWidth = (int) (phrase.getStartTime() * beatWidth);
191 while(enum3.hasMoreElements()){
192 Note aNote = (Note) enum3.nextElement();
193 maxWidth = maxWidth + (int)(aNote.getRhythmValue() * beatWidth);
194 }
195 }
196 }
197 }
198
199 // handle menu items
200 public void actionPerformed(ActionEvent e){
201 if(e.getSource() == play) playScore();
202 if(e.getSource() == speedUp) speedItUp();
203 if(e.getSource() == slowDown) slowItDown();
204 if(e.getSource() == clear) clearNotes();
205 if(e.getSource() == quit) System.exit(0);
206 if(e.getSource() == saveMIDI) saveMidi();
207 if(e.getSource() == openMIDI) openMidi();
208 if(e.getSource() == saveXML) saveXMLFile();
209 if(e.getSource() == openXML) openXMLFile();
210 }
211
212 private void playScore() {
213 MidiSynth ms = new MidiSynth();
214 try {
215 ms.play(score);
216 } catch (Exception e) {
217 System.err.println("MIDI Playback Error:" + e);
218 return;
219 }
220 }
221
222 private void speedItUp() {
223 double tempTempo = score.getTempo() + 10.0;
224 if (tempTempo > 250.0) tempTempo = 250.0;
225 score.setTempo(tempTempo);
226 play.setLabel("Play @ "+tempTempo+" bpm");
227 }
228
229 private void slowItDown() {
230 double tempTempo = score.getTempo() - 10.0;
231 if (tempTempo < 20.0) tempTempo = 20.0;
232 score.setTempo(tempTempo);
233 play.setLabel("Play @ "+tempTempo+" bpm");
234 }
235
236 private void clearNotes() {
237 score.removeAllParts();
238 sketchScoreArea.repaint();
239 }
240
241 /**
242 * Dialog to save phrase as a MIDI file.
243 */
244 public void saveMidi() {
245 FileDialog fd = new FileDialog(this, "Save as a MIDI file...", FileDialog.SAVE);
246 fd.show();
247 //write a MIDI file to disk
248 if ( fd.getFile() != null) {
249 Write.midi(score,fd.getDirectory()+fd.getFile());
250 }
251 }
252
253 /**
254 * Save score as a jMusic XML file.
255 */
256 public void saveXMLFile() {
257 FileDialog fd = new FileDialog(new Frame(),
258 "Save as a jMusic XML file...",
259 FileDialog.SAVE);
260 fd.show();
261 if (fd.getFile() != null) {
262 jm.util.Write.xml(score, fd.getDirectory() + fd.getFile());
263 }
264 }
265
266 /**
267 * Read a MIDI file and display its data.
268 */
269 public void openMidi() {
270 FileDialog fd = new FileDialog(new Frame(),
271 "Select a MIDI file to display.",
272 FileDialog.LOAD);
273 fd.show();
274 String fileName = fd.getFile();
275 if (fileName != null) {
276 Score score = new Score();
277 jm.util.Read.midi(score, fd.getDirectory() + fileName);
278 this.score = score;
279 update();
280 }
281 }
282
283 /**
284 * Read a jMusic XML file and display its data.
285 */
286 public void openXMLFile() {
287 FileDialog fd = new FileDialog(new Frame(),
288 "Select a jMusic XML file to display.",
289 FileDialog.LOAD);
290 fd.show();
291 String fileName = fd.getFile();
292 if (fileName != null) {
293 Score score = new Score();
294 jm.util.Read.xml(score, fd.getDirectory() + fileName);
295 this.score = score;
296 update();
297 }
298 }
299 }