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

Annotation of /jsampler/trunk/src/org/jsampler/view/classic/Channel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 842 - (hide annotations) (download)
Thu Mar 16 18:08:34 2006 UTC (18 years, 1 month ago) by iliev
File size: 29499 byte(s)
Updating to version 0.2a

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005 Grigor Kirilov Iliev
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.Color;
26 iliev 842 import java.awt.Cursor;
27 iliev 787 import java.awt.Dimension;
28     import java.awt.GridBagConstraints;
29     import java.awt.GridBagLayout;
30     import java.awt.Insets;
31    
32     import java.awt.event.ActionEvent;
33     import java.awt.event.ActionListener;
34    
35 iliev 842 import java.beans.PropertyChangeEvent;
36     import java.beans.PropertyChangeListener;
37    
38 iliev 787 import java.net.URL;
39    
40 iliev 842 import java.util.Vector;
41    
42 iliev 787 import java.util.logging.Level;
43    
44     import javax.swing.BorderFactory;
45     import javax.swing.Box;
46     import javax.swing.BoxLayout;
47     import javax.swing.ImageIcon;
48     import javax.swing.JButton;
49     import javax.swing.JComboBox;
50     import javax.swing.JLabel;
51     import javax.swing.JPanel;
52     import javax.swing.JSeparator;
53     import javax.swing.JSlider;
54     import javax.swing.JToggleButton;
55    
56 iliev 842 import javax.swing.border.Border;
57     import javax.swing.border.LineBorder;
58    
59 iliev 787 import javax.swing.event.ChangeEvent;
60     import javax.swing.event.ChangeListener;
61    
62     import net.sf.juife.JuifeUtils;
63    
64     import org.jsampler.CC;
65     import org.jsampler.AudioDeviceModel;
66     import org.jsampler.MidiDeviceModel;
67     import org.jsampler.SamplerChannelModel;
68     import org.jsampler.SamplerModel;
69    
70     import org.jsampler.event.AudioDeviceListEvent;
71     import org.jsampler.event.AudioDeviceListListener;
72     import org.jsampler.event.MidiDeviceListEvent;
73     import org.jsampler.event.MidiDeviceListListener;
74     import org.jsampler.event.SamplerChannelAdapter;
75     import org.jsampler.event.SamplerChannelEvent;
76     import org.jsampler.event.SamplerChannelListener;
77    
78     import org.linuxsampler.lscp.AudioOutputDevice;
79     import org.linuxsampler.lscp.MidiInputDevice;
80     import org.linuxsampler.lscp.MidiPort;
81     import org.linuxsampler.lscp.SamplerChannel;
82     import org.linuxsampler.lscp.SamplerEngine;
83    
84     import static org.jsampler.view.classic.ClassicI18n.i18n;
85    
86    
87     /**
88     *
89     * @author Grigor Iliev
90     */
91     public class Channel extends org.jsampler.view.JSChannel {
92     private final static ImageIcon iconMuteOn;
93     private final static ImageIcon iconMuteOff;
94     private final static ImageIcon iconMutedBySolo;
95    
96     private final static ImageIcon iconSoloOn;
97     private final static ImageIcon iconSoloOff;
98    
99     private final static ImageIcon iconShowProperties;
100     private final static ImageIcon iconHideProperties;
101    
102 iliev 842 private static Border borderSelected;
103     private static Border borderDeselected;
104    
105     private static Color borderColor;
106    
107     private final static Vector<PropertyChangeListener> propertyChangeListeners
108     = new Vector<PropertyChangeListener>();
109    
110 iliev 787 static {
111     String path = "org/jsampler/view/classic/res/icons/";
112     URL url = ClassLoader.getSystemClassLoader().getResource(path + "mute_on.png");
113     iconMuteOn = new ImageIcon(url);
114    
115     url = ClassLoader.getSystemClassLoader().getResource(path + "mute_off.png");
116     iconMuteOff = new ImageIcon(url);
117    
118     url = ClassLoader.getSystemClassLoader().getResource(path + "muted_by_solo.png");
119     iconMutedBySolo = new ImageIcon(url);
120    
121     url = ClassLoader.getSystemClassLoader().getResource(path + "solo_on.png");
122     iconSoloOn = new ImageIcon(url);
123    
124     url = ClassLoader.getSystemClassLoader().getResource(path + "solo_off.png");
125     iconSoloOff = new ImageIcon(url);
126    
127     url = ClassLoader.getSystemClassLoader().getResource(path + "Back16.gif");
128     iconShowProperties = new ImageIcon(url);
129    
130     url = ClassLoader.getSystemClassLoader().getResource(path + "Down16.gif");
131     iconHideProperties = new ImageIcon(url);
132 iliev 842
133     if(ClassicPrefs.getCustomChannelBorderColor())
134     setBorderColor(ClassicPrefs.getChannelBorderColor());
135     else setBorderColor(ClassicPrefs.getDefaultChannelBorderColor());
136    
137     borderSelected = new LineBorder(getBorderColor(), 2, true);
138     borderDeselected = BorderFactory.createEmptyBorder(2, 2, 2, 2);
139 iliev 787 }
140    
141 iliev 842 /**
142     * Registers the specified listener for receiving property change events.
143     * @param l The <code>PropertyChangeListener</code> to register.
144     */
145     public void
146     addPropertyChangeListener(PropertyChangeListener l) {
147     propertyChangeListeners.add(l);
148     }
149 iliev 787
150 iliev 842 /**
151     * Removes the specified listener.
152     * @param l The <code>PropertyChangeListener</code> to remove.
153     */
154     public void
155     removePropertyChangeListener(PropertyChangeListener l) {
156     propertyChangeListeners.remove(l);
157     }
158    
159     /**
160     * Gets the border color that is used when the channel is selected.
161     * @return The border color that is used when the channel is selected.
162     */
163     public static Color
164     getBorderColor() { return borderColor; }
165    
166     /**
167     * Sets the border color to be used when the channel is selected.
168     * @param c The border color to be used when the channel is selected.
169     */
170     public static void
171     setBorderColor(Color c) {
172     if(borderColor != null && borderColor.getRGB() == c.getRGB()) return;
173    
174     Color oldColor = borderColor;
175     borderColor = c;
176     borderSelected = new LineBorder(getBorderColor(), 2, true);
177     firePropertyChanged("borderColor", oldColor, borderColor);
178     }
179    
180     private static void
181     firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
182     PropertyChangeEvent e =
183     new PropertyChangeEvent(Channel.class, propertyName, oldValue, newValue);
184    
185     for(PropertyChangeListener l : propertyChangeListeners) l.propertyChange(e);
186     }
187    
188    
189 iliev 787 private final JPanel mainPane = new JPanel();
190     private final ChannelProperties propertiesPane;
191     private final JButton btnInstr = new JButton(i18n.getLabel("Channel.btnInstr"));
192     private final JButton btnMute = new JButton();
193     private final JButton btnSolo = new JButton();
194     private final JSlider slVolume = new JSlider(0, 100);
195     private final JLabel lVolume = new JLabel();
196     private final JLabel lStreams = new JLabel("--");
197     private final JLabel lVoices = new JLabel("--");
198     private final JToggleButton btnProperties = new JToggleButton();
199    
200     private final EventHandler eventHandler = new EventHandler();
201    
202     private static int count = 2;
203    
204     private boolean selected = false;
205    
206    
207     /**
208     * Creates a new instance of <code>Channel</code> using the specified
209     * non-<code>null</code> channel model.
210     * @param model The model to be used by this channel.
211     * @throws IllegalArgumentException If the model is <code>null</code>.
212     */
213     public
214     Channel(SamplerChannelModel model) {
215     super(model);
216    
217     setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
218    
219     mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
220    
221     JPanel p = new JPanel();
222     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
223     p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
224    
225     //setToolTipText(" Channel: " + String.valueOf(getChannelID()) + " ");
226    
227     Dimension d = btnInstr.getPreferredSize();
228     btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, d.height));
229     p.add(btnInstr);
230     p.add(Box.createRigidArea(new Dimension(6, 0)));
231    
232     lStreams.setHorizontalAlignment(JLabel.CENTER);
233     lVoices.setHorizontalAlignment(JLabel.CENTER);
234    
235     JPanel statPane = new JPanel();
236     statPane.setBorder(BorderFactory.createLoweredBevelBorder());
237     statPane.setLayout(new BoxLayout(statPane, BoxLayout.X_AXIS));
238     statPane.add(Box.createRigidArea(new Dimension(6, 0)));
239     statPane.add(lStreams);
240     statPane.add(new JLabel("/"));
241     statPane.add(lVoices);
242     statPane.add(Box.createRigidArea(new Dimension(6, 0)));
243    
244     p.add(statPane);
245    
246     p.add(Box.createRigidArea(new Dimension(6, 0)));
247    
248     btnMute.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
249     p.add(btnMute);
250     p.add(Box.createRigidArea(new Dimension(6, 0)));
251    
252     btnSolo.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
253     p.add(btnSolo);
254     p.add(Box.createRigidArea(new Dimension(6, 0)));
255    
256     JPanel volumePane = new JPanel();
257     volumePane.setBorder(BorderFactory.createLoweredBevelBorder());
258     volumePane.setLayout(new BoxLayout(volumePane, BoxLayout.X_AXIS));
259     volumePane.add(Box.createRigidArea(new Dimension(6, 0)));
260    
261     d = slVolume.getPreferredSize();
262     slVolume.setMaximumSize(new Dimension(d.width > 300 ? d.width : 300, d.height));
263     volumePane.add(slVolume);
264    
265     lVolume.setBorder(BorderFactory.createEmptyBorder(3, 6, 3, 6));
266     lVolume.setHorizontalAlignment(lVolume.RIGHT);
267    
268     // We use this to set the size of the lVolume that will be used in setVolume()
269     // to prevent the frequent resizing of lVolume
270     lVolume.setText("100%");
271    
272     volumePane.add(lVolume);
273    
274     p.add(volumePane);
275     p.add(Box.createRigidArea(new Dimension(6, 0)));
276    
277     btnProperties.setContentAreaFilled(false);
278     btnProperties.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
279     btnProperties.setIcon(iconShowProperties);
280     btnProperties.setSelectedIcon(iconHideProperties);
281     p.add(btnProperties);
282    
283     mainPane.add(p);
284    
285     propertiesPane = new ChannelProperties(model);
286     propertiesPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
287     propertiesPane.setVisible(false);
288     mainPane.add(propertiesPane);
289     add(mainPane);
290    
291     d = getPreferredSize();
292     setMaximumSize(new Dimension(getMaximumSize().width, d.height));
293    
294 iliev 842 getModel().addSamplerChannelListener(getHandler());
295 iliev 787
296     btnInstr.addActionListener(new ActionListener() {
297     public void
298     actionPerformed(ActionEvent e) { loadInstrument(); }
299     });
300    
301     btnMute.addActionListener(new ActionListener() {
302     public void
303     actionPerformed(ActionEvent e) { changeMute(); }
304     });
305    
306     btnSolo.addActionListener(new ActionListener() {
307     public void
308     actionPerformed(ActionEvent e) { changeSolo(); }
309     });
310    
311     slVolume.addChangeListener(new ChangeListener() {
312     public void
313     stateChanged(ChangeEvent e) { setVolume(); }
314     });
315    
316     btnProperties.addActionListener(new ActionListener() {
317     public void
318     actionPerformed(ActionEvent e) {
319     showProperties(btnProperties.isSelected());
320 iliev 842
321     String s;
322     if(btnProperties.isSelected()) {
323     s = i18n.getButtonLabel("Channel.ttHideProps");
324     } else {
325     s = i18n.getButtonLabel("Channel.ttShowProps");
326     }
327    
328     btnProperties.setToolTipText(s);
329 iliev 787 }
330     });
331    
332 iliev 842 btnProperties.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
333    
334     String s;
335     if(btnProperties.isSelected()) s = i18n.getButtonLabel("Channel.ttHideProps");
336     else s = i18n.getButtonLabel("Channel.ttShowProps");
337    
338     btnProperties.setToolTipText(s);
339    
340     addPropertyChangeListener(getHandler());
341    
342 iliev 787 updateChannelInfo();
343     }
344    
345 iliev 842 private EventHandler
346     getHandler() { return eventHandler; }
347    
348     private class EventHandler implements SamplerChannelListener, PropertyChangeListener {
349 iliev 787 /**
350     * Invoked when changes are made to a sampler channel.
351     * @param e A <code>SamplerChannelEvent</code> instance
352     * containing event information.
353     */
354     public void
355     channelChanged(SamplerChannelEvent e) { updateChannelInfo(); }
356    
357     /**
358     * Invoked when the number of active disk streams has changed.
359     * @param e A <code>SamplerChannelEvent</code> instance
360     * containing event information.
361     */
362     public void
363     streamCountChanged(SamplerChannelEvent e) {
364     updateStreamCount(getModel().getStreamCount());
365     }
366    
367     /**
368     * Invoked when the number of active voices has changed.
369     * @param e A <code>SamplerChannelEvent</code> instance
370     * containing event information.
371     */
372     public void
373     voiceCountChanged(SamplerChannelEvent e) {
374     updateVoiceCount(getModel().getVoiceCount());
375     }
376 iliev 842
377     public void
378     propertyChange(PropertyChangeEvent e) {
379     if(e.getPropertyName() == "borderColor") setSelected(isSelected());
380     }
381 iliev 787 }
382    
383     /**
384     * Determines whether the channel is selected.
385     * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
386     */
387     public boolean isSelected() { return selected; }
388    
389     /**
390     * Sets the selection state of this channel.
391     * This method is invoked when the selection state of the channel has changed.
392     * @param select Specifies the new selection state of this channel;
393     * <code>true</code> to select the channel, <code>false</code> otherwise.
394     */
395     public void
396     setSelected(boolean select) {
397 iliev 842 if(select) mainPane.setBorder(borderSelected);
398     else mainPane.setBorder(borderDeselected);
399 iliev 787
400     selected = select;
401     }
402    
403     /** Hides the channel properties. */
404     public void
405     collapseChannel() { if(btnProperties.isSelected()) btnProperties.doClick(); }
406    
407     /** Shows the channel properties. */
408     public void
409     expandChannel() { if(!btnProperties.isSelected()) btnProperties.doClick(); }
410    
411     /**
412     * Updates the channel settings. This method is invoked when changes to the
413     * channel were made.
414     */
415     private void
416     updateChannelInfo() {
417     SamplerChannel sc = getChannelInfo();
418    
419     int status = sc.getInstrumentStatus();
420     if(status >= 0 && status < 100) {
421     btnInstr.setText(i18n.getLabel("Channel.loadingInstrument", status));
422     } else {
423     if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
424     else btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
425     }
426    
427     updateMute(sc);
428    
429     if(sc.isSoloChannel()) btnSolo.setIcon(iconSoloOn);
430     else btnSolo.setIcon(iconSoloOff);
431    
432     slVolume.setValue((int)(sc.getVolume() * 100));
433    
434     boolean b = sc.getEngine() != null;
435     slVolume.setEnabled(b);
436     btnSolo.setEnabled(b);
437     btnMute.setEnabled(b);
438     }
439    
440     /** Invoked when the user clicks the mute button. */
441     private void
442     changeMute() {
443     SamplerChannel sc = getChannelInfo();
444     boolean b = true;
445    
446     /*
447     * Changing the mute button icon now instead of
448     * leaving the work to the notification mechanism of the LinuxSampler.
449     */
450     if(sc.isMuted() && !sc.isMutedBySolo()) {
451     b = false;
452     boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
453    
454     if(sc.isSoloChannel() || !hasSolo) btnMute.setIcon(iconMuteOff);
455     else btnMute.setIcon(iconMutedBySolo);
456     } else btnMute.setIcon(iconMuteOn);
457    
458     getModel().setMute(b);
459     }
460    
461     /** Invoked when the user clicks the solo button. */
462     private void
463     changeSolo() {
464     SamplerChannel sc = getChannelInfo();
465     boolean b = !sc.isSoloChannel();
466    
467     /*
468     * Changing the solo button icon (and related) now instead of
469     * leaving the work to the notification mechanism of the LinuxSampler.
470     */
471     if(b) {
472     btnSolo.setIcon(iconSoloOn);
473     if(sc.isMutedBySolo()) btnMute.setIcon(iconMuteOff);
474     } else {
475     btnSolo.setIcon(iconSoloOff);
476     if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
477     btnMute.setIcon(iconMutedBySolo);
478     }
479    
480     getModel().setSolo(b);
481     }
482    
483     /** Invoked when the user changes the volume */
484     private void
485     setVolume() {
486     updateVolume();
487    
488     if(slVolume.getValueIsAdjusting()) return;
489    
490     int vol = (int)(getChannelInfo().getVolume() * 100);
491    
492     if(vol == slVolume.getValue()) return;
493    
494     /*
495     * If the model's volume is not equal to the slider
496     * value we assume that the change is due to user input.
497     * So we must update the volume at the backend too.
498     */
499     float volume = slVolume.getValue();
500     volume /= 100;
501     getModel().setVolume(volume);
502     }
503    
504     private void
505     updateVolume() {
506     int volume = slVolume.getValue();
507     slVolume.setToolTipText(i18n.getLabel("Channel.volume", volume));
508    
509     setVolumeLabel(volume);
510    
511    
512     }
513    
514     private void
515     setVolumeLabel(int volume) {
516     Dimension d = lVolume.getPreferredSize();
517     lVolume.setText(String.valueOf(volume) + '%');
518     d = JuifeUtils.getUnionSize(d, lVolume.getPreferredSize());
519     lVolume.setMinimumSize(d);
520     lVolume.setPreferredSize(d);
521     lVolume.setMaximumSize(d);
522     }
523    
524     /**
525     * Updates the mute button with the proper icon regarding to information obtained
526     * from <code>channel</code>.
527     * @param channel A <code>SamplerChannel</code> instance containing the new settings
528     * for this channel.
529     */
530     private void
531     updateMute(SamplerChannel channel) {
532     if(channel.isMutedBySolo()) btnMute.setIcon(iconMutedBySolo);
533     else if(channel.isMuted()) btnMute.setIcon(iconMuteOn);
534     else btnMute.setIcon(iconMuteOff);
535     }
536    
537     /**
538     * Updates the number of active disk streams.
539     * @param count The new number of active disk streams.
540     */
541     private void
542     updateStreamCount(int count) {
543     Dimension d = lStreams.getPreferredSize();
544     lStreams.setText(count == 0 ? "--" : String.valueOf(count));
545     d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());
546     lStreams.setMinimumSize(d);
547     lStreams.setPreferredSize(d);
548     lStreams.setMaximumSize(d);
549     }
550    
551     /**
552     * Updates the number of active voices.
553     * @param count The new number of active voices.
554     */
555     private void
556     updateVoiceCount(int count) {
557     Dimension d = lVoices.getPreferredSize();
558     lVoices.setText(count == 0 ? "--" : String.valueOf(count));
559     d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());
560     lVoices.setMinimumSize(d);
561     lVoices.setPreferredSize(d);
562     lVoices.setMaximumSize(d);
563     }
564    
565     private void
566     showProperties(boolean show) {propertiesPane.setVisible(show); }
567    
568     private void
569     loadInstrument() {
570     InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());
571     dlg.setVisible(true);
572    
573     if(!dlg.isCancelled()) {
574     getModel().loadInstrument(dlg.getFileName(), dlg.getInstrumentIndex());
575     }
576     }
577     }
578    
579     class ChannelProperties extends JPanel {
580     private final static ImageIcon iconAudioProps;
581    
582     static {
583     String path = "org/jsampler/view/classic/res/icons/";
584     URL url = ClassLoader.getSystemClassLoader().getResource(path + "Import16.gif");
585     iconAudioProps = new ImageIcon(url);
586     }
587    
588     private final JLabel lMidiDevice =
589     new JLabel(i18n.getLabel("ChannelProperties.lMidiDevice"));
590     private final JLabel lMidiPort =
591     new JLabel(i18n.getLabel("ChannelProperties.lMidiPort"));
592     private final JLabel lMidiChannel =
593     new JLabel(i18n.getLabel("ChannelProperties.lMidiChannel"));
594    
595     private final JLabel lAudioDevice =
596     new JLabel(i18n.getLabel("ChannelProperties.lAudioDevice"));
597    
598     private final JComboBox cbEngines = new JComboBox();
599    
600     private final JComboBox cbMidiDevice = new JComboBox();
601     private final JComboBox cbMidiPort = new JComboBox();
602     private final JComboBox cbMidiChannel = new JComboBox();
603     private final JComboBox cbAudioDevice = new JComboBox();
604    
605     private final JButton btnAudioProps = new JButton(iconAudioProps);
606    
607     private SamplerChannelModel channelModel = null;
608    
609     private boolean update = false;
610    
611     /**
612     * Creates a new instance of <code>ChannelProperties</code> using the specified non-null
613     * channel model.
614     * @param model The model to be used by this channel properties pane.
615     */
616     ChannelProperties(SamplerChannelModel model) {
617     channelModel = model;
618    
619     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
620    
621     add(new JSeparator());
622    
623     JPanel enginesPane = new JPanel();
624    
625     for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngines.addItem(e);
626    
627     //cbEngines.setMaximumSize(cbEngines.getPreferredSize());
628    
629     enginesPane.add(cbEngines);
630     String s = i18n.getLabel("ChannelProperties.enginesPane");
631     enginesPane.setBorder(BorderFactory.createTitledBorder(s));
632    
633     JPanel devicesPane = new JPanel();
634     devicesPane.setLayout(new BoxLayout(devicesPane, BoxLayout.X_AXIS));
635    
636     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
637    
638     devicesPane.add(createMidiPane());
639    
640     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
641    
642     devicesPane.add(enginesPane);
643    
644     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
645    
646     JPanel audioPane = createAudioPane();
647     Dimension d = audioPane.getPreferredSize();
648     d.height = Short.MAX_VALUE;
649    
650     audioPane.setMaximumSize(d);
651     devicesPane.add(audioPane);
652    
653     add(devicesPane);
654     add(Box.createRigidArea(new Dimension(0, 6)));
655    
656     add(new JSeparator());
657    
658     cbMidiChannel.addItem("All");
659     for(int i = 1; i <= 16; i++) cbMidiChannel.addItem(String.valueOf(i));
660    
661     cbMidiDevice.addActionListener(new ActionListener() {
662     public void
663     actionPerformed(ActionEvent e) { setMidiDevice(); }
664     });
665    
666     cbMidiPort.addActionListener(new ActionListener() {
667     public void
668     actionPerformed(ActionEvent e) { setMidiPort(); }
669     });
670    
671     cbMidiChannel.addActionListener(new ActionListener() {
672     public void
673     actionPerformed(ActionEvent e) { setMidiChannel(); }
674     });
675    
676     cbEngines.addActionListener(new ActionListener() {
677     public void
678     actionPerformed(ActionEvent e) { setEngineType(); }
679     });
680    
681     cbAudioDevice.addActionListener(new ActionListener() {
682     public void
683     actionPerformed(ActionEvent e) { setAudioDevice(); }
684     });
685    
686     getModel().addSamplerChannelListener(new SamplerChannelAdapter() {
687     public void
688     channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }
689     });
690    
691     CC.getSamplerModel().addMidiDeviceListListener(getHandler());
692     CC.getSamplerModel().addAudioDeviceListListener(getHandler());
693    
694     btnAudioProps.setToolTipText(i18n.getLabel("ChannelProperties.routing"));
695     btnAudioProps.addActionListener(new ActionListener() {
696     public void
697     actionPerformed(ActionEvent e) {
698     SamplerChannel c = getModel().getChannelInfo();
699     new ChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
700    
701     }
702     });
703    
704    
705    
706     updateMidiDevices();
707     updateAudioDevices();
708     updateChannelProperties();
709     }
710    
711     private JPanel
712     createMidiPane() {
713     JPanel midiPane = new JPanel();
714    
715     GridBagLayout gridbag = new GridBagLayout();
716     GridBagConstraints c = new GridBagConstraints();
717    
718     midiPane.setLayout(gridbag);
719    
720     c.gridx = 0;
721     c.gridy = 0;
722     c.insets = new Insets(3, 3, 3, 3);
723     gridbag.setConstraints(lMidiDevice, c);
724     midiPane.add(lMidiDevice);
725    
726     c.gridx = 1;
727     c.gridy = 0;
728     gridbag.setConstraints(cbMidiDevice, c);
729     midiPane.add(cbMidiDevice);
730    
731     c.gridx = 2;
732     c.gridy = 0;
733     gridbag.setConstraints(lMidiPort, c);
734     midiPane.add(lMidiPort);
735    
736     c.gridx = 4;
737     c.gridy = 0;
738     gridbag.setConstraints(lMidiChannel, c);
739     midiPane.add(lMidiChannel);
740    
741     c.gridx = 5;
742     c.gridy = 0;
743     gridbag.setConstraints(cbMidiChannel, c);
744     midiPane.add(cbMidiChannel);
745    
746     c.gridx = 3;
747     c.gridy = 0;
748     c.weightx = 1.0;
749     c.fill = GridBagConstraints.HORIZONTAL;
750     c.insets = new Insets(3, 3, 3, 3);
751     gridbag.setConstraints(cbMidiPort, c);
752     midiPane.add(cbMidiPort);
753    
754     String s = i18n.getLabel("ChannelProperties.midiPane");
755     midiPane.setBorder(BorderFactory.createTitledBorder(s));
756    
757     return midiPane;
758     }
759    
760     private JPanel
761     createAudioPane() {
762     JPanel audioPane = new JPanel();
763    
764     GridBagLayout gridbag = new GridBagLayout();
765     GridBagConstraints c = new GridBagConstraints();
766    
767     audioPane.setLayout(gridbag);
768    
769     c.gridx = 0;
770     c.gridy = 0;
771     c.insets = new Insets(3, 3, 3, 3);
772     gridbag.setConstraints(lAudioDevice, c);
773     audioPane.add(lAudioDevice);
774    
775     c.gridx = 1;
776     c.gridy = 0;
777     gridbag.setConstraints(cbAudioDevice, c);
778     audioPane.add(cbAudioDevice);
779    
780     btnAudioProps.setMargin(new Insets(0, 0, 0, 0));
781     c.gridx = 2;
782     c.gridy = 0;
783     c.insets = new Insets(3, 9, 3, 3);
784     gridbag.setConstraints(btnAudioProps, c);
785     audioPane.add(btnAudioProps);
786    
787     String s = i18n.getLabel("ChannelProperties.audioPane");
788     audioPane.setBorder(BorderFactory.createTitledBorder(s));
789    
790     return audioPane;
791     }
792    
793     /**
794     * Gets the model that is currently used by this channel properties pane.
795     * @return model The <code>SamplerChannelModel</code> instance
796     * that provides information about the channel whose settings are
797     * represented by this channel properties pane.
798     */
799     public SamplerChannelModel
800     getModel() { return channelModel; }
801    
802     /**
803     * Updates the channel settings. This method is invoked when changes to the
804     * channel were made.
805     */
806     private void
807     updateChannelProperties() {
808     SamplerModel sm = CC.getSamplerModel();
809     SamplerChannel sc = getModel().getChannelInfo();
810    
811     MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
812     AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
813    
814     if(isUpdate()) CC.getLogger().warning("Unexpected update state!");
815    
816     setUpdate(true);
817    
818     try {
819     cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
820    
821     cbEngines.setSelectedItem(sc.getEngine());
822    
823     cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
824     } catch(Exception x) {
825     CC.getLogger().log(Level.WARNING, "Unkown error", x);
826     }
827    
828     setUpdate(false);
829     }
830    
831     /**
832     * Updates the MIDI device list.
833     */
834     private void
835     updateMidiDevices() {
836     SamplerModel sm = CC.getSamplerModel();
837     SamplerChannel sc = getModel().getChannelInfo();
838    
839     setUpdate(true);
840    
841     try {
842     cbMidiDevice.removeAllItems();
843    
844     for(MidiDeviceModel m : sm.getMidiDeviceModels())
845     cbMidiDevice.addItem(m.getDeviceInfo());
846    
847     MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
848     cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
849     } catch(Exception x) {
850     CC.getLogger().log(Level.WARNING, "Unkown error", x);
851     }
852    
853     setUpdate(false);
854     }
855    
856     /**
857     * Updates the audio device list.
858     */
859     private void
860     updateAudioDevices() {
861     SamplerModel sm = CC.getSamplerModel();
862     SamplerChannel sc = getModel().getChannelInfo();
863    
864     setUpdate(true);
865    
866     try {
867     cbAudioDevice.removeAllItems();
868    
869     for(AudioDeviceModel m : sm.getAudioDeviceModels())
870     cbAudioDevice.addItem(m.getDeviceInfo());
871    
872     AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
873     cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
874     } catch(Exception x) {
875     CC.getLogger().log(Level.WARNING, "Unkown error", x);
876     }
877    
878     setUpdate(false);
879     }
880    
881     private void
882     setMidiDevice() {
883     MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();
884    
885     if(!isUpdate()) {
886     if(mid != null) getModel().setMidiInputDevice(mid.getDeviceID());
887     return;
888     }
889    
890     cbMidiPort.removeAllItems();
891    
892     if(mid == null) {
893     cbMidiPort.setEnabled(false);
894    
895     cbMidiChannel.setSelectedItem(null);
896     cbMidiChannel.setEnabled(false);
897     } else {
898     cbMidiPort.setEnabled(true);
899    
900     MidiPort[] ports = mid.getMidiPorts();
901     for(MidiPort port : ports) cbMidiPort.addItem(port);
902    
903     int p = getModel().getChannelInfo().getMidiInputPort();
904     cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);
905    
906     cbMidiChannel.setEnabled(true);
907     int c = getModel().getChannelInfo().getMidiInputChannel();
908     cbMidiChannel.setSelectedItem(c == -1 ? "All" : String.valueOf(c + 1));
909     }
910    
911    
912     }
913    
914     private void
915     setMidiPort() {
916     if(isUpdate()) return;
917    
918     getModel().setMidiInputPort(cbMidiPort.getSelectedIndex());
919     }
920    
921     private void
922     setMidiChannel() {
923     if(isUpdate()) return;
924    
925     Object o = cbMidiChannel.getSelectedItem();
926     if(o == null) return;
927    
928     int c = o.toString().equals("All") ? -1 : Integer.parseInt(o.toString()) - 1;
929    
930     getModel().setMidiInputChannel(c);
931     }
932    
933     /** Invoked when the user selects an engine. */
934     private void
935     setEngineType() {
936     Object oldEngine = getModel().getChannelInfo().getEngine();
937     SamplerEngine newEngine = (SamplerEngine)cbEngines.getSelectedItem();
938    
939     if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }
940     else if(newEngine == null) return;
941    
942     getModel().setEngineType(newEngine.getName());
943    
944     }
945    
946     private void
947     setAudioDevice() {
948     if(isUpdate()) return;
949     AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();
950     if(dev != null) getModel().setAudioOutputDevice(dev.getDeviceID());
951     }
952    
953     /**
954     * Determines whether the currently processed changes are due to update.
955     * @return <code>true</code> if the currently processed changes are due to update and
956     * <code>false</code> if the currently processed changes are due to user input.
957     */
958     private boolean
959     isUpdate() { return update; }
960    
961     /**
962     * Sets whether the currently processed changes are due to update.
963     * @param b Specify <code>true</code> to indicate that the currently
964     * processed changes are due to update; <code>false</code>
965     * indicates that the currently processed changes are due to user input.
966     */
967     private void
968     setUpdate(boolean b) { update = b; }
969    
970     private final Handler handler = new Handler();
971    
972     private Handler
973     getHandler() { return handler; }
974    
975     private class Handler implements MidiDeviceListListener, AudioDeviceListListener {
976     /**
977     * Invoked when a new MIDI device is created.
978     * @param e A <code>MidiDeviceListEvent</code>
979     * instance providing the event information.
980     */
981     public void
982     deviceAdded(MidiDeviceListEvent e) {
983     cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());
984     }
985    
986     /**
987     * Invoked when a MIDI device is removed.
988     * @param e A <code>MidiDeviceListEvent</code>
989     * instance providing the event information.
990     */
991     public void
992     deviceRemoved(MidiDeviceListEvent e) {
993     cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());
994     }
995    
996     /**
997     * Invoked when a new audio device is created.
998     * @param e An <code>AudioDeviceListEvent</code>
999     * instance providing the event information.
1000     */
1001     public void
1002     deviceAdded(AudioDeviceListEvent e) {
1003     cbAudioDevice.addItem(e.getAudioDeviceModel().getDeviceInfo());
1004     }
1005    
1006     /**
1007     * Invoked when an audio device is removed.
1008     * @param e An <code>AudioDeviceListEvent</code>
1009     * instance providing the event information.
1010     */
1011     public void
1012     deviceRemoved(AudioDeviceListEvent e) {
1013     cbAudioDevice.removeItem(e.getAudioDeviceModel().getDeviceInfo());
1014     }
1015     }
1016     }

  ViewVC Help
Powered by ViewVC