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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2288 - (hide annotations) (download)
Wed Nov 23 21:19:44 2011 UTC (12 years, 5 months ago) by iliev
File size: 17008 byte(s)
* Added option to select a sampler engine in Add/Edit Instrument dialog
* Moved all Swing dependent code outside the JSampler core

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 2192 * Copyright (C) 2005-2011 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 787 *
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.Dimension;
27     import java.awt.MediaTracker;
28    
29     import java.awt.event.ActionEvent;
30     import java.awt.event.ActionListener;
31    
32     import java.net.URL;
33    
34     import java.util.logging.Level;
35    
36     import javax.swing.AbstractAction;
37     import javax.swing.Action;
38     import javax.swing.BorderFactory;
39     import javax.swing.Box;
40     import javax.swing.BoxLayout;
41     import javax.swing.ImageIcon;
42     import javax.swing.JComboBox;
43     import javax.swing.JOptionPane;
44     import javax.swing.JLabel;
45     import javax.swing.JPanel;
46     import javax.swing.JScrollPane;
47     import javax.swing.JSplitPane;
48     import javax.swing.JTable;
49     import javax.swing.JToolBar;
50     import javax.swing.ListSelectionModel;
51    
52     import javax.swing.event.ListSelectionEvent;
53     import javax.swing.event.ListSelectionListener;
54    
55     import javax.swing.table.AbstractTableModel;
56     import javax.swing.table.TableColumn;
57    
58 iliev 2288 import net.sf.juife.swing.InformationDialog;
59     import net.sf.juife.swing.JuifeUtils;
60     import net.sf.juife.swing.NavigationPage;
61 iliev 787
62 iliev 842 import org.jsampler.AudioDeviceModel;
63 iliev 787 import org.jsampler.CC;
64 iliev 842 import org.jsampler.HF;
65 iliev 787
66 iliev 2192 import org.jsampler.event.AudioDeviceAdapter;
67 iliev 787 import org.jsampler.event.AudioDeviceEvent;
68 iliev 1143 import org.jsampler.event.ListEvent;
69     import org.jsampler.event.ListListener;
70 iliev 787 import org.jsampler.event.ParameterEvent;
71     import org.jsampler.event.ParameterListener;
72    
73 iliev 2288 import org.jsampler.view.swing.NumberCellEditor;
74     import org.jsampler.view.swing.ParameterTable;
75     import org.jsampler.view.swing.SHF;
76 iliev 787
77     import org.linuxsampler.lscp.AudioOutputChannel;
78     import org.linuxsampler.lscp.AudioOutputDevice;
79     import org.linuxsampler.lscp.Parameter;
80    
81     import static org.jsampler.view.classic.ClassicI18n.i18n;
82     import static org.jsampler.view.classic.AudioDevicesTableModel.*;
83    
84    
85     /**
86     *
87     * @author Grigor Iliev
88     */
89     public class AudioDevicesPage extends NavigationPage {
90     private final Action duplicateAudioDevice = new DuplicateAudioDevice();
91     private final Action removeAudioDevice = new RemoveAudioDevice();
92     private final Action audioDeviceProps = new AudioDeviceProps();
93    
94     private final ToolbarButton btnNewDevice = new ToolbarButton(A4n.addAudioDevice);
95     private final ToolbarButton btnDuplicateDevice = new ToolbarButton(duplicateAudioDevice);
96     private final ToolbarButton btnRemoveDevice = new ToolbarButton(removeAudioDevice);
97     private final ToolbarButton btnDeviceProps = new ToolbarButton(audioDeviceProps);
98    
99     private final JTable devicesTable = new JTable(new AudioDevicesTableModel());
100    
101     private final JLabel lChannels = new JLabel(i18n.getLabel("AudioDevicesPage.lChannels"));
102     private final JComboBox cbChannels = new JComboBox();
103    
104     ParameterTable channelParamTable = new ParameterTable();
105    
106    
107     /** Creates a new instance of <code>AudioDevicesPage</code> */
108     public
109     AudioDevicesPage() {
110     setTitle(i18n.getLabel("AudioDevicesPage.title"));
111    
112     cbChannels.setEnabled(false);
113    
114     TableColumn tc = devicesTable.getColumnModel().getColumn(ACTIVE_COLUMN_INDEX);
115     tc.setPreferredWidth(tc.getMinWidth());
116    
117     NumberCellEditor nce = new NumberCellEditor();
118     nce.setMinimum(0);
119     nce.setMaximum(255);
120     tc = devicesTable.getColumnModel().getColumn(CHANNELS_COLUMN_INDEX);
121     tc.setCellEditor(nce);
122    
123     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
124    
125     JToolBar tb = new JToolBar();
126     tb.setMaximumSize(new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height));
127     tb.setFloatable(false);
128     tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
129    
130 iliev 1143 tb.add(Box.createRigidArea(new Dimension(3, 0)));
131     tb.add(new JLabel(Res.iconVol24));
132     tb.add(Box.createRigidArea(new Dimension(3, 0)));
133 iliev 787 tb.add(btnNewDevice);
134     tb.add(btnDuplicateDevice);
135     tb.add(btnRemoveDevice);
136     tb.addSeparator();
137     tb.add(btnDeviceProps);
138    
139     add(tb);
140    
141     JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
142 iliev 1143 splitPane.setContinuousLayout(true);
143 iliev 787
144     devicesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
145     JScrollPane sp = new JScrollPane(devicesTable);
146    
147 iliev 911 Dimension d;
148     d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
149     sp.setPreferredSize(d);
150    
151 iliev 787 JPanel p = new JPanel();
152     p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
153     p.add(sp);
154     p.add(Box.createRigidArea(new Dimension(0, 8)));
155    
156     splitPane.setTopComponent(p);
157    
158     JPanel channelsPane = new JPanel();
159     channelsPane.setLayout(new BoxLayout(channelsPane, BoxLayout.Y_AXIS));
160    
161     p = new JPanel();
162     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
163     p.add(lChannels);
164     p.add(Box.createRigidArea(new Dimension(5, 0)));
165     p.add(cbChannels);
166     p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
167     channelsPane.add(p);
168    
169 iliev 911 sp = new JScrollPane(channelParamTable);
170     d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
171     sp.setPreferredSize(d);
172    
173 iliev 787 p = new JPanel();
174     p.setLayout(new BorderLayout());
175     p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
176 iliev 911 p.add(sp);
177 iliev 787 channelsPane.add(p);
178    
179     channelsPane.setBorder (
180     BorderFactory.createTitledBorder(i18n.getLabel("AudioDevicesPage.channels"))
181     );
182    
183     p = new JPanel();
184     p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
185     p.add(Box.createRigidArea(new Dimension(0, 5)));
186     p.add(channelsPane);
187    
188     splitPane.setBottomComponent(p);
189     splitPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
190     splitPane.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
191     splitPane.setDividerSize(3);
192     add(splitPane);
193    
194     splitPane.setDividerLocation(150);
195    
196     cbChannels.addActionListener(getHandler());
197    
198     devicesTable.getSelectionModel().addListSelectionListener(getHandler());
199     channelParamTable.getModel().addParameterListener(getHandler());
200     }
201    
202     private AudioDeviceModel
203     getSelectedAudioDeviceModel() {
204     ListSelectionModel lsm = devicesTable.getSelectionModel();
205     if(lsm.isSelectionEmpty()) return null;
206    
207     return ((AudioDevicesTableModel)devicesTable.getModel()).getAudioDeviceModel (
208     lsm.getMinSelectionIndex()
209     );
210     }
211    
212     private final Handler handler = new Handler();
213    
214     private Handler
215     getHandler() { return handler; }
216    
217 iliev 2192 private class Handler extends AudioDeviceAdapter implements ActionListener,
218     ListSelectionListener, ParameterListener {
219 iliev 787 public void
220     actionPerformed(ActionEvent e) {
221     Object obj = cbChannels.getSelectedItem();
222     if(obj == null) {
223     channelParamTable.getModel().setParameters(new Parameter[0]);
224     return;
225     }
226    
227     AudioOutputChannel c = (AudioOutputChannel)obj;
228    
229     channelParamTable.getModel().setParameters(c.getAllParameters());
230     }
231    
232     public void
233     valueChanged(ListSelectionEvent e) {
234     if(e.getValueIsAdjusting()) return;
235    
236 iliev 1204 for(AudioDeviceModel m : CC.getSamplerModel().getAudioDevices()) {
237 iliev 787 m.removeAudioDeviceListener(this);
238     }
239    
240     ListSelectionModel lsm = (ListSelectionModel)e.getSource();
241    
242     if(lsm.isSelectionEmpty()) {
243     duplicateAudioDevice.setEnabled(false);
244     removeAudioDevice.setEnabled(false);
245     audioDeviceProps.setEnabled(false);
246    
247     cbChannels.removeAllItems();
248     cbChannels.setEnabled(false);
249     return;
250     }
251    
252     duplicateAudioDevice.setEnabled(true);
253     removeAudioDevice.setEnabled(true);
254     audioDeviceProps.setEnabled(true);
255    
256     AudioDeviceModel m;
257     m = ((AudioDevicesTableModel)devicesTable.getModel()).getAudioDeviceModel (
258     lsm.getMinSelectionIndex()
259     );
260    
261     cbChannels.removeAllItems();
262     for(AudioOutputChannel c : m.getDeviceInfo().getAudioChannels()) {
263     cbChannels.addItem(c);
264     }
265     cbChannels.setEnabled(true);
266    
267     m.addAudioDeviceListener(this);
268     }
269    
270     /** Invoked when when the settings of a particular audio device have changed. */
271     public void
272     settingsChanged(AudioDeviceEvent e) {
273     AudioOutputDevice d = e.getAudioDeviceModel().getDeviceInfo();
274    
275     int idx = cbChannels.getSelectedIndex();
276     cbChannels.removeAllItems();
277     for(AudioOutputChannel c : d.getAudioChannels()) cbChannels.addItem(c);
278    
279     if(idx >= cbChannels.getModel().getSize()) idx = 0;
280    
281     if(cbChannels.getModel().getSize() > 0) cbChannels.setSelectedIndex(idx);
282     }
283    
284     /** Invoked when when the value of a particular parameter is changed. */
285     public void
286     parameterChanged(ParameterEvent e) {
287     AudioDeviceModel m = getSelectedAudioDeviceModel();
288     if(m == null) {
289     CC.getLogger().warning("Unexpected null AudioDeviceModel!");
290     return;
291     }
292    
293     int c = cbChannels.getSelectedIndex();
294     if(c == -1) {
295     CC.getLogger().warning("There is no audio channel selected!");
296     return;
297     }
298    
299 iliev 1143 m.setBackendChannelParameter(c, e.getParameter());
300 iliev 787 }
301     }
302    
303     private class DuplicateAudioDevice extends AbstractAction {
304     DuplicateAudioDevice() {
305     super("");
306    
307     putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttDuplicateAudioDevice"));
308    
309     try {
310     URL url = ClassLoader.getSystemClassLoader().getResource (
311     "org/jsampler/view/classic/res/icons/Copy16.gif"
312     );
313    
314     ImageIcon icon = new ImageIcon(url);
315     if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
316     putValue(Action.SMALL_ICON, icon);
317 iliev 842 } catch(Exception x) {
318     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
319     }
320 iliev 787
321     setEnabled(false);
322     }
323    
324     public void
325     actionPerformed(ActionEvent e) {
326     JOptionPane.showMessageDialog (
327 iliev 2288 SHF.getMainFrame(), "Not implemented yet",
328 iliev 787 "",
329     JOptionPane.INFORMATION_MESSAGE
330     );
331    
332     AudioDeviceModel m = getSelectedAudioDeviceModel();
333     if(m == null) {
334     CC.getLogger().warning("No selected audio device to duplicate!");
335     return;
336     }
337    
338    
339     }
340     }
341    
342     private class RemoveAudioDevice extends AbstractAction {
343     RemoveAudioDevice() {
344     super("");
345    
346     putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttRemoveAudioDevice"));
347    
348     try {
349     URL url = ClassLoader.getSystemClassLoader().getResource (
350     "org/jsampler/view/classic/res/icons/Delete16.gif"
351     );
352    
353     ImageIcon icon = new ImageIcon(url);
354     if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
355     putValue(Action.SMALL_ICON, icon);
356 iliev 842 } catch(Exception x) {
357     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
358     }
359 iliev 787
360     setEnabled(false);
361     }
362    
363     public void
364     actionPerformed(ActionEvent e) {
365     AudioDeviceModel m = getSelectedAudioDeviceModel();
366     if(m == null) {
367     CC.getLogger().warning("No selected audio device to remove!");
368     return;
369     }
370    
371 iliev 1143 CC.getSamplerModel().removeBackendAudioDevice(m.getDeviceId());
372 iliev 787 }
373     }
374    
375     private class AudioDeviceProps extends AbstractAction {
376     AudioDeviceProps() {
377     super("");
378    
379     putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttAudioDeviceProps"));
380    
381     try {
382     URL url = ClassLoader.getSystemClassLoader().getResource (
383     "org/jsampler/view/classic/res/icons/Properties16.gif"
384     );
385    
386     ImageIcon icon = new ImageIcon(url);
387     if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
388     putValue(Action.SMALL_ICON, icon);
389 iliev 842 } catch(Exception x) {
390     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
391     }
392 iliev 787
393     setEnabled(false);
394     }
395    
396     public void
397     actionPerformed(ActionEvent e) { new DevicePropsDlg().setVisible(true); }
398     }
399    
400     private class DevicePropsDlg extends InformationDialog {
401     DevicePropsDlg() {
402 iliev 2288 super(SHF.getMainFrame(), i18n.getLabel("AudioDevicesPage.DevicePropsDlg"));
403 iliev 787
404     AudioDeviceModel m = getSelectedAudioDeviceModel();
405     ParameterTable table = new ParameterTable();
406     table.getModel().setParameters (
407     m.getDeviceInfo().getAdditionalParameters()
408     );
409    
410     JScrollPane sp = new JScrollPane(table);
411     sp.setPreferredSize(JuifeUtils.getUnionSize (
412     sp.getMinimumSize(), new Dimension(200, 200)
413     ));
414     setMainPane(sp);
415     }
416     }
417     }
418    
419     class AudioDevicesTableModel extends AbstractTableModel {
420     protected final static int ACTIVE_COLUMN_INDEX = 0;
421     protected final static int DEVICE_ID_COLUMN_INDEX = 1;
422     protected final static int CHANNELS_COLUMN_INDEX = 2;
423    
424     private final String[] columnNames = {
425     "",
426     i18n.getLabel("AudioDevicesTableModel.deviceID"),
427     i18n.getLabel("AudioDevicesTableModel.channels")
428     };
429    
430     private AudioDeviceModel[] deviceList;
431    
432     AudioDevicesTableModel() {
433     CC.getSamplerModel().addAudioDeviceListListener(new Handler());
434 iliev 1204 deviceList = CC.getSamplerModel().getAudioDevices();
435 iliev 787
436     }
437    
438     public AudioDeviceModel
439     getAudioDeviceModel(int index) { return deviceList[index]; }
440    
441     // The Table Model implementation
442    
443     /**
444     * Gets the number of columns in the model.
445     * @return The number of columns in the model.
446     */
447     public int
448     getColumnCount() { return columnNames.length; }
449    
450     /**
451     * Gets the number of rows in the model.
452     * @return The number of rows in the model.
453     */
454     public int
455     getRowCount() { return deviceList.length; }
456    
457     /**
458     * Gets the name of the column at <code>columnIndex</code>.
459     * @return The name of the column at <code>columnIndex</code>.
460     */
461     public String
462     getColumnName(int col) { return columnNames[col]; }
463    
464     /**
465     * Gets the value for the cell at <code>columnIndex</code> and
466     * <code>rowIndex</code>.
467     * @param row The row whose value is to be queried.
468     * @param col The column whose value is to be queried.
469     * @return The value for the cell at <code>columnIndex</code> and
470     * <code>rowIndex</code>.
471     */
472     public Object
473     getValueAt(int row, int col) {
474     switch(col) {
475     case ACTIVE_COLUMN_INDEX:
476     return deviceList[row].getDeviceInfo().isActive();
477     case DEVICE_ID_COLUMN_INDEX:
478 iliev 1143 return deviceList[row].getDeviceId();
479 iliev 787 case CHANNELS_COLUMN_INDEX:
480     return deviceList[row].getDeviceInfo().getChannelCount();
481     }
482    
483     return null;
484     }
485    
486     /**
487     * Sets the value in the cell at <code>columnIndex</code>
488     * and <code>rowIndex</code> to <code>value</code>.
489     */
490     public void
491     setValueAt(Object value, int row, int col) {
492     switch(col) {
493     case ACTIVE_COLUMN_INDEX:
494     boolean active = (Boolean)value;
495     deviceList[row].getDeviceInfo().setActive(active);
496 iliev 1143 deviceList[row].setBackendActive(active);
497 iliev 787 break;
498     case CHANNELS_COLUMN_INDEX:
499     int channels = (Integer)value;
500 iliev 1143 getAudioDeviceModel(row).setBackendChannelCount(channels);
501 iliev 787 break;
502     default: return;
503     }
504    
505     fireTableCellUpdated(row, col);
506     }
507    
508     /**
509     * Returns <code>true</code> if the cell at
510     * <code>rowIndex</code> and <code>columnIndex</code> is editable.
511     */
512     public boolean
513     isCellEditable(int row, int col) {
514     switch(col) {
515     case ACTIVE_COLUMN_INDEX:
516     return true;
517     case DEVICE_ID_COLUMN_INDEX:
518     return false;
519     case CHANNELS_COLUMN_INDEX:
520     return true;
521     default: return false;
522     }
523     }
524    
525     /**
526     * Returns the most specific superclass for all the cell values
527     * in the column. This is used by the <code>JTable</code> to set up a
528     * default renderer and editor for the column.
529     * @param columnIndex The index of the column.
530     * @return The common ancestor class of the object values in the model.
531     */
532     public Class
533     getColumnClass(int columnIndex) {
534     return getValueAt(0, columnIndex).getClass();
535     }
536     ///////
537    
538 iliev 2192 private class Handler extends AudioDeviceAdapter implements ListListener<AudioDeviceModel> {
539 iliev 787 /**
540     * Invoked when a new audio device is created.
541     * @param e An <code>AudioDeviceListEvent</code>
542     * instance providing the event information.
543     */
544     public void
545 iliev 1143 entryAdded(ListEvent<AudioDeviceModel> e) {
546 iliev 787 for(AudioDeviceModel m : deviceList) m.removeAudioDeviceListener(this);
547 iliev 1204 deviceList = CC.getSamplerModel().getAudioDevices();
548 iliev 787 for(AudioDeviceModel m : deviceList) m.addAudioDeviceListener(this);
549     fireTableDataChanged();
550     }
551    
552     /**
553     * Invoked when an audio device is removed.
554     * @param e An <code>AudioDeviceListEvent</code>
555     * instance providing the event information.
556     */
557     public void
558 iliev 1143 entryRemoved(ListEvent<AudioDeviceModel> e) {
559 iliev 787 for(AudioDeviceModel m : deviceList) m.removeAudioDeviceListener(this);
560 iliev 1204 deviceList = CC.getSamplerModel().getAudioDevices();
561 iliev 787 for(AudioDeviceModel m : deviceList) m.addAudioDeviceListener(this);
562     fireTableDataChanged();
563     }
564    
565     /** Invoked when when the settings of a particular audio device have changed. */
566     public void
567     settingsChanged(AudioDeviceEvent e) {
568     for(int i = 0; i < deviceList.length; i++) {
569     AudioOutputDevice d = deviceList[i].getDeviceInfo();
570     AudioOutputDevice d2 = e.getAudioDeviceModel().getDeviceInfo();
571    
572 iliev 1143 if(d.getDeviceId() == d2.getDeviceId()) {
573 iliev 787 fireTableRowsUpdated(i, i);
574     }
575     }
576     }
577     }
578     }

  ViewVC Help
Powered by ViewVC