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

Contents of /jsampler/trunk/src/org/jsampler/view/SamplerTreeModel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2192 - (show annotations) (download)
Fri Jun 24 21:34:51 2011 UTC (12 years, 10 months ago) by iliev
File size: 13363 byte(s)
* Initial implementation of Sampler Browser
  (choose Window/Sampler Browser) - another way to view/edit
  the sampler configuration (work in progress - for now only
  support for viewing/editing send effects)

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2011 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 package org.jsampler.view;
23
24 import javax.swing.event.TreeModelEvent;
25 import javax.swing.tree.TreePath;
26 import java.util.ArrayList;
27 import java.util.Enumeration;
28 import java.util.Vector;
29 import javax.swing.event.TreeModelListener;
30 import javax.swing.tree.TreeModel;
31 import javax.swing.tree.TreeNode;
32
33 import org.jsampler.AudioDeviceModel;
34 import org.jsampler.CC;
35 import org.jsampler.EffectChain;
36 import org.jsampler.event.AudioDeviceAdapter;
37 import org.jsampler.event.AudioDeviceEvent;
38 import org.jsampler.event.EffectChainEvent;
39 import org.jsampler.event.EffectChainListener;
40 import org.jsampler.event.ListEvent;
41 import org.jsampler.event.ListListener;
42
43 import org.linuxsampler.lscp.Effect;
44 import org.linuxsampler.lscp.EffectInstance;
45
46 import static org.jsampler.JSI18n.i18n;
47
48 /**
49 *
50 * @author Grigor Iliev
51 */
52 public class SamplerTreeModel implements TreeModel {
53 private final SamplerTreeNode root = new SamplerTreeNode(this);
54 private ArrayList<TreeModelListener> listeners = new ArrayList<TreeModelListener>();
55
56 private final AudioDevicesTreeNode audioDevices;
57 private final InternalEffectsTreeNode internalEffects;
58
59 public
60 SamplerTreeModel() {
61 audioDevices = new AudioDevicesTreeNode(this, root);
62 root.addChild(audioDevices);
63
64 for(AudioDeviceModel a : CC.getSamplerModel().getAudioDevices()) {
65 audioDevices.addChild(new AudioDeviceTreeNode(this, audioDevices, a));
66 a.addAudioDeviceListener(getHandler());
67 }
68
69 CC.getSamplerModel().addAudioDeviceListListener(getHandler());
70
71 internalEffects = new InternalEffectsTreeNode(this, root);
72 root.addChild(internalEffects);
73 for(int i = 0; i < CC.getSamplerModel().getEffects().getEffectCount(); i++) {
74 Effect fx = CC.getSamplerModel().getEffects().getEffect(i);
75 internalEffects.addChild(new InternalEffectTreeNode(internalEffects, fx));
76 }
77 }
78
79 // Tree model methods
80 @Override
81 public void
82 addTreeModelListener(TreeModelListener l) {
83 listeners.add(l);
84 }
85
86 @Override
87 public void
88 removeTreeModelListener(TreeModelListener l) {
89 listeners.remove(l);
90 }
91
92 @Override
93 public Object
94 getChild(Object parent, int index) {
95 return ((TreeNode)parent).getChildAt(index);
96 }
97
98 @Override
99 public int
100 getChildCount(Object parent) {
101 return ((TreeNode)parent).getChildCount();
102 }
103
104 @Override
105 public Object
106 getRoot() { return root; }
107
108 @Override
109 public int
110 getIndexOfChild(Object parent, Object child) {
111 if(parent == null || child == null) return -1;
112 return ((TreeNode)parent).getIndex((TreeNode)child);
113 }
114
115 @Override
116 public boolean
117 isLeaf(Object node) { return ((TreeNode)node).isLeaf(); }
118
119 @Override
120 public void
121 valueForPathChanged(TreePath path, Object newValue) {
122
123 }
124 ///////
125
126 protected Object[]
127 getPathToRoot(TreeNode node) {
128 Vector v = new Vector();
129
130 while(node != null) {
131 v.insertElementAt(node, 0);
132 if(node == getRoot()) break;
133 node = node.getParent();
134 }
135
136 return v.toArray(new Object[v.size()]);
137 }
138
139 private void
140 fireNodeInserted(TreeNode node, int index) {
141 Object[] path = getPathToRoot(node.getParent());
142
143 int[] idxs = { index };
144 Object[] objs = { node };
145 TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
146 for(TreeModelListener l : listeners) {
147 l.treeNodesInserted(e);
148 }
149 }
150
151 private void
152 fireNodeChanged(TreeNode node, int index) {
153 Object[] path = getPathToRoot(node.getParent());
154 int[] idxs = { index };
155 Object[] objs = { node };
156 TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
157 for(TreeModelListener l : listeners) {
158 l.treeNodesChanged(e);
159 }
160 }
161
162 private void
163 fireNodeRemoved(TreeNode parent, TreeNode node, int index) {
164 Object[] path = getPathToRoot(parent);
165 int[] idxs = { index };
166 Object[] objs = { node };
167 TreeModelEvent e = new TreeModelEvent(this, path, idxs, objs);
168 for(int i = listeners.size() - 1; i >=0; i--) {
169 listeners.get(i).treeNodesRemoved(e);
170 }
171 }
172
173 private void
174 fireNodeStructureChanged(TreeNode node) {
175 Object[] path = getPathToRoot(node);
176 Object[] objs = { node };
177 TreeModelEvent e = new TreeModelEvent(this, path);
178 for(TreeModelListener l : listeners) {
179 l.treeStructureChanged(e);
180 }
181 }
182
183
184 private final EventHandler eventHandler = new EventHandler();
185
186 private EventHandler
187 getHandler() { return eventHandler; }
188
189 private class EventHandler extends AudioDeviceAdapter implements ListListener<AudioDeviceModel> {
190
191
192 /** Invoked when a new entry is added to a list. */
193 @Override
194 public void
195 entryAdded(final ListEvent<AudioDeviceModel> e) {
196 e.getEntry().addAudioDeviceListener(getHandler());
197 AudioDeviceTreeNode node =
198 new AudioDeviceTreeNode(SamplerTreeModel.this, audioDevices, e.getEntry());
199 audioDevices.addChild(node);
200 fireNodeInserted(node, audioDevices.getIndex(node));
201 }
202
203 /** Invoked when an entry is removed from a list. */
204 @Override
205 public void
206 entryRemoved(ListEvent<AudioDeviceModel> e) {
207 TreeNode node = audioDevices.getChildById(e.getEntry().getDeviceId());
208 int i = audioDevices.getIndex(node);
209 if(i == -1) return;
210
211 audioDevices.removeChildAt(i);
212 fireNodeRemoved(audioDevices, node, i);
213
214 e.getEntry().removeAudioDeviceListener(getHandler());
215 }
216
217 /** Invoked when a new send effect chain is added to the audio device. */
218 @Override
219 public void
220 sendEffectChainAdded(AudioDeviceEvent e) {
221 AudioDeviceTreeNode node =
222 audioDevices.getChildById(e.getAudioDeviceModel().getDeviceId());
223
224 if(node == null) {
225 CC.getLogger().warning("Missing audio device node. This is a bug!");
226 return;
227 }
228
229 SendEffectChainTreeNode child =
230 new SendEffectChainTreeNode(SamplerTreeModel.this, node, e.getEffectChain());
231 node.addChild(child);
232 fireNodeInserted(child, node.getIndex(child));
233 }
234
235 /** Invoked when when a send effect chain is removed from the audio device. */
236 @Override
237 public void
238 sendEffectChainRemoved(AudioDeviceEvent e) {
239 AudioDeviceTreeNode node =
240 audioDevices.getChildById(e.getAudioDeviceModel().getDeviceId());
241
242 if(node == null) {
243 CC.getLogger().warning("Missing audio device node. This is a bug!");
244 return;
245 }
246
247 SendEffectChainTreeNode child = node.getChildById(e.getEffectChain().getChainId());
248 if(child == null) {
249 CC.getLogger().warning("Missing send effect chain node. This is a bug!");
250 return;
251 }
252
253 int idx = node.getIndex(child);
254 node.removeChildAt(idx);
255 fireNodeRemoved(node, child, idx);
256 }
257 }
258
259 public static class AbstractTreeNode<T extends TreeNode> implements TreeNode {
260 protected final SamplerTreeModel treeModel;
261 private final TreeNode parent;
262 private final Vector<T> children = new Vector<T>();
263
264 public
265 AbstractTreeNode(SamplerTreeModel treeModel) { this(treeModel, null); }
266
267 public
268 AbstractTreeNode(SamplerTreeModel treeModel, TreeNode parent) {
269 this.parent = parent;
270 this.treeModel = treeModel;
271 }
272
273 // Tree node model methods
274 @Override
275 public T
276 getChildAt(int index) { return children.get(index); }
277
278 @Override
279 public int
280 getChildCount() { return children.size(); }
281
282 @Override
283 public TreeNode
284 getParent() { return parent; }
285
286 @Override
287 public int
288 getIndex(TreeNode node) { return children.indexOf(node); }
289
290 @Override
291 public boolean
292 getAllowsChildren() { return true; }
293
294 @Override
295 public boolean
296 isLeaf() { return false; }
297
298 @Override
299 public Enumeration
300 children() { return children.elements(); }
301 ///////
302
303 public void
304 addChild(T child) { children.add(child); }
305
306 public T
307 removeChildAt(int index) { return children.remove(index); }
308
309 public void
310 removeAllChildren() { children.removeAllElements(); }
311 }
312
313 public static class AbstractTreeLeaf<T extends TreeNode> implements TreeNode {
314 private final T parent;
315
316 public
317 AbstractTreeLeaf() { this(null); }
318
319 public
320 AbstractTreeLeaf(T parent) {this.parent = parent; }
321
322 // Tree node model methods
323 @Override
324 public TreeNode
325 getChildAt(int index) { return null; }
326
327 @Override
328 public int
329 getChildCount() { return 0; }
330
331 @Override
332 public T
333 getParent() { return parent; }
334
335 @Override
336 public int
337 getIndex(TreeNode node) { return -1; }
338
339 @Override
340 public boolean
341 getAllowsChildren() { return false; }
342
343 @Override
344 public boolean
345 isLeaf() { return true; }
346
347 @Override
348 public Enumeration
349 children() { return null; }
350 ///////
351 }
352
353 public static class SamplerTreeNode extends AbstractTreeNode {
354 public
355 SamplerTreeNode(SamplerTreeModel treeModel) {
356 super(treeModel);
357 }
358
359 @Override
360 public String
361 toString() { return i18n.getLabel("SamplerTreeNode.toString"); }
362 }
363
364 public static class AudioDevicesTreeNode extends AbstractTreeNode<AudioDeviceTreeNode> {
365 public
366 AudioDevicesTreeNode(SamplerTreeModel treeModel, TreeNode parent) {
367 super(treeModel, parent);
368 }
369
370 public AudioDeviceTreeNode
371 getChildById(int audioDeviceId) {
372 for(int i = 0; i < getChildCount(); i++) {
373 if(getChildAt(i).getAudioDeviceId() == audioDeviceId) return getChildAt(i);
374 }
375
376 return null;
377 }
378
379 @Override
380 public String
381 toString() { return i18n.getLabel("AudioDevicesTreeNode.toString"); }
382 }
383
384 public static class AudioDeviceTreeNode extends AbstractTreeNode<SendEffectChainTreeNode> {
385 private final AudioDeviceModel audioDevice;
386
387 public
388 AudioDeviceTreeNode (
389 SamplerTreeModel treeModel, TreeNode parent, AudioDeviceModel audioDevice
390 ) {
391 super(treeModel, parent);
392 this.audioDevice = audioDevice;
393
394 for(int i = 0; i < audioDevice.getSendEffectChainCount(); i++) {
395 EffectChain chain = audioDevice.getSendEffectChain(i);
396 addChild(new SendEffectChainTreeNode(treeModel, this, chain));
397 }
398 }
399
400 public AudioDeviceModel
401 getAudioDevice() { return audioDevice; }
402
403 public int
404 getAudioDeviceId() { return audioDevice.getDeviceId(); }
405
406 public SendEffectChainTreeNode
407 getChildById(int chainId) {
408 for(int i = 0; i < getChildCount(); i++) {
409 if(getChildAt(i).getChainId() == chainId) return getChildAt(i);
410 }
411
412 return null;
413 }
414
415 @Override
416 public String
417 toString() { return i18n.getLabel("AudioDeviceTreeNode.toString", getAudioDeviceId()); }
418 }
419
420 public static class SendEffectChainTreeNode extends AbstractTreeNode<EffectInstanceTreeNode>
421 implements EffectChainListener {
422 private final EffectChain chain;
423
424 public
425 SendEffectChainTreeNode (
426 SamplerTreeModel treeModel, AudioDeviceTreeNode parent, EffectChain chain
427 ) {
428 super(treeModel, parent);
429 this.chain = chain;
430 chain.addAudioDeviceListener(this);
431 updateEffectInstanceList();
432 }
433 ///////
434
435 public EffectChain
436 getEffectChain() { return chain; }
437
438 public int
439 getChainId() { return chain.getChainId(); }
440
441 /**
442 * Gets the audio device to which the
443 * send effect chain represented by this tree node belongs.
444 */
445 public AudioDeviceModel
446 getAudioDevice() { return ((AudioDeviceTreeNode)getParent()).getAudioDevice(); }
447
448 @Override
449 public String
450 toString() { return i18n.getLabel("SendEffectChainTreeNode.toString", chain.getChainId()); }
451
452 @Override
453 public void
454 effectInstanceListChanged(EffectChainEvent e) {
455 updateEffectInstanceList();
456 treeModel.fireNodeStructureChanged(this);
457 }
458
459 private void
460 updateEffectInstanceList() {
461 removeAllChildren();
462 for(int i = 0; i < chain.getEffectInstanceCount(); i++) {
463 EffectInstance ei = chain.getEffectInstance(i);
464 addChild(new EffectInstanceTreeNode(this, ei));
465 }
466
467
468 }
469 }
470
471 public static class EffectInstanceTreeNode extends AbstractTreeLeaf<SendEffectChainTreeNode> {
472 private final EffectInstance effectInstance;
473
474 public
475 EffectInstanceTreeNode(SendEffectChainTreeNode parent, EffectInstance ei) {
476 super(parent);
477 effectInstance = ei;
478 }
479
480 public int
481 getInstanceId() { return effectInstance.getInstanceId(); }
482
483 @Override
484 public String
485 toString() { return effectInstance.getDescription(); }
486 }
487
488 public static class InternalEffectsTreeNode extends AbstractTreeNode<InternalEffectTreeNode> {
489 public
490 InternalEffectsTreeNode(SamplerTreeModel treeModel, TreeNode parent) {
491 super(treeModel, parent);
492 }
493
494 @Override
495 public String
496 toString() { return i18n.getLabel("InternalEffectsTreeNode.toString"); }
497 }
498
499 public static class InternalEffectTreeNode extends AbstractTreeLeaf {
500 private final Effect effect;
501
502 public
503 InternalEffectTreeNode(TreeNode parent, Effect effect) {
504 super(parent);
505 this.effect = effect;
506 }
507
508 @Override
509 public String
510 toString() { return effect.getDescription(); }
511 }
512
513 }

  ViewVC Help
Powered by ViewVC