/[svn]/jsampler/trunk/src/org/jsampler/view/classic/MidiInstrumentTree.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/view/classic/MidiInstrumentTree.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1144 - (show annotations) (download)
Mon Apr 2 21:39:15 2007 UTC (17 years ago) by iliev
File size: 10927 byte(s)
- upgrading to version 0.4a

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2006 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.classic;
24
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27
28 import javax.swing.JTree;
29
30 import javax.swing.tree.DefaultMutableTreeNode;
31 import javax.swing.tree.DefaultTreeCellRenderer;
32 import javax.swing.tree.DefaultTreeModel;
33 import javax.swing.tree.TreeSelectionModel;
34
35 import org.jsampler.CC;
36 import org.jsampler.HF;
37 import org.jsampler.MidiInstrument;
38 import org.jsampler.MidiInstrumentMap;
39
40 import org.jsampler.event.MidiInstrumentEvent;
41 import org.jsampler.event.MidiInstrumentListener;
42 import org.jsampler.event.MidiInstrumentMapEvent;
43 import org.jsampler.event.MidiInstrumentMapListener;
44
45 import org.linuxsampler.lscp.MidiInstrumentInfo;
46 import org.linuxsampler.lscp.MidiInstrumentMapInfo;
47
48 import static org.jsampler.view.classic.ClassicI18n.i18n;
49
50
51 /**
52 *
53 * @author Grigor Iliev
54 */
55 public class MidiInstrumentTree extends JTree {
56 private DefaultTreeModel model;
57 private MidiInstrumentMap midiInstrumentMap;
58
59 /** Creates a new instance of <code>MidiInstrumentTree</code> */
60 public
61 MidiInstrumentTree() {
62 setRootVisible(false);
63 setShowsRootHandles(true);
64 setEditable(false);
65
66 DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
67 renderer.setClosedIcon(Res.iconFolder16);
68 renderer.setOpenIcon(Res.iconFolderOpen16);
69 renderer.setLeafIcon(Res.iconInstrument16);
70
71 setCellRenderer(renderer);
72
73 addMouseListener(new MouseAdapter() {
74 public void
75 mousePressed(MouseEvent e) {
76 if(e.getButton() != e.BUTTON3) return;
77 setSelectionPath(getClosestPathForLocation(e.getX(), e.getY()));
78 }
79 });
80
81 setMidiInstrumentMap(null);
82
83 getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
84 }
85
86 /**
87 * Gets the MIDI instrument map that is represented by this MIDI instrument tree.
88 * @return The MIDI instrument map that is represented by this MIDI instrument tree.
89 */
90 public MidiInstrumentMap
91 getMidiInstrumentMap() { return midiInstrumentMap; }
92
93 /**
94 * Sets the MIDI instrument map to be represented by this MIDI instrument tree.
95 * @param map The MIDI instrument map to be represented by this MIDI instrument tree.
96 */
97 public void
98 setMidiInstrumentMap(MidiInstrumentMap map) {
99 if(getMidiInstrumentMap() != null) {
100 for(MidiInstrument instr : getMidiInstrumentMap().getAllMidiInstruments()) {
101 instr.removeMidiInstrumentListener(getHandler());
102 }
103
104 getMidiInstrumentMap().removeMidiInstrumentMapListener(getHandler());
105 }
106
107 midiInstrumentMap = map;
108
109 DefaultMutableTreeNode root = new DefaultMutableTreeNode() {
110 public boolean
111 isLeaf() { return false; }
112
113 public Object
114 getUserObject() { return "/"; }
115 };
116
117 model = new DefaultTreeModel(root);
118
119 if(map != null) {
120 for(MidiInstrument instr : map.getAllMidiInstruments()) {
121 mapInstrument(instr);
122 instr.addMidiInstrumentListener(getHandler());
123 }
124
125 map.addMidiInstrumentMapListener(getHandler());
126 }
127
128 setEnabled(map != null);
129
130 setModel(model);
131 }
132
133 /**
134 * Adds the specified MIDI instrument to this tree.
135 * @param instr The MIDI instrument to add.
136 */
137 public void
138 mapInstrument(MidiInstrument instr) {
139 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
140 DefaultMutableTreeNode bankNode = findBank(bank);
141
142 if(bankNode == null) {
143 bankNode = new BankTreeNode(bank);
144
145 model.insertNodeInto (
146 bankNode,
147 (DefaultMutableTreeNode)model.getRoot(),
148 findBankPosition(bank.getID())
149 );
150 }
151
152 model.insertNodeInto (
153 new InstrTreeNode(instr),
154 bankNode,
155 removeProgram(bankNode, instr.getInfo().getMidiProgram())
156 );
157 }
158
159 /**
160 * Removes the specified MIDI instrument from the tree.
161 * @param instr The MIDI instrument to remove.
162 * @throws IllegalArgumentException If the specified instrument is not found.
163 */
164 public void
165 unmapInstrument(MidiInstrument instr) {
166 MidiBank bank = new MidiBank(instr.getInfo().getMidiBank());
167 DefaultMutableTreeNode bankNode = findBank(bank);
168
169 if(bankNode == null)
170 throw new IllegalArgumentException("Missing MIDI bank: " + bank.getID());
171
172 removeProgram(bankNode, instr.getInfo().getMidiProgram());
173 if(bankNode.getChildCount() == 0) model.removeNodeFromParent(bankNode);
174 }
175
176 /**
177 * Gets the selected MIDI instrument.
178 * @return The selected MIDI instrument, or
179 * <code>null</code> if there is no MIDI instrument selected.
180 */
181 public MidiInstrument
182 getSelectedInstrument() {
183 if(getSelectionCount() == 0) return null;
184 Object obj = getSelectionPath().getLastPathComponent();
185 if(!(obj instanceof InstrTreeNode)) return null;
186 obj = ((InstrTreeNode)obj).getUserObject();
187 return (MidiInstrument)obj;
188 }
189
190 /**
191 * Removes (on the backend side) the selected MIDI instrument or MIDI bank.
192 */
193 public void
194 removeSelectedInstrumentOrBank() {
195 if(getSelectionCount() == 0) return;
196
197 Object obj = getSelectionPath().getLastPathComponent();
198 if(obj instanceof InstrTreeNode) {
199 obj = ((InstrTreeNode)obj).getUserObject();
200 removeInstrument((MidiInstrument)obj);
201 } else if(obj instanceof BankTreeNode) {
202 BankTreeNode n = (BankTreeNode)obj;
203 int c = n.getChildCount();
204 if(c > 1) {
205 String s;
206 s = i18n.getMessage("MidiInstrumentTree.removeInstruments?", c);
207 if(!HF.showYesNoDialog(CC.getMainFrame(), s)) return;
208 }
209
210 for(int i = c - 1; i >= 0; i--) {
211 obj = ((InstrTreeNode)n.getChildAt(i)).getUserObject();
212 removeInstrument((MidiInstrument)obj);
213 }
214 }
215 }
216
217 /**
218 * Removes (on the backend side) the specified MIDI instrument.
219 */
220 private void
221 removeInstrument(MidiInstrument instr) {
222 MidiInstrumentInfo i = instr.getInfo();
223 CC.getSamplerModel().unmapBackendMidiInstrument (
224 i.getMapId(), i.getMidiBank(), i.getMidiProgram()
225 );
226 }
227
228 /**
229 * Returns the position, where the specified bank should be inserted.
230 */
231 private int
232 findBankPosition(int bankID) {
233 DefaultMutableTreeNode root = (DefaultMutableTreeNode)model.getRoot();
234
235 for(int i = 0; i < root.getChildCount(); i++) {
236 DefaultMutableTreeNode node = (DefaultMutableTreeNode)root.getChildAt(i);
237 MidiBank bank = (MidiBank)node.getUserObject();
238 if(bank.getID() > bankID) return i;
239 }
240
241 return root.getChildCount();
242 }
243
244 /**
245 * If there is already an instrument with MIDI program <code>program</code>,
246 * those instrument is removed from the tree.
247 * @return The position, where the instrument of the specified program should be inserted.
248 */
249 private int
250 removeProgram(DefaultMutableTreeNode bankNode, int program) {
251
252 for(int i = 0; i < bankNode.getChildCount(); i++) {
253 DefaultMutableTreeNode n = (DefaultMutableTreeNode)bankNode.getChildAt(i);
254 MidiInstrument instr = (MidiInstrument)n.getUserObject();
255
256 if(instr.getInfo().getMidiProgram() == program) {
257 model.removeNodeFromParent(n);
258 return i;
259 }
260
261 if(instr.getInfo().getMidiProgram() > program) return i;
262 }
263
264 return bankNode.getChildCount();
265 }
266
267 private DefaultMutableTreeNode
268 findNode(DefaultMutableTreeNode parent, Object obj) {
269 for(int i = 0; i < parent.getChildCount(); i++) {
270 DefaultMutableTreeNode node = (DefaultMutableTreeNode)parent.getChildAt(i);
271 if(node.getUserObject().equals(obj)) return node;
272 }
273
274 return null;
275 }
276
277 private DefaultMutableTreeNode
278 findBank(Object obj) {
279 return findNode((DefaultMutableTreeNode)model.getRoot(), obj);
280 }
281
282 private DefaultMutableTreeNode
283 findInstrument(Object obj) {
284 if(obj == null || !(obj instanceof MidiInstrument)) return null;
285 MidiInstrument i = (MidiInstrument) obj;
286 DefaultMutableTreeNode bank = findBank(new MidiBank(i.getInfo().getMidiBank()));
287 if(bank == null) return null;
288 return findNode(bank, obj);
289 }
290
291
292 private class MidiBank {
293 int id;
294
295 MidiBank(int id) {
296 this.id = id;
297 }
298
299 public int
300 getID() { return id; }
301
302 public boolean
303 equals(Object obj) {
304 if(obj == null) return false;
305 if(!(obj instanceof MidiBank)) return false;
306 if(getID() == ((MidiBank)obj).getID()) return true;
307 return false;
308 }
309
310 public String
311 toString() { return i18n.getLabel("MidiInstrumentTree.MidiBank.name", id); }
312 }
313
314 protected class BankTreeNode extends DefaultMutableTreeNode {
315 BankTreeNode(Object obj) {
316 super(obj);
317 }
318
319 public void
320 setUserObject(Object userObject) {
321 if(userObject instanceof MidiBank) {
322 super.setUserObject(userObject);
323 return;
324 }
325
326 // If we are here, this means that tree editing occurs.
327 CC.getLogger().info("MidiInstrumentTree: editing not supported");
328 }
329
330 public boolean
331 isLeaf() { return false; }
332 }
333
334 protected class InstrTreeNode extends DefaultMutableTreeNode {
335 InstrTreeNode(Object obj) {
336 super(obj);
337 }
338
339 public void
340 setUserObject(Object userObject) {
341 if(userObject instanceof MidiInstrument) {
342 super.setUserObject(userObject);
343 return;
344 }
345
346 // If we are here, this means that tree editing occurs.
347 CC.getLogger().info("MidiInstrumentTree: editing not supported");
348 }
349
350 public boolean
351 isLeaf() { return true; }
352 }
353
354 private final EventHandler eventHandler = new EventHandler();
355
356 private EventHandler
357 getHandler() { return eventHandler; }
358
359 private class EventHandler implements MidiInstrumentListener, MidiInstrumentMapListener {
360
361 /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
362 public void
363 instrumentInfoChanged(MidiInstrumentEvent e) {
364 DefaultMutableTreeNode n = findInstrument(e.getSource());
365 if(n != null) model.nodeChanged(n);
366 }
367
368 /** Invoked when the name of MIDI instrument map is changed. */
369 public void nameChanged(MidiInstrumentMapEvent e) { }
370
371 /** Invoked when an instrument is added to a MIDI instrument map. */
372 public void
373 instrumentAdded(MidiInstrumentMapEvent e) {
374 e.getInstrument().addMidiInstrumentListener(getHandler());
375 mapInstrument(e.getInstrument());
376
377 }
378
379 /** Invoked when an instrument is removed from a MIDI instrument map. */
380 public void
381 instrumentRemoved(MidiInstrumentMapEvent e) {
382 unmapInstrument(e.getInstrument());
383 e.getInstrument().removeMidiInstrumentListener(getHandler());
384 }
385 }
386 }

  ViewVC Help
Powered by ViewVC