private MooTrackView mtv;
private MooNote note;
+ private JPopupMenu popup;
+ private JMenuItem popupRemove, popupProp, popupTransposeOctUp, popupTransposeOctDown;
private Rectangle pitchRect, veloRect;
+ private String notePitch, noteVelocity;
+ private boolean selected = false;
public Color textColor;
public static final Color bgColor = new Color(160, 218, 255);
public static final Color invBgColor = new Color(96, 38, 0);
- private String notePitch, noteVelocity;
- private JPopupMenu popup;
- private JMenuItem popupRemove, popupProp, popupTransposeOctUp, popupTransposeOctDown;
/**
* Creates a new note element.
* Selects the current NoteElement.
*/
public void select() {
+ selected = true;
mtv.addSelected(this);
setBackground(invBgColor);
textColor = Color.white;
* Deselects the current NoteElement.
*/
public void deselect() {
+ selected = false;
// mtv.removeSelected(this);
setBackground(bgColor);
textColor = Color.black;
noteVelocity = ""+note.getVelocity();
}
+
+ /**
+ * Asks the MooTrackView that the note element is painted on to remove this element and the note.
+ */
+ protected void remove(){
+ mtv.removeNote(this);
+ }
+
/**
* Listener that checks the mouse actions on this element.
*/
class MAdapter extends MouseAdapter {
+ /**
+ * If left mouse button is clicked, selects the note and plays it.
+ */
public void mouseClicked(MouseEvent e) {
- select();
- // Play the note
+ if (SwingUtilities.isLeftMouseButton(e) && !e.isControlDown()) {
+ select();
+ // Play the note
+ }
}
/**
} else if (SwingUtilities.isLeftMouseButton(e)) {
note.setPitch(note.getPitch() - 1);
}
+ Moosique.setEdited();
calculateString();
repaint();
} else if (veloRect.contains(e.getPoint())) {
} else if (SwingUtilities.isLeftMouseButton(e)) {
note.setVelocity(note.getVelocity() - 1);
}
+ Moosique.setEdited();
calculateString();
repaint();
}
* Shows the menu if an OS-specific popup-trigger was activated.
*/
private void maybeShowPopup(MouseEvent e) {
- if (e.isPopupTrigger() && !e.isControlDown()) popup.show(e.getComponent(), e.getX(), e.getY());
+ if (e.isPopupTrigger() && !e.isControlDown()) {
+ if (!selected || mtv.isTheOnlySelected((MooNoteElement)e.getComponent())) popup.show(e.getComponent(), e.getX(), e.getY());
+ else mtv.showSelectionPopup(e.getComponent(), e.getX(), e.getY());
+ }
}
}
repaint();
}
}
-
- /**
- * Asks the MooTrackView that the note element is painted on to remove this element and the note.
- */
- protected void remove(){
- mtv.removeNote(this);
- }
}
private static Sequence seq;
private static Sequencer sequencer;
private static Synthesizer synthesizer;
+ private static Receiver receiver;
private static MidiChannel[] channels;
private static MidiChannel activeChannel;
private static MidiEvent[] timeSignatures, tempoChanges;
/**
* Starts the application.
+ *
+ * Parses command-line arguments, acquires MIDI devices and connects them,
+ * loads a sequence and creates the GUI.
*/
public static void main (String[] args) {
System.out.println("\nMoosique version 1.0\n");
synthesizer = MidiSystem.getSynthesizer();
System.out.print(".");
synthesizer.open();
- sequencer.getTransmitter().setReceiver(synthesizer.getReceiver());
+ receiver = synthesizer.getReceiver();
+ sequencer.getTransmitter().setReceiver(receiver);
channels = synthesizer.getChannels();
setActiveChannel(0);
} catch (MidiUnavailableException e) {
System.out.println("Failed, quitting.");
+ // System.exit(1);
}
System.out.println("Done");
}
}
+
+
+
+
+
+
+
+ /* ***
+ ** ACCESSOR METHODS **
+ *** */
+
+
+
+
+
+
+
+
+ /**
+ * Returns the currently active MidiChannel.
+ * @return the active MidiChannel
+ */
+ public static MidiChannel getActiveChannel() {
+ return activeChannel;
+ }
+
+ /**
+ * Returns the MidiChannels of the selected synthesizer.
+ * @return the available MidiChannels
+ */
+ public static MidiChannel getChannel(int i) {
+ return channels[i];
+ }
+
+ /**
+ * Returns the MidiChannels of the selected synthesizer.
+ * @return the available MidiChannels
+ */
+ public static MidiChannel[] getChannels() {
+ return channels;
+ }
+
+ /**
+ * Returns the current editing position of the sequencer.
+ * @return the tick position
+ */
+ public static long getEditPosition() {
+ return editPosition;
+ }
+
/**
* Returns the GUI.
* @return the GUI
return gui;
}
+ /**
+ * Returns the receiver of the current sequencer.
+ * @return the receiver
+ */
+ public static Receiver getReceiver() {
+ return receiver;
+ }
+
/**
* Returns the current sequence.
* @return the current sequence
}
/**
- * Returns the MidiChannels of the selected synthesizer.
- * @return the available MidiChannels
+ * Returns the tempo of the current sequence.
+ * @return the tick position
*/
- public static MidiChannel[] getChannels() {
- return channels;
+ public static int getTempo() {
+ return 120;
+ // if (tempoMsg == null) return 0;
}
/**
- * Returns the MidiChannels of the selected synthesizer.
- * @return the available MidiChannels
+ * Returns the tempo of the current sequence.
+ * @return the tick position
*/
- public static MidiChannel getChannel(int i) {
- return channels[i];
+ public static int[] getTimeSig() {
+ int[] ts = {4, 4};
+ return ts;
+ // if (timeSigMsg == null) return 0;
}
/**
- * Returns the currently active MidiChannel.
- * @return the active MidiChannel
+ * Returns true if the current sequence has been edited.
+ * @return the tick position
*/
- public static MidiChannel getActiveChannel() {
- return activeChannel;
+ public static boolean isEdited() {
+ return isEdited;
+ }
+
+ /**
+ * Returns whether the given track should be drawn
+ * @return true if the given track should be drawn
+ */
+ public static boolean shouldBeDrawn(Track track) {
+ if (drawEmptyTracks) return true;
+ else return (!emptyTracks.contains(track));
+ }
+
+
+
+
+
+
+
+
+ /* ***
+ ** MUTATOR METHODS **
+ *** */
+
+
+
+
+
+
+
+
+ /**
+ * Fast forwards the current sequence the given number of measures.
+ * @param measures the number of measures to fast forward
+ */
+ public static void forward(long ticks) {
+ editPosition += ticks;
+ }
+
+ /**
+ * Rewinds the current sequence the given number of measures.
+ * @param measures the number of measures to rewind
+ */
+ public static void rewind(long ticks) {
+ editPosition -= ticks;
}
/**
}
/**
- * Replaces the current sequence with a new one, holding three empty tracks.
+ * Sets whether empty tracks should be drawn
+ * @param state true if empty tracks should be drawn
*/
- public static void clearSequence() {
- // Creates a new sequence and sends it to the sequencer.
- try {
- seq = new Sequence(Sequence.PPQ, DEFAULT_RESOLUTION, DEFAULT_TRACKS);
- sequencer.setSequence(seq);
- filename = null;
- emptyTracks = new ArrayList();
- } catch (InvalidMidiDataException e) {}
- // Sends sequence to GUI.
- if (gui != null) gui.setSequence(seq);
+ public static void setDrawEmptyTracks(boolean state) {
+ drawEmptyTracks = state;
}
/**
- * Starts playback of the current sequence.
+ * Sets the current sequence as edited, which implies prompts when loading a new sequence.
*/
- public static void play() {
- sequencer.setTickPosition(editPosition);
- resume();
+ public static void setEdited() {
+ isEdited = true;
}
/**
- * Pauses playback of the current sequence.
+ * Sets the current editing position of the sequencer.
+ * @param ticks the tick position
*/
- public static void pause() {
- if (sequencer.isRunning()) {
- sequencer.stop();
- }
- if (player != null) player.interrupt();
+ public static void setEditPosition(long ticks) {
+ editPosition = ticks;
+ }
+
+ /**
+ * Sets the current editing position of the sequencer.
+ * @param ticks the tick position
+ */
+ public static void setTempo(int bpm) {
+ // tempoMsg
+ }
+
+ /**
+ * Sets the current editing position of the sequencer.
+ * @param ticks the tick position
+ */
+ public static void setTimeSig(int bpm) {
+ // timeSigMsg
+ }
+
+
+
+
+
+
+
+
+ /* ***
+ ** PLAYBACK METHODS **
+ *** */
+
+
+
+
+
+
+
+
+ /**
+ * Starts playback of the current sequence.
+ */
+ public static void play() {
+ sequencer.setTickPosition(editPosition);
+ resume();
}
/**
player.start();
}
+ /**
+ * Pauses playback of the current sequence.
+ */
+ public static void pause() {
+ if (sequencer.isRunning()) {
+ sequencer.stop();
+ }
+ if (player != null) player.interrupt();
+ }
+
/**
* Stops playback of the current sequence.
*/
gui.update((long)0);
}
- /**
- * Returns the current editing position of the sequencer.
- * @return the tick position
- */
- public static long getEditPosition() {
- return editPosition;
- }
- /**
- * Sets the current editing position of the sequencer.
- * @param ticks the tick position
- */
- public static void setEditPosition(long ticks) {
- editPosition = ticks;
- }
- /**
- * Returns the tempo of the current sequence.
- * @return the tick position
- */
- public static int getTempo() {
- return 120;
- // if (tempoMsg == null) return 0;
- }
- /**
- * Sets the current editing position of the sequencer.
- * @param ticks the tick position
- */
- public static void setTempo(int bpm) {
- // tempoMsg
- }
- /**
- * Returns the tempo of the current sequence.
- * @return the tick position
- */
- public static int[] getTimeSig() {
- int[] ts = {4, 4};
- return ts;
- // if (timeSigMsg == null) return 0;
- }
- /**
- * Sets the current editing position of the sequencer.
- * @param ticks the tick position
- */
- public static void setTimeSig(int bpm) {
- // timeSigMsg
- }
- /**
- * Returns true if the current sequence has been edited.
- * @return the tick position
- */
- public static boolean isEdited() {
- return isEdited;
- }
- /**
- * Sets the current sequence as edited, which implies prompts when loading a new sequence.
- */
- public static void setEdited() {
- isEdited = true;
- }
+ /* ***
+ ** SYSTEM & IO METHODS **
+ *** */
+
+
+
- /**
- * Rewinds the current sequence the given number of measures.
- * @param measures the number of measures to rewind
- */
- public static void rewind(long ticks) {
- editPosition -= ticks;
- }
- /**
- * Fast forwards the current sequence the given number of measures.
- * @param measures the number of measures to fast forward
- */
- public static void forward(long ticks) {
- editPosition += ticks;
- }
- /**
- * Returns whether the given track should be drawn
- * @return true if the given track should be drawn
- */
- public static boolean shouldBeDrawn(Track track) {
- if (drawEmptyTracks) return true;
- else return (!emptyTracks.contains(track));
- }
/**
- * Sets whether empty tracks should be drawn
- * @param state true if empty tracks should be drawn
+ * Replaces the current sequence with a new one, holding three empty tracks.
*/
- public static void setDrawEmptyTracks(boolean state) {
- drawEmptyTracks = state;
+ public static void clearSequence() {
+ // Creates a new sequence and sends it to the sequencer.
+ try {
+ seq = new Sequence(Sequence.PPQ, DEFAULT_RESOLUTION, DEFAULT_TRACKS);
+ sequencer.setSequence(seq);
+ filename = null;
+ emptyTracks = new ArrayList();
+ } catch (InvalidMidiDataException e) {}
+ // Sends sequence to GUI.
+ if (gui != null) gui.setSequence(seq);
}
/**
- * Loads the MooSequence in the given file.
+ * Loads a MIDI sequence from the given file.
* @param filename the filename to use
*/
public static boolean load(String file) {
}
}
}
-// timeSignatures = ts.toArray(timeSignatures);
-// tempoChanges = tc.toArray(tempoChanges);
+ // timeSignatures = ts.toArray(timeSignatures);
+ // tempoChanges = tc.toArray(tempoChanges);
// Wraps each NoteOn event with its NoteOff event in a MooNote
ArrayList noteOns, noteOffs;
return true;
}
+ /**
+ * Saves the current sequence to the previously given filename.
+ */
+ public static boolean save() {
+ if (filename == null) return false;
+ else {
+ saveAs(filename);
+ return true;
+ }
+ }
+
/**
* Saves the current sequence to the given filename
* @param file the filename to use
}
}
- /**
- * Saves the current sequence to the previously given filename.
- */
- public static boolean save() {
- if (filename == null) return false;
- else {
- saveAs(filename);
- return true;
- }
- }
-
/**
* Releases all reserved devices and exits the program.
*/
public static void quit() {
+ if (isEdited && gui != null) {
+ int exitOption = JOptionPane.showConfirmDialog(gui,
+ "The current sequence has been edited, but not saved.\nDo you wish to quit anyway?",
+ "File not saved - really quit?",
+ JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.WARNING_MESSAGE);
+ if (exitOption == JOptionPane.CANCEL_OPTION || exitOption == JOptionPane.CLOSED_OPTION) return;
+ }
if (sequencer.isOpen()) sequencer.close();
if (synthesizer.isOpen()) synthesizer.close();
System.exit(0);
Arbetskatalog
Fem senast öppnade filerna
Valda MIDI-enheter
-
-x Integrera MooViewCounter i MooTrackView genom att istället variera de horisontella streckens gråa nyanser?!?
- (Omöjligt att följa strecken till högra änden av skärmen.)
-
-x Ändra längden på MooNoteElement (JPanel).
- Känn av klick på panelens gräns, MouseMotionListener känner av när ny ruta nås.
- void mouseDragged(MouseEvent)
- Called in response to the user moving the mouse while holding a mouse button down.
- This event is fired by the component that fired the most recent mouse-pressed event,
- even if the cursor is no longer over that component.
-
x Fixa InstrumentList.
x Fixa så att toolbarens rutor sitter fast!
x Räkna ut tempo och taktart. Skicka (på nåt sätt) tempovektorn till MooToolbar.
x Gör en ruta för tempot i MooToolbar.
x Gör en ruta för taktarten i MooViews övre vänstra hörn.
-x Implementera klart menyn, med alla dialoger.
+x Implementera klart menyn, med alla dialoger. (Går visst att göra med JOptionPane, kolla denna:
+ http://java.sun.com/tutorial/uiswing/components/example-swing/CustomDialog.java)
x Lägg till en tom panel i MooGUI för att fylla ut skärmen. Använd setBounds()
+x Textfält som gör att man bara kan skriva in siffror? (MooNoteProp)
+
+MooTrackView
+
x Fixa markera, kopiera, klipp ut och klistra in.
x Highlighta noter som spelas? (Enligt kravspec.)
-x Textfält som gör att man bara kan skriva in siffror? (MooNoteProp)
+x Ändra längden på MooNoteElement (JPanel).
+ Känn av klick på panelens gräns, MouseMotionListener känner av när ny ruta nås.
+ void mouseDragged(MouseEvent)
+ Called in response to the user moving the mouse while holding a mouse button down.
+ This event is fired by the component that fired the most recent mouse-pressed event,
+ even if the cursor is no longer over that component.
+ Eller.. ComponentListener.componentMoved(ComponentEvent e)
+
+x Integrera MooViewCounter i MooTrackView genom att istället variera de horisontella streckens gråa nyanser?!?
+ (Omöjligt att följa strecken till högra änden av skärmen.)
\f
\ No newline at end of file