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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 iliev 1286 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1746 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 1286 *
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 iliev 1767 import java.awt.Dimension;
26    
27     import java.beans.PropertyChangeEvent;
28     import java.beans.PropertyChangeListener;
29    
30 iliev 1286 import java.awt.event.ActionEvent;
31     import java.awt.event.ActionListener;
32 iliev 1746 import java.awt.event.KeyEvent;
33 iliev 1286 import java.awt.event.MouseAdapter;
34     import java.awt.event.MouseEvent;
35    
36 iliev 1767 import java.util.Vector;
37    
38 iliev 1746 import javax.swing.AbstractAction;
39     import javax.swing.Action;
40 iliev 1767 import javax.swing.Box;
41     import javax.swing.BoxLayout;
42 iliev 1746 import javax.swing.JComponent;
43 iliev 1767 import javax.swing.JLabel;
44     import javax.swing.JMenu;
45 iliev 1286 import javax.swing.JMenuItem;
46 iliev 1767 import javax.swing.JPanel;
47 iliev 1286 import javax.swing.JPopupMenu;
48 iliev 1767 import javax.swing.JScrollPane;
49     import javax.swing.JTable;
50 iliev 1286 import javax.swing.JTree;
51 iliev 1746 import javax.swing.KeyStroke;
52 iliev 1286
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 iliev 1767 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 iliev 1286 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 iliev 1767 private final ContextMenu contextMenu;
87 iliev 1286
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 iliev 1767 contextMenu = new ContextMenu();
115 iliev 1286 addMouseListener(contextMenu);
116 iliev 1746
117 iliev 1767 addTreeSelectionListener(getHandler());
118    
119 iliev 1746 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 iliev 1767
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 iliev 1286 }
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 iliev 1767 findBankPosition(bank.getId())
211 iliev 1286 );
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 iliev 1767 throw new IllegalArgumentException("Missing MIDI bank: " + bank.getId());
233 iliev 1286
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 iliev 1767 * 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 iliev 1286 * 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 iliev 1767 if(bank.getId() > bankID) return i;
317 iliev 1286 }
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 iliev 1767 private int id;
372 iliev 1286
373     MidiBank(int id) {
374     this.id = id;
375     }
376    
377     public int
378 iliev 1767 getId() { return id; }
379 iliev 1286
380     public boolean
381     equals(Object obj) {
382     if(obj == null) return false;
383     if(!(obj instanceof MidiBank)) return false;
384 iliev 1767 if(getId() == ((MidiBank)obj).getId()) return true;
385 iliev 1286 return false;
386     }
387    
388     public String
389 iliev 1767 toString() {
390     int i = CC.getViewConfig().getFirstMidiBankNumber();
391     return i18n.getLabel("JSMidiInstrumentTree.MidiBank.name", i + id);
392     }
393 iliev 1286 }
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 iliev 1767 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 iliev 1286 private final EventHandler eventHandler = new EventHandler();
621    
622     private EventHandler
623     getHandler() { return eventHandler; }
624    
625 iliev 1767 private class EventHandler implements MidiInstrumentListener, MidiInstrumentMapListener,
626     TreeSelectionListener {
627 iliev 1286
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 iliev 1767
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 iliev 1286 }
663    
664 iliev 1767 class ContextMenu extends MouseAdapter {
665     private final JPopupMenu bankMenu = new JPopupMenu();
666 iliev 1286
667 iliev 1767 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 iliev 1286 ContextMenu() {
689 iliev 1767 JMenuItem mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
690     bankMenu.add(mi);
691     mi.addActionListener(new ActionListener() {
692 iliev 1286 public void
693     actionPerformed(ActionEvent e) {
694 iliev 1767 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 iliev 1286 editSelectedInstrument();
726     }
727     });
728    
729 iliev 1767 instrumentMenu.addSeparator();
730    
731     mi = new JMenuItem(i18n.getMenuLabel("JSMidiInstrumentTree.ContextMenu.moveTo"));
732     instrumentMenu.add(mi);
733 iliev 1286 mi.addActionListener(new ActionListener() {
734     public void
735     actionPerformed(ActionEvent e) {
736 iliev 1767 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 iliev 1286 removeSelectedInstrumentOrBank();
795     }
796     });
797    
798     }
799    
800 iliev 1767 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 iliev 1286 public void
837     mousePressed(MouseEvent e) {
838     if(e.isPopupTrigger()) show(e);
839     }
840 iliev 1767
841 iliev 1286 public void
842     mouseReleased(MouseEvent e) {
843     if(e.isPopupTrigger()) show(e);
844     }
845 iliev 1767
846 iliev 1286 void
847     show(MouseEvent e) {
848 iliev 1329 if(getSelectionCount() == 0) return;
849 iliev 1767
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 iliev 1286 }
856    
857 iliev 1767 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 iliev 1286 }
877     }
878     }
879 iliev 1767
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