3 import java.awt.event.*;
6 * Graphical representation of a MIDI note.
8 * @author Andersson, Andreen, Lanneskog, Pehrson
12 public class MooNoteElement extends JPanel implements Comparable{
14 private MooTrackView mtv;
16 private JPopupMenu popup;
17 private JMenuItem popupRemove, popupProp, popupTranspOctUp, popupTranspOctDown;
18 private Rectangle pitchRect, veloRect;
19 private String notePitch, noteVelocity;
20 private boolean selected = false, leftMouseButtonPressed = false, mouseIn = false;
21 public Color textColor;
22 public static final Color bgColor = new Color(160, 218, 255);
23 public static final Color invBgColor = new Color(96, 38, 0);
26 * Creates a new note element.
27 * @param parent The MooTrackView that this element will be painted on.
28 * @param mn the note that will be graphically represented
30 public MooNoteElement (MooTrackView parent, MooNote mn) {
34 addMouseListener(new MAdapter());
35 setBorder(BorderFactory.createLineBorder(Color.black));
36 setBackground(bgColor);
37 textColor = Color.black;
39 // Defines coordinates.
40 pitchRect = new Rectangle(0, 0, 15, 10);
41 veloRect = new Rectangle(20, 0, 40, 10);
43 // Creates pop-up menu.
44 popup = new JPopupMenu();
45 PopupListener pList = new PopupListener();
46 popupProp = new JMenuItem("Preferences...");
47 popupProp.addActionListener(pList);
49 popupRemove = new JMenuItem("Remove");
50 popupRemove.addActionListener(pList);
51 popup.add(popupRemove);
52 popupTranspOctUp = new JMenuItem("Transpose one octave up");
53 popupTranspOctUp.addActionListener(pList);
54 popup.add(popupTranspOctUp);
55 popupTranspOctDown = new JMenuItem("Transpose one octave down");
56 popupTranspOctDown.addActionListener(pList);
57 popup.add(popupTranspOctDown);
61 * Returns the note of this element.
64 public MooNote getNote() {
69 * Compares the note of this element to that of another note.
70 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object
72 public int compareTo(Object o) {
73 return note.compareTo(((MooNoteElement)o).getNote());
77 * Selects the current NoteElement.
79 public void select() {
82 setBackground(invBgColor);
83 textColor = Color.white;
88 * Deselects the current NoteElement.
90 public void deselect() {
92 // mtv.deselectNote(this);
93 setBackground(bgColor);
94 textColor = Color.black;
99 * Transposes the current note element the given number of halftones.
100 * @param halftones the number of halftones to transpose - positive for up, negative for down
102 public void transpose(int halftones) {
103 note.transpose(halftones);
108 * Draws the string that shows the note's properties.
109 * @param g The Graphics object used to draw the strings.
111 public void paintComponent(Graphics g)
113 super.paintComponent(g);
114 if (!(g instanceof Graphics2D)) return;
115 Graphics2D g2 = (Graphics2D)g;
116 g2.setColor(textColor);
117 g2.setFont(new Font("Helvetica", Font.PLAIN, 8));
126 g2.drawString(notePitch, 1, 8);
127 g2.drawString("" + noteVelocity, 21, 8);
131 * Calculate what the string that shows the note properties should look like.
133 protected void calculateString(){
137 if(note == null) return;
139 int pitch = note.getPitch();
140 switch (pitch % 12) {
141 case 0: notePitch = "C"; break;
142 case 1: notePitch = "C#"; break;
143 case 2: notePitch = "D"; break;
144 case 3: notePitch = "D#"; break;
145 case 4: notePitch = "E"; break;
146 case 5: notePitch = "F"; break;
147 case 6: notePitch = "F#"; break;
148 case 7: notePitch = "G"; break;
149 case 8: notePitch = "G#"; break;
150 case 9: notePitch = "A"; break;
151 case 10: notePitch = "A#"; break;
152 case 11: notePitch = "B"; break;
154 notePitch += pitch / 12 - 1;
155 noteVelocity = ""+note.getVelocity();
160 * Asks the MooTrackView that the note element is painted on to remove this element and the note.
162 protected void remove(){
163 mtv.removeNote(this);
167 * Updates the graphical content of the element and repaints it.
169 public void update() {
175 * Layout this changed elemnt.
177 protected void newLayout(){
178 mtv.layoutElement(this,true);
182 * Listener that checks the mouse actions on this element.
184 class MAdapter extends MouseAdapter {
187 * Selects the note if mouse entered with the left mouse button pressed.
189 public void mouseEntered(MouseEvent e) {
191 if (mtv.isLeftMouseButtonPressed()) {
197 * Registers mouse exited.
199 public void mouseExited(MouseEvent e) {
204 * Checks if the mouse is pressed.
205 * Increases the pitch or velocity if the right mouse button is pressed while holding CTRL.
206 * Decreases the pitch or velocity if the left mouse button is pressed while holding CTRL.
207 * @param e the event recieved.
209 public void mousePressed(MouseEvent e) {
210 if (e.isControlDown()) {
211 if (pitchRect.contains(e.getPoint())) {
212 if (SwingUtilities.isRightMouseButton(e)) {
214 } else if (SwingUtilities.isLeftMouseButton(e)) {
217 Moosique.setEdited();
220 } else if (veloRect.contains(e.getPoint())) {
221 if (SwingUtilities.isRightMouseButton(e)) {
222 note.setVelocity(note.getVelocity() + 1);
223 } else if (SwingUtilities.isLeftMouseButton(e)) {
224 note.setVelocity(note.getVelocity() - 1);
226 Moosique.setEdited();
237 public void mouseReleased(MouseEvent e) {
238 if (!maybeShowPopup(e) && !mouseIn) {
240 if (y < 0) mtv.maybeMoveSelectedNotes((int)Math.floor((double)y / MooTrackView.NOTE_HEIGHT) * MooTrackView.NOTE_HEIGHT);
241 if (y > getHeight()) mtv.maybeMoveSelectedNotes((int)Math.ceil(((double)y - getHeight()) / MooTrackView.NOTE_HEIGHT) * MooTrackView.NOTE_HEIGHT);
247 * Shows the menu if an OS-specific popup-trigger was activated.
249 private boolean maybeShowPopup(MouseEvent e) {
250 if (!e.isPopupTrigger()) return false;
251 if (!e.isControlDown()) {
252 if (!selected || mtv.isTheOnlySelected((MooNoteElement)e.getComponent())) popup.show(e.getComponent(), e.getX(), e.getY());
253 else mtv.showSelectionPopup(e.getComponent(), e.getX(), e.getY());
260 * Listens on the actions made to the popupmenu.
262 class PopupListener implements ActionListener {
263 public void actionPerformed(ActionEvent e) {
264 Object source = e.getSource();
265 if (source == popupProp) {
266 System.out.println("Duration: " + note.getDuration());
268 System.out.println("Duration: " + note.getDuration());
271 } else if (source == popupRemove) {
273 } else if (source == popupTranspOctUp) {
275 } else if (source == popupTranspOctDown) {