/[svn]/jsampler/trunk/src/org/jsampler/view/std/JSMidiInstrumentTree.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/std/JSMidiInstrumentTree.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1776 - (show annotations) (download)
Thu Sep 11 18:48:36 2008 UTC (15 years, 7 months ago) by iliev
File size: 26811 byte(s)
* Implemented virtual MIDI keyboard

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but 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 JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.std;
24
25 import java.awt.Dimension;
26
27 import java.beans.PropertyChangeEvent;
28 import java.beans.PropertyChangeListener;
29
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.awt.event.KeyEvent;
33 import java.awt.event.MouseAdapter;
34 import java.awt.event.MouseEvent;
35
36 import java.util.Vector;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.Action;
40 import javax.swing.Box;
41 import javax.swing.BoxLayout;
42 import javax.swing.JComponent;
43 import javax.swing.JLabel;
44 import javax.swing.JMenu;
45 import javax.swing.JMenuItem;
46 import javax.swing.JPanel;
47 import javax.swing.JPopupMenu;
48 import javax.swing.JScrollPane;
49 import javax.swing.JTable;
50 import javax.swing.JTree;
51 import javax.swing.KeyStroke;
52
53 import javax.swing.event.TreeSelectionEvent;
54 import javax.swing.event.TreeSelectionListener;
55
56 import javax.swing.tree.DefaultMutableTreeNode;
57 import javax.swing.tree.DefaultTreeModel;
58 import javax.swing.tree.TreeSelectionModel;
59
60 import org.jsampler.CC;
61 import org.jsampler.HF;
62 import org.jsampler.MidiInstrument;
63 import org.jsampler.MidiInstrumentMap;
64
65 import org.jsampler.event.MidiInstrumentEvent;
66 import org.jsampler.event.MidiInstrumentListener;
67 import org.jsampler.event.MidiInstrumentMapEvent;
68 import org.jsampler.event.MidiInstrumentMapListener;
69
70 import org.linuxsampler.lscp.MidiInstrumentInfo;
71
72 import net.sf.juife.OkCancelDialog;
73
74 import static org.jsampler.JSPrefs.FIRST_MIDI_BANK_NUMBER;
75 import static org.jsampler.JSPrefs.FIRST_MIDI_PROGRAM_NUMBER;
76 import static org.jsampler.view.std.StdI18n.i18n;
77
78
79 /**
80 *
81 * @author Grigor Iliev
82 */
83 public class JSMidiInstrumentTree extends JTree {
84 private DefaultTreeModel model;
85 private MidiInstrumentMap midiInstrumentMap;
86 private final ContextMenu contextMenu;
87
88 /**
89 * Creates a new instance of <code>JSMidiInstrumentTree</code>
90 */
91 public
92 JSMidiInstrumentTree() {
93 setRootVisible(false);
94 setShowsRootHandles(true);
95 setEditable(false);
96
97 addMouseListener(new MouseAdapter() {
98 public void
99 mousePressed(MouseEvent e) {
100 if(e.getButton() != e.BUTTON3) return;
101 setSelectionPath(getClosestPathForLocation(e.getX(), e.getY()));
102 }
103
104 public void
105 mouseClicked(MouseEvent e) {
106 if(e.getButton() != e.BUTTON1) return;
107 if(e.getClickCount() > 1) editSelectedInstrument();
108 }
109 });
110
111 setMidiInstrumentMap(null);
112
113 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
114 contextMenu = new ContextMenu();
115 addMouseListener(contextMenu);
116
117 addTreeSelectionListener(getHandler());
118
119 Action a = new AbstractAction() {
120 public void
121 actionPerformed(ActionEvent e) {
122 removeSelectedInstrumentOrBank();
123 }
124 };
125
126 KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
127 getInputMap(JComponent.WHEN_FOCUSED).put(k, "removeSelectedInstrumentOrBank");
128 getActionMap().put("removeSelectedInstrumentOrBank", a);
129
130 String s = FIRST_MIDI_BANK_NUMBER;
131 CC.preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
132 public void
133 propertyChange(PropertyChangeEvent e) {
134 model.reload();
135 }
136 });
137
138 s = FIRST_MIDI_PROGRAM_NUMBER;
139 CC.preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
140 public void
141 propertyChange(PropertyChangeEvent e) {
142 model.reload();
143 contextMenu.updateChangeProgramMenu();
144 }
145 });
146 }
147
148 /**
149 * Gets the MIDI instrument map that is represented by this MIDI instrument tree.
150 * @return The MIDI instrument map that is represented by this MIDI instrument tree.
151 */
152 public MidiInstrumentMap
153 getMidiInstrumentMap() { return midiInstrumentMap; }
154
155 /**
156 * Sets the MIDI instrument map to be represented by this MIDI instrument tree.
157 * @param map The MIDI instrument map to be represented by this MIDI instrument tree.
158 */
159 public void
160 setMidiInstrumentMap(MidiInstrumentMap map) {
161 if(getMidiInstrumentMap() != null) {
162 for(MidiInstrument instr : getMidiInstrumentMap().getAllMidiInstruments()) {
163 instr.removeMidiInstrumentListener(getHandler());
164 }
165
166 getMidiInstrumentMap().removeMidiInstrumentMapListener(getHandler());
167 }
168
169 midiInstrumentMap = map;
170
171 DefaultMutableTreeNode root = new DefaultMutableTreeNode() {
172 public boolean
173 isLeaf() { return false; }
174
175 public Object
176 getUserObject() { return "/"; }
177 };
178
179 model = new DefaultTreeModel(root);
180
181 if(map != null) {
182 for(MidiInstrument instr : map.getAllMidiInstruments()) {
183 mapInstrument(instr);
184 instr.addMidiInstrumentListener(getHandler());
185 }
186
187 map.addMidiInstrumentMapListener(getHandler());
188 }
189
190 setEnabled(map != null);
191
192 setModel(model);
193 }
194
195 /**
196 * Adds the specified MIDI instrument to this tree.
197 * @param instr The MIDI instrument to add.
198 */
199 public void
200 mapInstrument(MidiInstrument instr) {
201 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
202 DefaultMutableTreeNode bankNode = findBank(bank);
203
204 if(bankNode == null) {
205 bankNode = new BankTreeNode(bank);
206
207 model.insertNodeInto (
208 bankNode,
209 (DefaultMutableTreeNode)model.getRoot(),
210 findBankPosition(bank.getId())
211 );
212 }
213
214 model.insertNodeInto (
215 new InstrTreeNode(instr),
216 bankNode,
217 removeProgram(bankNode, instr.getInfo().getMidiProgram())
218 );
219 }
220
221 /**
222 * Removes the specified MIDI instrument from the tree.
223 * @param instr The MIDI instrument to remove.
224 * @throws IllegalArgumentException If the specified instrument is not found.
225 */
226 public void
227 unmapInstrument(MidiInstrument instr) {
228 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
229 DefaultMutableTreeNode bankNode = findBank(bank);
230
231 if(bankNode == null)
232 throw new IllegalArgumentException("Missing MIDI bank: " + bank.getId());
233
234 removeProgram(bankNode, instr.getInfo().getMidiProgram());
235 if(bankNode.getChildCount() == 0) model.removeNodeFromParent(bankNode);
236 }
237
238 /**
239 * Gets the selected MIDI instrument.
240 * @return The selected MIDI instrument, or
241 * <code>null</code> if there is no MIDI instrument selected.
242 */
243 public MidiInstrument
244 getSelectedInstrument() {
245 if(getSelectionCount() == 0) return null;
246 Object obj = getSelectionPath().getLastPathComponent();
247 if(!(obj instanceof InstrTreeNode)) return null;
248 obj = ((InstrTreeNode)obj).getUserObject();
249 return (MidiInstrument)obj;
250 }
251
252 /**
253 * Gets the selected MIDI bank.
254 * @return The selected MIDI bank, or
255 * <code>null</code> if there is no MIDI bank selected.
256 */
257 public MidiBank
258 getSelectedMidiBank() {
259 if(getSelectionCount() == 0) return null;
260
261 Object obj = getSelectionPath().getLastPathComponent();
262 if(!(obj instanceof BankTreeNode)) return null;
263
264 BankTreeNode n = (BankTreeNode)obj;
265 return (MidiBank)n.getUserObject();
266 }
267
268 /**
269 * Removes (on the backend side) the selected MIDI instrument or MIDI bank.
270 */
271 public void
272 removeSelectedInstrumentOrBank() {
273 if(getSelectionCount() == 0) return;
274
275 Object obj = getSelectionPath().getLastPathComponent();
276 if(obj instanceof InstrTreeNode) {
277 obj = ((InstrTreeNode)obj).getUserObject();
278 removeInstrument((MidiInstrument)obj);
279 } else if(obj instanceof BankTreeNode) {
280 BankTreeNode n = (BankTreeNode)obj;
281 int c = n.getChildCount();
282 if(c > 1) {
283 String s;
284 s = i18n.getMessage("JSMidiInstrumentTree.removeInstruments?", c);
285 if(!HF.showYesNoDialog(CC.getMainFrame(), s)) return;
286 }
287
288 for(int i = c - 1; i >= 0; i--) {
289 obj = ((InstrTreeNode)n.getChildAt(i)).getUserObject();
290 removeInstrument((MidiInstrument)obj);
291 }
292 }
293 }
294
295 /**
296 * Removes (on the backend side) the specified MIDI instrument.
297 */
298 private void
299 removeInstrument(MidiInstrument instr) {
300 MidiInstrumentInfo i = instr.getInfo();
301 CC.getSamplerModel().unmapBackendMidiInstrument (
302 i.getMapId(), i.getMidiBank(), i.getMidiProgram()
303 );
304 }
305
306 /**
307 * Returns the position, where the specified bank should be inserted.
308 */
309 private int
310 findBankPosition(int bankID) {
311 DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
312
313 for(int i = 0; i < root.getChildCount(); i++) {
314 DefaultMutableTreeNode node = (DefaultMutableTreeNode)root.getChildAt(i);
315 MidiBank bank = (MidiBank)node.getUserObject();
316 if(bank.getId() > bankID) return i;
317 }
318
319 return root.getChildCount();
320 }
321
322 /**
323 * If there is already an instrument with MIDI program <code>program</code>,
324 * those instrument is removed from the tree.
325 * @return The position, where the instrument of the specified program should be inserted.
326 */
327 private int
328 removeProgram(DefaultMutableTreeNode bankNode, int program) {
329
330 for(int i = 0; i < bankNode.getChildCount(); i++) {
331 DefaultMutableTreeNode n = (DefaultMutableTreeNode)bankNode.getChildAt(i);
332 MidiInstrument instr = (MidiInstrument)n.getUserObject();
333
334 if(instr.getInfo().getMidiProgram() == program) {
335 model.removeNodeFromParent(n);
336 return i;
337 }
338
339 if(instr.getInfo().getMidiProgram() > program) return i;
340 }
341
342 return bankNode.getChildCount();
343 }
344
345 private DefaultMutableTreeNode
346 findNode(DefaultMutableTreeNode parent, Object obj) {
347 for(int i = 0; i < parent.getChildCount(); i++) {
348 DefaultMutableTreeNode node = (DefaultMutableTreeNode)parent.getChildAt(i);
349 if(node.getUserObject().equals(obj)) return node;
350 }
351
352 return null;
353 }
354
355 private DefaultMutableTreeNode
356 findBank(Object obj) {
357 return findNode((DefaultMutableTreeNode)model.getRoot(), obj);
358 }
359
360 private DefaultMutableTreeNode
361 findInstrument(Object obj) {
362 if(obj == null || !(obj instanceof MidiInstrument)) return null;
363 MidiInstrument i = (MidiInstrument) obj;
364 DefaultMutableTreeNode bank = findBank(new MidiBank(i.getInfo().getMidiBank()));
365 if(bank == null) return null;
366 return findNode(bank, obj);
367 }
368
369
370 private class MidiBank {
371 private int id;
372
373 MidiBank(int id) {
374 this.id = id;
375 }
376
377 public int
378 getId() { return id; }
379
380 public boolean
381 equals(Object obj) {
382 if(obj == null) return false;
383 if(!(obj instanceof MidiBank)) return false;
384 if(getId() == ((MidiBank)obj).getId()) return true;
385 return false;
386 }
387
388 public String
389 toString() {
390 int i = CC.getViewConfig().getFirstMidiBankNumber();
391 return i18n.getLabel("JSMidiInstrumentTree.MidiBank.name", i + id);
392 }
393 }
394
395 protected class BankTreeNode extends DefaultMutableTreeNode {
396 BankTreeNode(Object obj) {
397 super(obj);
398 }
399
400 public void
401 setUserObject(Object userObject) {
402 if(userObject instanceof MidiBank) {
403 super.setUserObject(userObject);
404 return;
405 }
406
407 // If we are here, this means that tree editing occurs.
408 CC.getLogger().info("MidiInstrumentTree: editing not supported");
409 }
410
411 public boolean
412 isLeaf() { return false; }
413 }
414
415 protected class InstrTreeNode extends DefaultMutableTreeNode {
416 InstrTreeNode(Object obj) {
417 super(obj);
418 }
419
420 public void
421 setUserObject(Object userObject) {
422 if(userObject instanceof MidiInstrument) {
423 super.setUserObject(userObject);
424 return;
425 }
426
427 // If we are here, this means that tree editing occurs.
428 CC.getLogger().info("MidiInstrumentTree: editing not supported");
429 }
430
431 public boolean
432 isLeaf() { return true; }
433 }
434
435 private void
436 editSelectedInstrument() {
437 MidiInstrument i = getSelectedInstrument();
438 if(i == null) return;
439 JSEditMidiInstrumentDlg dlg = new JSEditMidiInstrumentDlg(i.getInfo());
440 dlg.setVisible(true);
441
442 if(dlg.isCancelled()) return;
443
444 MidiInstrumentInfo info = dlg.getInstrument();
445 CC.getSamplerModel().mapBackendMidiInstrument (
446 info.getMapId(), info.getMidiBank(), info.getMidiProgram(), info
447 );
448 }
449
450 private void
451 copyMidiBankTo() { copyOrMoveMidiBankTo(true); }
452
453 private void
454 moveMidiBankTo() { copyOrMoveMidiBankTo(false); }
455
456 private void
457 copyOrMoveMidiBankTo(boolean copy) {
458 MidiBank bank = getSelectedMidiBank();
459 if(bank == null) return;
460
461 JSMidiBankChooser dlg = new JSMidiBankChooser();
462
463 if(copy) dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.copyTo"));
464 else dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.moveTo"));
465
466 dlg.setSelectedMidiInstrumentMap(getMidiInstrumentMap());
467 dlg.setVisible(true);
468 if(dlg.isCancelled()) return;
469
470 MidiInstrumentMap smap = dlg.getSelectedMidiInstrumentMap();
471
472 if(smap == null) {
473 HF.showErrorMessage(i18n.getMessage("JSMidiInstrumentTree.noMap!"), this);
474 return;
475 }
476
477 if(dlg.getMidiBank() == bank.getId() && smap.getMapId() == getMidiInstrumentMap().getMapId()) {
478 String s = "JSMidiInstrumentTree.sameSourceAndDestination!";
479 HF.showErrorMessage(i18n.getMessage(s), this);
480 return;
481 }
482
483 MidiInstrument[] instrs = getMidiInstrumentMap().getMidiInstruments(bank.getId());
484 int mapId = smap.getMapId();
485 int bnkId = dlg.getMidiBank();
486
487 Vector<MidiInstrument> v = new Vector<MidiInstrument>();
488 for(MidiInstrument i : instrs) {
489 MidiInstrument instr;
490 instr = smap.getMidiInstrument(bnkId, i.getInfo().getMidiProgram());
491 if(instr != null) v.add(instr);
492 }
493
494 if(!v.isEmpty()) {
495 String[] instrumentNames = new String[v.size()];
496 for(int i = 0; i < v.size(); i++) {
497 int base = CC.getViewConfig().getFirstMidiProgramNumber();
498 int p = v.get(i).getInfo().getMidiProgram();
499 instrumentNames[i] = (base + p) + ". " + v.get(i).getName();
500 }
501 JSOverrideInstrumentsConfirmDlg dlg2;
502 dlg2 = new JSOverrideInstrumentsConfirmDlg(instrumentNames);
503 dlg2.setVisible(true);
504 if(dlg2.isCancelled()) return;
505 }
506
507 for(MidiInstrument i : instrs) {
508 int p = i.getInfo().getMidiProgram();
509 CC.getSamplerModel().mapBackendMidiInstrument(mapId, bnkId, p, i.getInfo());
510 }
511
512 if(copy) return;
513
514 mapId = getMidiInstrumentMap().getMapId();
515 bnkId = bank.getId();
516
517 for(MidiInstrument i : instrs) {
518 int p = i.getInfo().getMidiProgram();
519 CC.getSamplerModel().unmapBackendMidiInstrument(mapId, bnkId, p);
520 }
521 }
522
523 private void
524 copyMidiInstrumentTo() { copyOrMoveMidiInstrumentTo(true); }
525
526 private void
527 moveMidiInstrumentTo() { copyOrMoveMidiInstrumentTo(false); }
528
529 private void
530 copyOrMoveMidiInstrumentTo(boolean copy) {
531 MidiInstrument instr = getSelectedInstrument();
532 if(instr == null) return;
533
534 JSMidiBankChooser dlg = new JSMidiBankChooser();
535
536 if(copy) dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.copyTo"));
537 else dlg.setTitle(i18n.getLabel("JSMidiInstrumentTree.moveTo"));
538
539 dlg.setSelectedMidiInstrumentMap(getMidiInstrumentMap());
540 dlg.setVisible(true);
541 if(dlg.isCancelled()) return;
542
543 MidiInstrumentMap smap = dlg.getSelectedMidiInstrumentMap();
544
545 if(smap == null) {
546 HF.showErrorMessage(i18n.getMessage("JSMidiInstrumentTree.noMap!"), this);
547 return;
548 }
549
550 int bank = instr.getInfo().getMidiBank();
551 if(dlg.getMidiBank() == bank && smap.getMapId() == getMidiInstrumentMap().getMapId()) {
552 String s = "JSMidiInstrumentTree.sameSourceAndDestination!";
553 HF.showErrorMessage(i18n.getMessage(s), this);
554 return;
555 }
556
557 int mapId = smap.getMapId();
558 int bnkId = dlg.getMidiBank();
559 int prgId = instr.getInfo().getMidiProgram();
560 MidiInstrument oldInstr = smap.getMidiInstrument(bnkId, prgId);
561
562 if(oldInstr != null) {
563 String[] iS = new String [1];
564 int base = CC.getViewConfig().getFirstMidiProgramNumber();
565 iS[0] = (base + prgId) + ". " + oldInstr.getName();
566 JSOverrideInstrumentsConfirmDlg dlg2;
567 dlg2 = new JSOverrideInstrumentsConfirmDlg(iS);
568 dlg2.setVisible(true);
569 if(dlg2.isCancelled()) return;
570 }
571
572 CC.getSamplerModel().mapBackendMidiInstrument(mapId, bnkId, prgId, instr.getInfo());
573
574 if(copy) return;
575
576 mapId = getMidiInstrumentMap().getMapId();
577
578 CC.getSamplerModel().unmapBackendMidiInstrument(mapId, bank, prgId);
579 }
580
581 private void
582 moveSelectedInstrumentUp() {
583 MidiInstrument instr = getSelectedInstrument();
584 if(instr == null) return;
585 moveSelectedInstrument(instr.getInfo().getMidiProgram() - 1);
586 }
587
588 private void
589 moveSelectedInstrumentDown() {
590 MidiInstrument instr = getSelectedInstrument();
591 if(instr == null) return;
592 moveSelectedInstrument(instr.getInfo().getMidiProgram() + 1);
593 }
594
595 private void
596 moveSelectedInstrument(int newProgram) {
597 if(newProgram < 0 || newProgram > 127) return;
598 MidiInstrument instr = getSelectedInstrument();
599 if(instr == null) return;
600
601 int bnk = instr.getInfo().getMidiBank();
602 int prg = instr.getInfo().getMidiProgram();
603
604 MidiInstrument oldInstr = getMidiInstrumentMap().getMidiInstrument(bnk, newProgram);
605 if(oldInstr != null) {
606 String[] iS = new String [1];
607 int base = CC.getViewConfig().getFirstMidiProgramNumber();
608 iS[0] = (base + prg) + ". " + oldInstr.getName();
609 JSOverrideInstrumentsConfirmDlg dlg;
610 dlg = new JSOverrideInstrumentsConfirmDlg(iS);
611 dlg.setVisible(true);
612 if(dlg.isCancelled()) return;
613 }
614
615 int map = this.getMidiInstrumentMap().getMapId();
616 CC.getSamplerModel().mapBackendMidiInstrument(map, bnk, newProgram, instr.getInfo());
617 CC.getSamplerModel().unmapBackendMidiInstrument(map, bnk, prg);
618 }
619
620 private final EventHandler eventHandler = new EventHandler();
621
622 private EventHandler
623 getHandler() { return eventHandler; }
624
625 private class EventHandler implements MidiInstrumentListener, MidiInstrumentMapListener,
626 TreeSelectionListener {
627
628 /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
629 public void
630 instrumentInfoChanged(MidiInstrumentEvent e) {
631 DefaultMutableTreeNode n = findInstrument(e.getSource());
632 if(n != null) model.nodeChanged(n);
633 }
634
635 /** Invoked when the name of MIDI instrument map is changed. */
636 public void nameChanged(MidiInstrumentMapEvent e) { }
637
638 /** Invoked when an instrument is added to a MIDI instrument map. */
639 public void
640 instrumentAdded(MidiInstrumentMapEvent e) {
641 e.getInstrument().addMidiInstrumentListener(getHandler());
642 mapInstrument(e.getInstrument());
643
644 }
645
646 /** Invoked when an instrument is removed from a MIDI instrument map. */
647 public void
648 instrumentRemoved(MidiInstrumentMapEvent e) {
649 unmapInstrument(e.getInstrument());
650 e.getInstrument().removeMidiInstrumentListener(getHandler());
651 }
652
653 public void
654 valueChanged(TreeSelectionEvent e) {
655 MidiInstrument instr = getSelectedInstrument();
656 if(instr != null) {
657 int p = instr.getInfo().getMidiProgram();
658 contextMenu.miMoveInstrumentDown.setEnabled(p < 127);
659 contextMenu.miMoveInstrumentUp.setEnabled(p > 0);
660 }
661 }
662 }
663
664 class ContextMenu extends MouseAdapter {
665 private final JPopupMenu bankMenu = new JPopupMenu();
666
667 private final JPopupMenu instrumentMenu = new JPopupMenu();
668
669 private final JMenu changeProgramMenu =
670 new JMenu(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.changeProgram"));
671
672 private final JMenuItem miMoveInstrumentUp =
673 new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveUp"));
674
675 private final JMenuItem miMoveInstrumentDown =
676 new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveDown"));
677
678 private final JMenu programGroup1Menu = new JMenu();
679 private final JMenu programGroup2Menu = new JMenu();
680 private final JMenu programGroup3Menu = new JMenu();
681 private final JMenu programGroup4Menu = new JMenu();
682 private final JMenu programGroup5Menu = new JMenu();
683 private final JMenu programGroup6Menu = new JMenu();
684 private final JMenu programGroup7Menu = new JMenu();
685 private final JMenu programGroup8Menu = new JMenu();
686
687
688 ContextMenu() {
689 JMenuItem mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
690 bankMenu.add(mi);
691 mi.addActionListener(new ActionListener() {
692 public void
693 actionPerformed(ActionEvent e) {
694 moveMidiBankTo();
695 }
696 });
697
698 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.copyTo"));
699 bankMenu.add(mi);
700 mi.addActionListener(new ActionListener() {
701 public void
702 actionPerformed(ActionEvent e) {
703 copyMidiBankTo();
704 }
705 });
706
707 bankMenu.addSeparator();
708
709 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.delete"));
710 bankMenu.add(mi);
711 mi.addActionListener(new ActionListener() {
712 public void
713 actionPerformed(ActionEvent e) {
714 removeSelectedInstrumentOrBank();
715 }
716 });
717
718 // MIDI Instrument Menu
719
720 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.edit"));
721 instrumentMenu.add(mi);
722 mi.addActionListener(new ActionListener() {
723 public void
724 actionPerformed(ActionEvent e) {
725 editSelectedInstrument();
726 }
727 });
728
729 instrumentMenu.addSeparator();
730
731 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
732 instrumentMenu.add(mi);
733 mi.addActionListener(new ActionListener() {
734 public void
735 actionPerformed(ActionEvent e) {
736 moveMidiInstrumentTo();
737 }
738 });
739
740 mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.copyTo"));
741 instrumentMenu.add(mi);
742 mi.addActionListener(new ActionListener() {
743 public void
744 actionPerformed(ActionEvent e) {
745 copyMidiInstrumentTo();
746 }
747 });
748
749 instrumentMenu.add(changeProgramMenu);
750
751 changeProgramMenu.add(miMoveInstrumentUp);
752 miMoveInstrumentUp.addActionListener(new ActionListener() {
753 public void
754 actionPerformed(ActionEvent e) {
755 moveSelectedInstrumentUp();
756 }
757 });
758
759 changeProgramMenu.add(miMoveInstrumentDown);
760 miMoveInstrumentDown.addActionListener(new ActionListener() {
761 public void
762 actionPerformed(ActionEvent e) {
763 moveSelectedInstrumentDown();
764 }
765 });
766
767 changeProgramMenu.addSeparator();
768
769 changeProgramMenu.add(programGroup1Menu);
770 addProgramMenuItems(programGroup1Menu, 0, 15);
771 changeProgramMenu.add(programGroup2Menu);
772 addProgramMenuItems(programGroup2Menu, 16, 31);
773 changeProgramMenu.add(programGroup3Menu);
774 addProgramMenuItems(programGroup3Menu, 32, 47);
775 changeProgramMenu.add(programGroup4Menu);
776 addProgramMenuItems(programGroup4Menu, 48, 63);
777 changeProgramMenu.add(programGroup5Menu);
778 addProgramMenuItems(programGroup5Menu, 64, 79);
779 changeProgramMenu.add(programGroup6Menu);
780 addProgramMenuItems(programGroup6Menu, 80, 95);
781 changeProgramMenu.add(programGroup7Menu);
782 addProgramMenuItems(programGroup7Menu, 96, 111);
783 changeProgramMenu.add(programGroup8Menu);
784 addProgramMenuItems(programGroup8Menu, 112, 127);
785
786 instrumentMenu.addSeparator();
787 updateChangeProgramMenu();
788
789 mi = new JMenuItem(i18n.getMenuLabel("ContextMenu.delete"));
790 instrumentMenu.add(mi);
791 mi.addActionListener(new ActionListener() {
792 public void
793 actionPerformed(ActionEvent e) {
794 removeSelectedInstrumentOrBank();
795 }
796 });
797
798 }
799
800 private void
801 addProgramMenuItems(JMenu menu, int prgStart, int prgEnd) {
802 for(int i = prgStart; i <= prgEnd; i++) {
803 menu.add(new ProgramMenuItem(i));
804 }
805 }
806
807 private void
808 updateChangeProgramMenu() {
809 updateProgramGroupMenu(programGroup1Menu, 0, 15);
810 updateProgramGroupMenu(programGroup2Menu, 16, 31);
811 updateProgramGroupMenu(programGroup3Menu, 32, 47);
812 updateProgramGroupMenu(programGroup4Menu, 48, 63);
813 updateProgramGroupMenu(programGroup5Menu, 64, 79);
814 updateProgramGroupMenu(programGroup6Menu, 80, 95);
815 updateProgramGroupMenu(programGroup7Menu, 96, 111);
816 updateProgramGroupMenu(programGroup8Menu, 112, 127);
817 }
818
819 private void
820 updateProgramGroupMenu(JMenu menu, int prgStart, int prgEnd) {
821 int base = CC.getViewConfig().getFirstMidiProgramNumber();
822 String s = "JSMidiInstrumentTree.ContextMenu.programGroup";
823 String grp = "(" + (base + prgStart) + "-" + (base + prgEnd) + ")";
824 menu.setText(i18n.getMenuLabel(s, grp));
825
826 updateProgramGroupMenuItems(menu);
827 }
828
829 private void
830 updateProgramGroupMenuItems(JMenu menu) {
831 for(int i = 0; i < menu.getItemCount(); i++) {
832 ((ProgramMenuItem)menu.getItem(i)).updateProgramNumber();
833 }
834 }
835
836 public void
837 mousePressed(MouseEvent e) {
838 if(e.isPopupTrigger()) show(e);
839 }
840
841 public void
842 mouseReleased(MouseEvent e) {
843 if(e.isPopupTrigger()) show(e);
844 }
845
846 void
847 show(MouseEvent e) {
848 if(getSelectionCount() == 0) return;
849
850 if(getSelectedInstrument() != null) {
851 instrumentMenu.show(e.getComponent(), e.getX(), e.getY());
852 } else {
853 bankMenu.show(e.getComponent(), e.getX(), e.getY());
854 }
855 }
856
857 private class ProgramMenuItem extends JMenuItem implements ActionListener {
858 int program;
859
860 ProgramMenuItem(int program) {
861 this.program = program;
862 updateProgramNumber();
863 addActionListener(this);
864 }
865
866 public void
867 updateProgramNumber() {
868 int base = CC.getViewConfig().getFirstMidiProgramNumber();
869 setText(String.valueOf(base + program));
870 }
871
872 public void
873 actionPerformed(ActionEvent e) {
874 moveSelectedInstrument(program);
875 }
876 }
877 }
878 }
879
880 class JSOverrideInstrumentsConfirmDlg extends OkCancelDialog {
881 private final JLabel lMsg = new JLabel(i18n.getMessage("JSOverrideInstrumentsConfirmDlg.lMsg"));
882 private final JTable table;
883
884 JSOverrideInstrumentsConfirmDlg(String[] instrumentNames) {
885 super(CC.getMainFrame());
886
887 JPanel mainPane = new JPanel();
888 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
889
890 lMsg.setIcon(CC.getViewConfig().getBasicIconSet().getWarning32Icon());
891 lMsg.setAlignmentX(LEFT_ALIGNMENT);
892 mainPane.add(lMsg);
893
894 mainPane.add(Box.createRigidArea(new Dimension(0, 12)));
895
896 String[][] instrs = new String[instrumentNames.length][1];
897 for(int i = 0; i < instrumentNames.length; i++) {
898 instrs[i][0] = instrumentNames[i];
899 }
900
901 String[] columns = new String[1];
902 columns[0] = "";
903
904 table = new JTable(instrs, columns);
905 JScrollPane sp = new JScrollPane(table);
906 Dimension d = new Dimension(200, 200);
907 sp.setMinimumSize(d);
908 sp.setPreferredSize(d);
909 sp.setAlignmentX(LEFT_ALIGNMENT);
910 mainPane.add(sp);
911
912 setMainPane(mainPane);
913 setMinimumSize(getPreferredSize());
914 setResizable(true);
915 }
916
917 protected void
918 onOk() {
919 if(!btnOk.isEnabled()) return;
920
921 setVisible(false);
922 setCancelled(false);
923 }
924
925 protected void
926 onCancel() { setVisible(false); }
927 }

  ViewVC Help
Powered by ViewVC