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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2192 - (hide 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 iliev 2192 /*
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