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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1143 - (show annotations) (download)
Mon Apr 2 21:18:31 2007 UTC (17 years, 1 month ago) by iliev
File size: 43217 byte(s)
* upgrading to version 0.4a

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2007 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.BorderLayout;
26 import java.awt.Color;
27 import java.awt.Cursor;
28 import java.awt.Dimension;
29 import java.awt.GridBagConstraints;
30 import java.awt.GridBagLayout;
31 import java.awt.Insets;
32
33 import java.awt.datatransfer.Transferable;
34
35 import java.awt.event.ActionEvent;
36 import java.awt.event.ActionListener;
37 import java.awt.event.HierarchyEvent;
38 import java.awt.event.HierarchyListener;
39 import java.awt.event.MouseAdapter;
40 import java.awt.event.MouseEvent;
41 import java.awt.event.MouseMotionAdapter;
42
43 import java.beans.PropertyChangeEvent;
44 import java.beans.PropertyChangeListener;
45
46 import java.net.URL;
47
48 import java.util.Vector;
49
50 import java.util.logging.Level;
51
52 import javax.swing.Action;
53 import javax.swing.AbstractAction;
54 import javax.swing.BorderFactory;
55 import javax.swing.Box;
56 import javax.swing.BoxLayout;
57 import javax.swing.JComponent;
58 import javax.swing.ImageIcon;
59 import javax.swing.JButton;
60 import javax.swing.JComboBox;
61 import javax.swing.JLabel;
62 import javax.swing.JPanel;
63 import javax.swing.JSeparator;
64 import javax.swing.JSlider;
65 import javax.swing.JToggleButton;
66 import javax.swing.TransferHandler;
67
68 import javax.swing.border.Border;
69 import javax.swing.border.LineBorder;
70 import javax.swing.border.TitledBorder;
71
72 import javax.swing.event.ChangeEvent;
73 import javax.swing.event.ChangeListener;
74
75 import net.sf.juife.InformationDialog;
76 import net.sf.juife.JuifeUtils;
77
78 import org.jsampler.AudioDeviceModel;
79 import org.jsampler.CC;
80 import org.jsampler.HF;
81 import org.jsampler.Instrument;
82 import org.jsampler.MidiDeviceModel;
83 import org.jsampler.MidiInstrumentMap;
84 import org.jsampler.SamplerChannelModel;
85 import org.jsampler.SamplerModel;
86
87 import org.jsampler.event.ListEvent;
88 import org.jsampler.event.ListListener;
89 import org.jsampler.event.MidiDeviceListEvent;
90 import org.jsampler.event.MidiDeviceListListener;
91 import org.jsampler.event.SamplerAdapter;
92 import org.jsampler.event.SamplerChannelAdapter;
93 import org.jsampler.event.SamplerChannelEvent;
94 import org.jsampler.event.SamplerChannelListEvent;
95 import org.jsampler.event.SamplerChannelListListener;
96 import org.jsampler.event.SamplerChannelListener;
97 import org.jsampler.event.SamplerEvent;
98
99 import org.linuxsampler.lscp.AudioOutputDevice;
100 import org.linuxsampler.lscp.MidiInputDevice;
101 import org.linuxsampler.lscp.MidiPort;
102 import org.linuxsampler.lscp.SamplerChannel;
103 import org.linuxsampler.lscp.SamplerEngine;
104
105 import static org.jsampler.view.classic.ClassicI18n.i18n;
106
107
108 /**
109 *
110 * @author Grigor Iliev
111 */
112 public class Channel extends org.jsampler.view.JSChannel {
113 private final static ImageIcon iconMuteOn;
114 private final static ImageIcon iconMuteOff;
115 private final static ImageIcon iconMutedBySolo;
116
117 private final static ImageIcon iconSoloOn;
118 private final static ImageIcon iconSoloOff;
119
120 private final static ImageIcon iconShowProperties;
121 private final static ImageIcon iconHideProperties;
122
123 private static Border borderSelected;
124 private static Border borderHighlighted;
125 private static Border borderDeselected;
126
127 private static Color chnColor;
128 private static Color borderColor;
129 private static Color borderHighlightedColor;
130 private static Color chnSelectedColor;
131 private static Color chnHighlightedColor;
132
133 private final static Vector<PropertyChangeListener> propertyChangeListeners
134 = new Vector<PropertyChangeListener>();
135
136 static {
137 String path = "org/jsampler/view/classic/res/icons/";
138 URL url = ClassLoader.getSystemClassLoader().getResource(path + "mute_on.png");
139 iconMuteOn = new ImageIcon(url);
140
141 url = ClassLoader.getSystemClassLoader().getResource(path + "mute_off.png");
142 iconMuteOff = new ImageIcon(url);
143
144 url = ClassLoader.getSystemClassLoader().getResource(path + "muted_by_solo.png");
145 iconMutedBySolo = new ImageIcon(url);
146
147 url = ClassLoader.getSystemClassLoader().getResource(path + "solo_on.png");
148 iconSoloOn = new ImageIcon(url);
149
150 url = ClassLoader.getSystemClassLoader().getResource(path + "solo_off.png");
151 iconSoloOff = new ImageIcon(url);
152
153 url = ClassLoader.getSystemClassLoader().getResource(path + "Back16.gif");
154 iconShowProperties = new ImageIcon(url);
155
156 iconHideProperties = Res.iconDown16;
157
158 if(ClassicPrefs.getCustomChannelBorderColor())
159 setBorderColor(ClassicPrefs.getChannelBorderColor());
160 else setBorderColor(ClassicPrefs.getDefaultChannelBorderColor());
161
162 if(ClassicPrefs.getCustomChannelBorderHlColor())
163 setBorderHighlightedColor(ClassicPrefs.getChannelBorderHlColor());
164 else setBorderHighlightedColor(ClassicPrefs.getDefaultChannelBorderHlColor());
165
166 borderSelected = new LineBorder(getBorderColor(), 2, true);
167 borderHighlighted = new LineBorder(getBorderHighlightedColor(), 2, true);
168 borderDeselected = BorderFactory.createEmptyBorder(2, 2, 2, 2);
169
170 chnColor = new JPanel().getBackground();
171
172 if(ClassicPrefs.getCustomSelectedChannelBgColor()) {
173 chnSelectedColor = ClassicPrefs.getSelectedChannelBgColor();
174 } else {
175 int r = chnColor.getRed() - 14 < 0 ? 0 : chnColor.getRed() - 14;
176 int g = chnColor.getGreen() - 8 < 0 ? 0 : chnColor.getGreen() - 8;
177 int b = chnColor.getBlue() - 3 < 0 ? 0 : chnColor.getBlue() - 3;
178
179 chnSelectedColor = new Color(r, g, b);
180 }
181
182 /*r = r + 5 > 255 ? 255 : r + 5;
183 g = g + 4 > 255 ? 255 : g + 4;
184 b = b + 1 > 255 ? 255 : b + 1;*/
185
186 chnHighlightedColor = new Color(chnColor.getRGB());
187 }
188
189 /**
190 * Registers the specified listener for receiving property change events.
191 * @param l The <code>PropertyChangeListener</code> to register.
192 */
193 public void
194 addPropertyChangeListener(PropertyChangeListener l) {
195 propertyChangeListeners.add(l);
196 }
197
198 /**
199 * Removes the specified listener.
200 * @param l The <code>PropertyChangeListener</code> to remove.
201 */
202 public void
203 removePropertyChangeListener(PropertyChangeListener l) {
204 propertyChangeListeners.remove(l);
205 }
206
207 /**
208 * Gets the border color that is used when the channel is selected.
209 * @return The border color that is used when the channel is selected.
210 */
211 public static Color
212 getBorderColor() { return borderColor; }
213
214 /**
215 * Sets the border color to be used when the channel is selected.
216 * @param c The border color to be used when the channel is selected.
217 */
218 public static void
219 setBorderColor(Color c) {
220 if(borderColor != null && borderColor.getRGB() == c.getRGB()) return;
221
222 Color oldColor = borderColor;
223 borderColor = c;
224 borderSelected = new LineBorder(getBorderColor(), 2, true);
225 firePropertyChanged("borderColor", oldColor, borderColor);
226 }
227
228 /**
229 * Gets the border color that is used when the mouse pointer is over a channel.
230 * @return The border color that is used when the mouse pointer is over a channel.
231 */
232 public static Color
233 getBorderHighlightedColor() { return borderHighlightedColor; }
234
235 /**
236 * Sets the border color to be used when the mouse pointer is over a channel.
237 * @param c The border color to be used when the mouse pointer is over a channel.
238 */
239 public static void
240 setBorderHighlightedColor(Color c) {
241 Color oldColor = borderHighlightedColor;
242 if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
243
244 borderHighlightedColor = c;
245 borderHighlighted = new LineBorder(getBorderHighlightedColor(), 2, true);
246 firePropertyChanged("borderHighlightedColor", oldColor, borderHighlightedColor);
247 }
248
249 /**
250 * Gets the background color that is used when a channel is selected.
251 * @return The background color that is used when a channel is selected.
252 */
253 public static Color
254 getSelectedChannelBgColor() { return chnSelectedColor; }
255
256 /**
257 * Sets the background color that is used when a channel is selected.
258 * @param c The background color to be used when a channel is selected.
259 */
260 public static void
261 setSelectedChannelBgColor(Color c) {
262 Color oldColor = chnSelectedColor;
263 if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
264
265 chnSelectedColor = c;
266 firePropertyChanged("selectedChannelBgColor", oldColor, chnSelectedColor);
267 }
268
269 /**
270 * Gets the background color that is used when the mouse pointer is over a channel.
271 * @return The background color that is used when the mouse pointer is over a channel.
272 */
273 public static Color
274 getHighlightedChannelBgColor() { return chnHighlightedColor; }
275
276 /**
277 * Sets the background color to be used when the mouse pointer is over a channel.
278 * @param c The background color to be used when the mouse pointer is over a channel.
279 */
280 public static void
281 setHighlightedChannelBgColor(Color c) {
282 Color oldColor = chnHighlightedColor;
283 if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
284
285 chnHighlightedColor = c;
286 firePropertyChanged("highlightedChannelBgColor", oldColor, chnHighlightedColor);
287 }
288
289 private static void
290 firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
291 PropertyChangeEvent e =
292 new PropertyChangeEvent(Channel.class, propertyName, oldValue, newValue);
293
294 for(PropertyChangeListener l : propertyChangeListeners) l.propertyChange(e);
295 }
296
297
298 private final JPanel mainPane = new JPanel();
299 private final ChannelProperties propertiesPane;
300 private final JButton btnInstr = new InstrumentButton(i18n.getLabel("Channel.btnInstr"));
301 private final Action actInstr;
302 private final JButton btnMute = new JButton();
303 private final JButton btnSolo = new JButton();
304 private final JSlider slVolume = new JSlider(0, 100);
305 private final JLabel lVolume = new JLabel();
306 private final JLabel lVolImg = new JLabel(Res.iconVolume16);
307 private final JLabel lStreams = new JLabel("--");
308 private final JLabel lVoices = new JLabel("--");
309 private final JToggleButton btnProperties = new JToggleButton();
310
311 private static int count = 2;
312
313 private boolean selected = false;
314 private boolean mouseOver = false;
315
316
317 /**
318 * Creates a new instance of <code>Channel</code> using the specified
319 * non-<code>null</code> channel model.
320 * @param model The model to be used by this channel.
321 * @throws IllegalArgumentException If the model is <code>null</code>.
322 */
323 public
324 Channel(SamplerChannelModel model) {
325 super(model);
326
327 setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
328
329 mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
330 addMouseListener(getHandler());
331
332 JPanel p = new JPanel();
333 p.setOpaque(false);
334 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
335 p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
336
337 setToolTipText(i18n.getLabel("Channel.tt", getModel().getChannelId()));
338
339 Dimension d = btnInstr.getPreferredSize();
340 btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, d.height));
341 p.add(btnInstr);
342 p.add(Box.createRigidArea(new Dimension(6, 0)));
343
344 lStreams.setHorizontalAlignment(JLabel.CENTER);
345 lVoices.setHorizontalAlignment(JLabel.CENTER);
346
347 JPanel statPane = new JPanel();
348 statPane.setOpaque(false);
349 statPane.setBorder(BorderFactory.createLoweredBevelBorder());
350 statPane.setLayout(new BoxLayout(statPane, BoxLayout.X_AXIS));
351 statPane.add(Box.createRigidArea(new Dimension(6, 0)));
352 statPane.add(lStreams);
353 statPane.add(new JLabel("/"));
354 statPane.add(lVoices);
355 statPane.add(Box.createRigidArea(new Dimension(6, 0)));
356
357 p.add(statPane);
358
359 p.add(Box.createRigidArea(new Dimension(6, 0)));
360
361 btnMute.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
362 p.add(btnMute);
363 p.add(Box.createRigidArea(new Dimension(6, 0)));
364
365 btnSolo.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
366 p.add(btnSolo);
367 p.add(Box.createRigidArea(new Dimension(6, 0)));
368
369 JPanel volumePane = new JPanel();
370 volumePane.setOpaque(false);
371 volumePane.setBorder(BorderFactory.createLoweredBevelBorder());
372 volumePane.setLayout(new BoxLayout(volumePane, BoxLayout.X_AXIS));
373 volumePane.add(Box.createRigidArea(new Dimension(6, 0)));
374
375 volumePane.add(lVolImg);
376 volumePane.add(Box.createRigidArea(new Dimension(1, 0)));
377
378 d = slVolume.getPreferredSize();
379 slVolume.setMaximumSize(new Dimension(d.width > 300 ? d.width : 300, d.height));
380 slVolume.setOpaque(false);
381 volumePane.add(slVolume);
382
383 lVolume.setBorder(BorderFactory.createEmptyBorder(3, 6, 3, 6));
384 lVolume.setHorizontalAlignment(lVolume.RIGHT);
385
386 // We use this to set the size of the lVolume that will be used in setVolume()
387 // to prevent the frequent resizing of lVolume
388 lVolume.setText("100%");
389
390 volumePane.add(lVolume);
391
392 p.add(volumePane);
393 p.add(Box.createRigidArea(new Dimension(6, 0)));
394
395 btnProperties.setContentAreaFilled(false);
396 btnProperties.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
397 btnProperties.setIcon(iconShowProperties);
398 btnProperties.setSelectedIcon(iconHideProperties);
399 p.add(btnProperties);
400
401 mainPane.add(p);
402
403 propertiesPane = new ChannelProperties(model);
404 propertiesPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
405 propertiesPane.setVisible(false);
406 mainPane.add(propertiesPane);
407 add(mainPane);
408
409 d = getPreferredSize();
410 setMaximumSize(new Dimension(getMaximumSize().width, d.height));
411
412 getModel().addSamplerChannelListener(getHandler());
413
414 actInstr = new AbstractAction() {
415 public void
416 actionPerformed(ActionEvent e) {
417 if(actInstr.isEnabled()) loadInstrument();
418 }
419 };
420
421 btnInstr.addActionListener(actInstr);
422
423 btnMute.addActionListener(new ActionListener() {
424 public void
425 actionPerformed(ActionEvent e) { changeMute(); }
426 });
427
428 btnSolo.addActionListener(new ActionListener() {
429 public void
430 actionPerformed(ActionEvent e) { changeSolo(); }
431 });
432
433 slVolume.addChangeListener(new ChangeListener() {
434 public void
435 stateChanged(ChangeEvent e) { setVolume(); }
436 });
437
438 btnProperties.addActionListener(new ActionListener() {
439 public void
440 actionPerformed(ActionEvent e) {
441 showProperties(btnProperties.isSelected());
442
443 String s;
444 if(btnProperties.isSelected()) {
445 s = i18n.getButtonLabel("Channel.ttHideProps");
446 } else {
447 s = i18n.getButtonLabel("Channel.ttShowProps");
448 }
449
450 btnProperties.setToolTipText(s);
451 }
452 });
453
454 btnProperties.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
455
456 String s;
457 if(btnProperties.isSelected()) s = i18n.getButtonLabel("Channel.ttHideProps");
458 else s = i18n.getButtonLabel("Channel.ttShowProps");
459
460 btnProperties.setToolTipText(s);
461
462 addPropertyChangeListener(getHandler());
463
464 updateChannelInfo();
465 }
466
467 public class InstrumentButton extends JButton {
468 private boolean dragging = false;
469
470 InstrumentButton(String s) {
471 super(s);
472
473 setTransferHandler(new TransferHandler("instrument"));
474
475 addMouseListener(new MouseAdapter() {
476 public void
477 mouseExited(MouseEvent e) {
478 if(!dragging) return;
479
480 int b1 = e.BUTTON1_DOWN_MASK;
481 if((e.getModifiersEx() & b1) != b1) return;
482
483 actInstr.setEnabled(false);
484 doClick(0);
485 actInstr.setEnabled(true);
486
487 JComponent c = (JComponent)e.getSource();
488 TransferHandler handler = c.getTransferHandler();
489 handler.exportAsDrag(c, e, TransferHandler.COPY);
490 }
491
492 public void
493 mouseReleased(MouseEvent e) { dragging = false; }
494 });
495
496 addMouseMotionListener(new MouseMotionAdapter() {
497 public void
498 mouseDragged(MouseEvent e) { dragging = true; }
499 });
500 }
501
502 public String
503 getInstrument() {
504 SamplerChannel sc = Channel.this.getChannelInfo();
505
506 if(sc.getInstrumentName() == null || sc.getInstrumentStatus() < 0)
507 return null;
508
509 Instrument instr = new Instrument();
510 instr.setName(sc.getInstrumentName());
511 instr.setInstrumentIndex(sc.getInstrumentIndex());
512 instr.setPath(sc.getInstrumentFile());
513 return instr.getDnDString();
514 }
515
516 public void setInstrument(String instr) {
517 if(!Instrument.isDnDString(instr)) return;
518
519 String[] args = instr.split("\n");
520 if(args.length < 6) return;
521
522 try {
523 int idx = Integer.parseInt(args[5]);
524 Channel.this.getModel().loadBackendInstrument(args[4], idx);
525 } catch(Exception x) {
526 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
527 }
528 }
529 }
530
531 private final EventHandler eventHandler = new EventHandler();
532
533 private EventHandler
534 getHandler() { return eventHandler; }
535
536 private class EventHandler extends MouseAdapter implements SamplerChannelListener,
537 PropertyChangeListener, HierarchyListener {
538 /**
539 * Invoked when changes are made to a sampler channel.
540 * @param e A <code>SamplerChannelEvent</code> instance
541 * containing event information.
542 */
543 public void
544 channelChanged(SamplerChannelEvent e) { updateChannelInfo(); }
545
546 /**
547 * Invoked when the number of active disk streams has changed.
548 * @param e A <code>SamplerChannelEvent</code> instance
549 * containing event information.
550 */
551 public void
552 streamCountChanged(SamplerChannelEvent e) {
553 updateStreamCount(getModel().getStreamCount());
554 }
555
556 /**
557 * Invoked when the number of active voices has changed.
558 * @param e A <code>SamplerChannelEvent</code> instance
559 * containing event information.
560 */
561 public void
562 voiceCountChanged(SamplerChannelEvent e) {
563 updateVoiceCount(getModel().getVoiceCount());
564 }
565
566 public void
567 propertyChange(PropertyChangeEvent e) {
568 if (
569 e.getPropertyName() == "borderColor" ||
570 e.getPropertyName() == "borderHighlightedColor" ||
571 e.getPropertyName() == "selectedChannelBgColor" ||
572 e.getPropertyName() == "highlightedChannelBgColor"
573 ) {
574 updateColors(isSelected());
575 }
576 }
577
578 public void
579 mouseEntered(MouseEvent e) {
580 mouseOver = true;
581 updateColors(isSelected());
582 }
583
584 public void
585 mouseExited(MouseEvent e) {
586 if(getMousePosition(true) != null) return;
587
588 mouseOver = false;
589 updateColors(isSelected());
590 }
591
592
593
594 /** Called when the hierarchy has been changed. */
595 public void
596 hierarchyChanged(HierarchyEvent e) {
597 if((e.getChangeFlags() & e.SHOWING_CHANGED) == e.SHOWING_CHANGED) {
598 if(getMousePosition() == null) mouseExited(null);
599 else mouseEntered(null);
600 }
601 }
602 }
603
604 /**
605 * Determines whether the channel is selected.
606 * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
607 */
608 public boolean isSelected() { return selected; }
609
610 /**
611 * Sets the selection state of this channel.
612 * This method is invoked when the selection state of the channel has changed.
613 * @param select Specifies the new selection state of this channel;
614 * <code>true</code> to select the channel, <code>false</code> otherwise.
615 */
616 public void
617 setSelected(boolean select) {
618 updateColors(select);
619
620 selected = select;
621 }
622
623 /**
624 * Updates the channel background and border colors.
625 * @param selected Specifies the selection state of this channel.
626 */
627 private void
628 updateColors(boolean selected) {
629 if(selected) {
630 mainPane.setBorder(borderSelected);
631 mainPane.setBackground(chnSelectedColor);
632 } else {
633 if(mouseOver) {
634 mainPane.setBorder(borderHighlighted);
635 mainPane.setBackground(chnHighlightedColor);
636 } else {
637 mainPane.setBorder(borderDeselected);
638 mainPane.setBackground(chnColor);
639 }
640 }
641 }
642
643 /** Hides the channel properties. */
644 public void
645 collapseChannel() { if(btnProperties.isSelected()) btnProperties.doClick(); }
646
647 /** Shows the channel properties. */
648 public void
649 expandChannel() { if(!btnProperties.isSelected()) btnProperties.doClick(); }
650
651 /**
652 * Updates the channel settings. This method is invoked when changes to the
653 * channel were made.
654 */
655 private void
656 updateChannelInfo() {
657 SamplerChannel sc = getChannelInfo();
658
659 int status = sc.getInstrumentStatus();
660 if(status >= 0 && status < 100) {
661 btnInstr.setText(i18n.getLabel("Channel.loadingInstrument", status));
662 } else if(status == -1) {
663 btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
664 } else if(status < -1) {
665 btnInstr.setText(i18n.getLabel("Channel.errorLoadingInstrument"));
666 } else {
667 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
668 else btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
669 }
670
671 updateMuteIcon(sc);
672
673 if(sc.isSoloChannel()) btnSolo.setIcon(iconSoloOn);
674 else btnSolo.setIcon(iconSoloOff);
675
676 slVolume.setValue((int)(sc.getVolume() * 100));
677
678 boolean b = sc.getEngine() != null;
679 slVolume.setEnabled(b);
680 btnSolo.setEnabled(b);
681 btnMute.setEnabled(b);
682 }
683
684 /** Invoked when the user clicks the mute button. */
685 private void
686 changeMute() {
687 SamplerChannel sc = getChannelInfo();
688 boolean b = true;
689
690 /*
691 * Changing the mute button icon now instead of
692 * leaving the work to the notification mechanism of the LinuxSampler.
693 */
694 if(sc.isMuted() && !sc.isMutedBySolo()) {
695 b = false;
696 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
697
698 if(sc.isSoloChannel() || !hasSolo) btnMute.setIcon(iconMuteOff);
699 else btnMute.setIcon(iconMutedBySolo);
700 } else btnMute.setIcon(iconMuteOn);
701
702 getModel().setBackendMute(b);
703 }
704
705 /** Invoked when the user clicks the solo button. */
706 private void
707 changeSolo() {
708 SamplerChannel sc = getChannelInfo();
709 boolean b = !sc.isSoloChannel();
710
711 /*
712 * Changing the solo button icon (and related) now instead of
713 * leaving the work to the notification mechanism of the LinuxSampler.
714 */
715 if(b) {
716 btnSolo.setIcon(iconSoloOn);
717 if(sc.isMutedBySolo()) btnMute.setIcon(iconMuteOff);
718 } else {
719 btnSolo.setIcon(iconSoloOff);
720 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
721 btnMute.setIcon(iconMutedBySolo);
722 }
723
724 getModel().setBackendSolo(b);
725 }
726
727 /** Invoked when the user changes the volume */
728 private void
729 setVolume() {
730 updateVolume();
731
732 if(slVolume.getValueIsAdjusting()) return;
733
734 int vol = (int)(getChannelInfo().getVolume() * 100);
735
736 if(vol == slVolume.getValue()) return;
737
738 /*
739 * If the model's volume is not equal to the slider
740 * value we assume that the change is due to user input.
741 * So we must update the volume at the backend too.
742 */
743 float volume = slVolume.getValue();
744 volume /= 100;
745 getModel().setBackendVolume(volume);
746 }
747
748 private void
749 updateVolume() {
750 int volume = slVolume.getValue();
751 slVolume.setToolTipText(i18n.getLabel("Channel.volume", volume));
752 lVolImg.setToolTipText(i18n.getLabel("Channel.volume", volume));
753
754 setVolumeLabel(volume);
755
756
757 }
758
759 private void
760 setVolumeLabel(int volume) {
761 Dimension d = lVolume.getPreferredSize();
762 lVolume.setText(String.valueOf(volume) + '%');
763 d = JuifeUtils.getUnionSize(d, lVolume.getPreferredSize());
764 lVolume.setMinimumSize(d);
765 lVolume.setPreferredSize(d);
766 lVolume.setMaximumSize(d);
767 }
768
769 /**
770 * Updates the mute button with the proper icon regarding to information obtained
771 * from <code>channel</code>.
772 * @param channel A <code>SamplerChannel</code> instance containing the new settings
773 * for this channel.
774 */
775 private void
776 updateMuteIcon(SamplerChannel channel) {
777 if(channel.isMutedBySolo()) btnMute.setIcon(iconMutedBySolo);
778 else if(channel.isMuted()) btnMute.setIcon(iconMuteOn);
779 else btnMute.setIcon(iconMuteOff);
780 }
781
782 /**
783 * Updates the number of active disk streams.
784 * @param count The new number of active disk streams.
785 */
786 private void
787 updateStreamCount(int count) {
788 Dimension d = lStreams.getPreferredSize();
789 lStreams.setText(count == 0 ? "--" : String.valueOf(count));
790 d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());
791 lStreams.setMinimumSize(d);
792 lStreams.setPreferredSize(d);
793 lStreams.setMaximumSize(d);
794 }
795
796 /**
797 * Updates the number of active voices.
798 * @param count The new number of active voices.
799 */
800 private void
801 updateVoiceCount(int count) {
802 Dimension d = lVoices.getPreferredSize();
803 lVoices.setText(count == 0 ? "--" : String.valueOf(count));
804 d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());
805 lVoices.setMinimumSize(d);
806 lVoices.setPreferredSize(d);
807 lVoices.setMaximumSize(d);
808 }
809
810 private void
811 showProperties(boolean show) {propertiesPane.setVisible(show); }
812
813 private void
814 loadInstrument() {
815 InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());
816 dlg.setVisible(true);
817
818 if(!dlg.isCancelled()) {
819 int idx = dlg.getInstrumentIndex();
820 getModel().loadBackendInstrument(dlg.getFileName(), idx);
821 }
822 }
823 }
824
825 class ChannelProperties extends JPanel {
826 private final JLabel lMidiDevice =
827 new JLabel(i18n.getLabel("ChannelProperties.lMidiDevice"));
828 private final JLabel lMidiPort =
829 new JLabel(i18n.getLabel("ChannelProperties.lMidiPort"));
830 private final JLabel lMidiChannel =
831 new JLabel(i18n.getLabel("ChannelProperties.lMidiChannel"));
832
833 private final JLabel lInstrumentMap =
834 new JLabel(i18n.getLabel("ChannelProperties.lInstrumentMap"));
835
836 private final JLabel lAudioDevice =
837 new JLabel(i18n.getLabel("ChannelProperties.lAudioDevice"));
838
839 private final JComboBox cbEngines = new JComboBox();
840
841 private final JComboBox cbInstrumentMap = new JComboBox();
842 private final JComboBox cbMidiDevice = new JComboBox();
843 private final JComboBox cbMidiPort = new JComboBox();
844 private final JComboBox cbMidiChannel = new JComboBox();
845 private final JComboBox cbAudioDevice = new JComboBox();
846
847 private final JButton btnFxSends = new JButton(Res.iconFxSends22);
848 private final JButton btnAudioProps = new JButton(Res.iconAudioProps16);
849 private InformationDialog fxSendsDlg = null;
850
851 private SamplerChannelModel channelModel = null;
852
853 private boolean update = false;
854
855 private class NoMap {
856 public String
857 toString() { return "[None]"; }
858 }
859
860 private NoMap noMap = new NoMap();
861
862 private class DefaultMap {
863 public String
864 toString() { return "[Default]"; }
865 }
866
867 private DefaultMap defaultMap = new DefaultMap();
868
869 /**
870 * Creates a new instance of <code>ChannelProperties</code> using the specified non-null
871 * channel model.
872 * @param model The model to be used by this channel properties pane.
873 */
874 ChannelProperties(SamplerChannelModel model) {
875 channelModel = model;
876
877 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
878 setOpaque(false);
879
880 add(new JSeparator());
881
882 JPanel enginesPane = createEnginePane();
883
884 JPanel devicesPane = new JPanel();
885 devicesPane.setOpaque(false);
886 devicesPane.setLayout(new BoxLayout(devicesPane, BoxLayout.X_AXIS));
887
888 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
889
890 devicesPane.add(createMidiPane());
891
892 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
893
894 devicesPane.add(enginesPane);
895
896 devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
897
898 JPanel audioPane = createAudioPane();
899 Dimension d = audioPane.getPreferredSize();
900 d.height = Short.MAX_VALUE;
901
902 audioPane.setMaximumSize(d);
903 devicesPane.add(audioPane);
904
905 add(devicesPane);
906 add(Box.createRigidArea(new Dimension(0, 6)));
907
908 add(new JSeparator());
909
910 cbMidiChannel.addItem("All");
911 for(int i = 1; i <= 16; i++) cbMidiChannel.addItem(String.valueOf(i));
912
913 cbMidiDevice.addActionListener(new ActionListener() {
914 public void
915 actionPerformed(ActionEvent e) { setMidiDevice(); }
916 });
917
918 cbMidiPort.addActionListener(new ActionListener() {
919 public void
920 actionPerformed(ActionEvent e) { setMidiPort(); }
921 });
922
923 cbMidiChannel.addActionListener(new ActionListener() {
924 public void
925 actionPerformed(ActionEvent e) { setMidiChannel(); }
926 });
927
928 cbEngines.addActionListener(new ActionListener() {
929 public void
930 actionPerformed(ActionEvent e) { setEngineType(); }
931 });
932
933 cbAudioDevice.addActionListener(new ActionListener() {
934 public void
935 actionPerformed(ActionEvent e) { setAudioDevice(); }
936 });
937
938 getModel().addSamplerChannelListener(new SamplerChannelAdapter() {
939 public void
940 channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }
941 });
942
943 CC.getSamplerModel().addSamplerListener(new SamplerAdapter() {
944 /** Invoked when the default MIDI instrument map is changed. */
945 public void
946 defaultMapChanged(SamplerEvent e) {
947 updateCbInstrumentMapToolTipText();
948
949 }
950 });
951
952 cbInstrumentMap.addItem(noMap);
953 cbInstrumentMap.addItem(defaultMap);
954 for(MidiInstrumentMap map : CC.getSamplerModel().getMidiInstrumentMaps()) {
955 cbInstrumentMap.addItem(map);
956 }
957
958 int map = getModel().getChannelInfo().getMidiInstrumentMapId();
959 cbInstrumentMap.setSelectedItem(CC.getSamplerModel().getMidiInstrumentMapById(map));
960 if(cbInstrumentMap.getSelectedItem() == null) {
961 if(map == -1) cbInstrumentMap.setSelectedItem(noMap);
962 else if(map == -2) {
963 cbInstrumentMap.setSelectedItem(defaultMap);
964 }
965 }
966
967 updateCbInstrumentMapToolTipText();
968
969 if(getModel().getChannelInfo().getEngine() == null) {
970 cbInstrumentMap.setEnabled(false);
971 }
972
973 cbInstrumentMap.addActionListener(new ActionListener() {
974 public void
975 actionPerformed(ActionEvent e) { updateInstrumentMap(); }
976 });
977
978 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
979 CC.getSamplerModel().addAudioDeviceListListener(getHandler());
980 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
981
982 CC.getSamplerModel().addMidiInstrumentMapListListener(new MapListListener());
983
984 btnAudioProps.setToolTipText(i18n.getLabel("ChannelProperties.routing"));
985 btnAudioProps.addActionListener(new ActionListener() {
986 public void
987 actionPerformed(ActionEvent e) {
988 SamplerChannel c = getModel().getChannelInfo();
989 new ChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
990
991 }
992 });
993
994 btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelProperties.btnFxSends"));
995 btnFxSends.addActionListener(new ActionListener() {
996 public void
997 actionPerformed(ActionEvent e) {
998 if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
999 fxSendsDlg.toFront();
1000 return;
1001 }
1002
1003 FxSendsPane p = new FxSendsPane(getModel());
1004 int id = getModel().getChannelId();
1005 fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
1006 fxSendsDlg.setTitle(i18n.getLabel("FxSendsPane.title", id));
1007 fxSendsDlg.setModal(false);
1008 fxSendsDlg.showCloseButton(false);
1009 fxSendsDlg.setVisible(true);
1010 }
1011 });
1012
1013 updateMidiDevices();
1014 updateAudioDevices();
1015 updateChannelProperties();
1016 }
1017
1018 private JPanel
1019 createEnginePane() {
1020 for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngines.addItem(e);
1021
1022 cbEngines.setMaximumSize(cbEngines.getPreferredSize());
1023
1024 JPanel p = new JPanel();
1025 p.setOpaque(false);
1026 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
1027 p.add(cbEngines);
1028 p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
1029
1030 //enginesPane.add(Box.createGlue());
1031 JPanel enginesPane = new JPanel();
1032 enginesPane.setOpaque(false);
1033 enginesPane.setLayout(new BorderLayout());
1034 enginesPane.add(p, BorderLayout.SOUTH);
1035 //enginesPane.add(Box.createRigidArea(new Dimension(0, 3)));
1036
1037 String s = i18n.getLabel("ChannelProperties.enginesPane");
1038 enginesPane.setBorder(BorderFactory.createTitledBorder(s));
1039 Dimension d = new Dimension(enginesPane.getPreferredSize().width, Short.MAX_VALUE);
1040 enginesPane.setMaximumSize(d);
1041 return enginesPane;
1042 }
1043
1044 private JPanel
1045 createMidiPane() {
1046 JPanel midiPane = new JPanel();
1047 midiPane.setOpaque(false);
1048
1049 GridBagLayout gridbag = new GridBagLayout();
1050 GridBagConstraints c = new GridBagConstraints();
1051
1052 midiPane.setLayout(gridbag);
1053
1054 c.gridx = 1;
1055 c.gridy = 0;
1056 c.insets = new Insets(0, 3, 3, 3);
1057 gridbag.setConstraints(lMidiDevice, c);
1058 midiPane.add(lMidiDevice);
1059
1060 c.gridx = 2;
1061 c.gridy = 0;
1062 gridbag.setConstraints(lMidiPort, c);
1063 midiPane.add(lMidiPort);
1064
1065 c.gridx = 3;
1066 c.gridy = 0;
1067 gridbag.setConstraints(lMidiChannel, c);
1068 midiPane.add(lMidiChannel);
1069
1070 c.gridx = 4;
1071 c.gridy = 0;
1072 c.insets = new Insets(0, 10, 3, 3);
1073 gridbag.setConstraints(lInstrumentMap, c);
1074 midiPane.add(lInstrumentMap);
1075
1076 btnFxSends.setMargin(new Insets(0, 0, 0, 0));
1077 c.gridx = 0;
1078 c.gridy = 0;
1079 c.gridheight = 2;
1080 c.insets = new Insets(0, 5, 0, 8);
1081 gridbag.setConstraints(btnFxSends, c);
1082 midiPane.add(btnFxSends);
1083
1084 c.gridx = 1;
1085 c.gridy = 1;
1086 c.gridheight = 1;
1087 c.insets = new Insets(0, 4, 4, 3);
1088 c.fill = GridBagConstraints.HORIZONTAL;
1089 gridbag.setConstraints(cbMidiDevice, c);
1090 midiPane.add(cbMidiDevice);
1091
1092 c.gridx = 3;
1093 c.gridy = 1;
1094 gridbag.setConstraints(cbMidiChannel, c);
1095 midiPane.add(cbMidiChannel);
1096
1097 c.gridx = 2;
1098 c.gridy = 1;
1099 gridbag.setConstraints(cbMidiPort, c);
1100 midiPane.add(cbMidiPort);
1101
1102 c.gridx = 4;
1103 c.gridy = 1;
1104 c.weightx = 1.0;
1105 c.insets = new Insets(0, 10, 3, 3);
1106 gridbag.setConstraints(cbInstrumentMap, c);
1107 midiPane.add(cbInstrumentMap);
1108
1109 String s = i18n.getLabel("ChannelProperties.midiPane");
1110 TitledBorder border = BorderFactory.createTitledBorder(s);
1111 //border.setTitlePosition(border.TOP);
1112 midiPane.setBorder(border);
1113 return midiPane;
1114 }
1115
1116 private JPanel
1117 createAudioPane() {
1118 JPanel audioPane = new JPanel();
1119 audioPane.setOpaque(false);
1120
1121 GridBagLayout gridbag = new GridBagLayout();
1122 GridBagConstraints c = new GridBagConstraints();
1123
1124 audioPane.setLayout(gridbag);
1125
1126 c.gridx = 0;
1127 c.gridy = 0;
1128 c.insets = new Insets(0, 3, 3, 3);
1129 gridbag.setConstraints(lAudioDevice, c);
1130 audioPane.add(lAudioDevice);
1131
1132 c.gridx = 0;
1133 c.gridy = 1;
1134 c.fill = GridBagConstraints.HORIZONTAL;
1135 gridbag.setConstraints(cbAudioDevice, c);
1136 audioPane.add(cbAudioDevice);
1137
1138 btnAudioProps.setMargin(new Insets(0, 0, 0, 0));
1139 c.gridx = 1;
1140 c.gridy = 1;
1141 c.fill = GridBagConstraints.NONE;
1142 gridbag.setConstraints(btnAudioProps, c);
1143 audioPane.add(btnAudioProps);
1144
1145 String s = i18n.getLabel("ChannelProperties.audioPane");
1146 audioPane.setBorder(BorderFactory.createTitledBorder(s));
1147
1148 return audioPane;
1149 }
1150
1151 /**
1152 * Gets the model that is currently used by this channel properties pane.
1153 * @return model The <code>SamplerChannelModel</code> instance
1154 * that provides information about the channel whose settings are
1155 * represented by this channel properties pane.
1156 */
1157 public SamplerChannelModel
1158 getModel() { return channelModel; }
1159
1160
1161 private void
1162 updateInstrumentMap() {
1163 updateCbInstrumentMapToolTipText();
1164
1165 int id = getModel().getChannelInfo().getMidiInstrumentMapId();
1166 Object o = cbInstrumentMap.getSelectedItem();
1167 if(o == null && id == -1) return;
1168
1169 int cbId;
1170 if(o == null || o == noMap) cbId = -1;
1171 else if(o == defaultMap) cbId = -2;
1172 else cbId = ((MidiInstrumentMap)o).getMapId();
1173
1174 if(cbId == id) return;
1175
1176 channelModel.setBackendMidiInstrumentMap(cbId);
1177 }
1178
1179 private void
1180 updateCbInstrumentMapToolTipText() {
1181 if(cbInstrumentMap.getSelectedItem() != defaultMap) {
1182 cbInstrumentMap.setToolTipText(null);
1183 return;
1184 }
1185
1186 MidiInstrumentMap m = CC.getSamplerModel().getDefaultMidiInstrumentMap();
1187 if(m != null) {
1188 String s = i18n.getLabel("Channel.ttDefault", m.getName());
1189 cbInstrumentMap.setToolTipText(s);
1190 } else {
1191 cbInstrumentMap.setToolTipText(null);
1192 }
1193 }
1194
1195 /**
1196 * Updates the channel settings. This method is invoked when changes to the
1197 * channel were made.
1198 */
1199 private void
1200 updateChannelProperties() {
1201 SamplerModel sm = CC.getSamplerModel();
1202 SamplerChannel sc = getModel().getChannelInfo();
1203
1204 MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
1205 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
1206
1207 if(isUpdate()) CC.getLogger().warning("Unexpected update state!");
1208
1209 setUpdate(true);
1210
1211 try {
1212 cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1213
1214 cbEngines.setSelectedItem(sc.getEngine());
1215
1216 cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1217 } catch(Exception x) {
1218 CC.getLogger().log(Level.WARNING, "Unkown error", x);
1219 }
1220
1221 if(sc.getEngine() != null) {
1222 if(cbInstrumentMap.getItemCount() > 0) cbInstrumentMap.setEnabled(true);
1223 } else {
1224 cbInstrumentMap.setSelectedItem(noMap);
1225 cbInstrumentMap.setEnabled(false);
1226 }
1227
1228 setUpdate(false);
1229 }
1230
1231 /**
1232 * Updates the MIDI device list.
1233 */
1234 private void
1235 updateMidiDevices() {
1236 SamplerModel sm = CC.getSamplerModel();
1237 SamplerChannel sc = getModel().getChannelInfo();
1238
1239 setUpdate(true);
1240
1241 try {
1242 cbMidiDevice.removeAllItems();
1243
1244 for(MidiDeviceModel m : sm.getMidiDeviceModels())
1245 cbMidiDevice.addItem(m.getDeviceInfo());
1246
1247 MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
1248 cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1249 } catch(Exception x) {
1250 CC.getLogger().log(Level.WARNING, "Unkown error", x);
1251 }
1252
1253 setUpdate(false);
1254 }
1255
1256 /**
1257 * Updates the audio device list.
1258 */
1259 private void
1260 updateAudioDevices() {
1261 SamplerModel sm = CC.getSamplerModel();
1262 SamplerChannel sc = getModel().getChannelInfo();
1263
1264 setUpdate(true);
1265
1266 try {
1267 cbAudioDevice.removeAllItems();
1268
1269 for(AudioDeviceModel m : sm.getAudioDeviceModels())
1270 cbAudioDevice.addItem(m.getDeviceInfo());
1271
1272 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
1273 cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1274 } catch(Exception x) {
1275 CC.getLogger().log(Level.WARNING, "Unkown error", x);
1276 }
1277
1278 setUpdate(false);
1279 }
1280
1281 private void
1282 setMidiDevice() {
1283 MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();
1284
1285 if(!isUpdate()) {
1286 if(mid != null) getModel().setBackendMidiInputDevice(mid.getDeviceId());
1287 return;
1288 }
1289
1290 cbMidiPort.removeAllItems();
1291
1292 if(mid == null) {
1293 cbMidiPort.setEnabled(false);
1294
1295 cbMidiChannel.setSelectedItem(null);
1296 cbMidiChannel.setEnabled(false);
1297 } else {
1298 cbMidiPort.setEnabled(true);
1299
1300 MidiPort[] ports = mid.getMidiPorts();
1301 for(MidiPort port : ports) cbMidiPort.addItem(port);
1302
1303 int p = getModel().getChannelInfo().getMidiInputPort();
1304 cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);
1305
1306 cbMidiChannel.setEnabled(true);
1307 int c = getModel().getChannelInfo().getMidiInputChannel();
1308 cbMidiChannel.setSelectedItem(c == -1 ? "All" : String.valueOf(c + 1));
1309 }
1310
1311
1312 }
1313
1314 private void
1315 setMidiPort() {
1316 if(isUpdate()) return;
1317
1318 getModel().setBackendMidiInputPort(cbMidiPort.getSelectedIndex());
1319 }
1320
1321 private void
1322 setMidiChannel() {
1323 if(isUpdate()) return;
1324
1325 Object o = cbMidiChannel.getSelectedItem();
1326 if(o == null) return;
1327
1328 int c = o.toString().equals("All") ? -1 : Integer.parseInt(o.toString()) - 1;
1329
1330 getModel().setBackendMidiInputChannel(c);
1331 }
1332
1333 /** Invoked when the user selects an engine. */
1334 private void
1335 setEngineType() {
1336 Object oldEngine = getModel().getChannelInfo().getEngine();
1337 SamplerEngine newEngine = (SamplerEngine)cbEngines.getSelectedItem();
1338
1339 if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }
1340 else if(newEngine == null) return;
1341
1342 getModel().setBackendEngineType(newEngine.getName());
1343
1344 }
1345
1346 private void
1347 setAudioDevice() {
1348 if(isUpdate()) return;
1349 AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();
1350 if(dev != null) getModel().setBackendAudioOutputDevice(dev.getDeviceId());
1351 }
1352
1353 /**
1354 * Determines whether the currently processed changes are due to update.
1355 * @return <code>true</code> if the currently processed changes are due to update and
1356 * <code>false</code> if the currently processed changes are due to user input.
1357 */
1358 private boolean
1359 isUpdate() { return update; }
1360
1361 /**
1362 * Sets whether the currently processed changes are due to update.
1363 * @param b Specify <code>true</code> to indicate that the currently
1364 * processed changes are due to update; <code>false</code>
1365 * indicates that the currently processed changes are due to user input.
1366 */
1367 private void
1368 setUpdate(boolean b) { update = b; }
1369
1370 private final Handler handler = new Handler();
1371
1372 private Handler
1373 getHandler() { return handler; }
1374
1375 private class Handler implements MidiDeviceListListener,
1376 ListListener<AudioDeviceModel>, SamplerChannelListListener {
1377
1378 /**
1379 * Invoked when a new MIDI device is created.
1380 * @param e A <code>MidiDeviceListEvent</code>
1381 * instance providing the event information.
1382 */
1383 public void
1384 deviceAdded(MidiDeviceListEvent e) {
1385 cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());
1386 }
1387
1388 /**
1389 * Invoked when a MIDI device is removed.
1390 * @param e A <code>MidiDeviceListEvent</code>
1391 * instance providing the event information.
1392 */
1393 public void
1394 deviceRemoved(MidiDeviceListEvent e) {
1395 cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());
1396 }
1397
1398 /**
1399 * Invoked when a new audio device is created.
1400 * @param e An <code>AudioDeviceListEvent</code>
1401 * instance providing the event information.
1402 */
1403 public void
1404 entryAdded(ListEvent<AudioDeviceModel> e) {
1405 cbAudioDevice.addItem(e.getEntry().getDeviceInfo());
1406 }
1407
1408 /**
1409 * Invoked when an audio device is removed.
1410 * @param e An <code>AudioDeviceListEvent</code>
1411 * instance providing the event information.
1412 */
1413 public void
1414 entryRemoved(ListEvent<AudioDeviceModel> e) {
1415 cbAudioDevice.removeItem(e.getEntry().getDeviceInfo());
1416 }
1417
1418 /**
1419 * Invoked when a new sampler channel is created.
1420 * @param e A <code>SamplerChannelListEvent</code>
1421 * instance providing the event information.
1422 */
1423 public void
1424 channelAdded(SamplerChannelListEvent e) { }
1425
1426 /**
1427 * Invoked when a sampler channel is removed.
1428 * @param e A <code>SamplerChannelListEvent</code>
1429 * instance providing the event information.
1430 */
1431 public void
1432 channelRemoved(SamplerChannelListEvent e) {
1433 // Some cleanup when the channel is removed.
1434 if(e.getChannelModel().getChannelId() == channelModel.getChannelId()) {
1435 CC.getSamplerModel().removeMidiDeviceListListener(getHandler());
1436 CC.getSamplerModel().removeAudioDeviceListListener(getHandler());
1437 }
1438 }
1439 }
1440
1441 private class MapListListener implements ListListener<MidiInstrumentMap> {
1442 /** Invoked when a new MIDI instrument map is added to a list. */
1443 public void
1444 entryAdded(ListEvent<MidiInstrumentMap> e) {
1445 //cbInstrumentMap.addItem(e.getEntry());
1446 cbInstrumentMap.insertItemAt(e.getEntry(), cbInstrumentMap.getItemCount());
1447 boolean b = getModel().getChannelInfo().getEngine() != null;
1448 if(b && !cbInstrumentMap.isEnabled()) cbInstrumentMap.setEnabled(true);
1449 }
1450
1451 /** Invoked when a new MIDI instrument map is removed from a list. */
1452 public void
1453 entryRemoved(ListEvent<MidiInstrumentMap> e) {
1454 cbInstrumentMap.removeItem(e.getEntry());
1455 if(cbInstrumentMap.getItemCount() == 0) {
1456 cbInstrumentMap.setSelectedItem(noMap);
1457 cbInstrumentMap.setEnabled(false);
1458 }
1459 }
1460 }
1461 }

  ViewVC Help
Powered by ViewVC