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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 911 - (show annotations) (download)
Mon Aug 7 18:25:58 2006 UTC (17 years, 8 months ago) by iliev
File size: 17121 byte(s)
updating to JSampler 0.3a

1 /*
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.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 import net.sf.juife.InformationDialog;
59 import net.sf.juife.JuifeUtils;
60 import net.sf.juife.NavigationPage;
61
62 import org.jsampler.AudioDeviceModel;
63 import org.jsampler.CC;
64 import org.jsampler.HF;
65
66 import org.jsampler.event.AudioDeviceEvent;
67 import org.jsampler.event.AudioDeviceListEvent;
68 import org.jsampler.event.AudioDeviceListListener;
69 import org.jsampler.event.AudioDeviceListener;
70 import org.jsampler.event.ParameterEvent;
71 import org.jsampler.event.ParameterListener;
72
73 import org.jsampler.task.DestroyAudioDevice;
74 import org.jsampler.task.EnableAudioDevice;
75 import org.jsampler.task.SetAudioChannelParameter;
76 import org.jsampler.task.SetAudioOutputChannelCount;
77
78 import org.jsampler.view.NumberCellEditor;
79 import org.jsampler.view.ParameterTable;
80
81 import org.linuxsampler.lscp.AudioOutputChannel;
82 import org.linuxsampler.lscp.AudioOutputDevice;
83 import org.linuxsampler.lscp.Parameter;
84
85 import static org.jsampler.view.classic.ClassicI18n.i18n;
86 import static org.jsampler.view.classic.AudioDevicesTableModel.*;
87
88
89 /**
90 *
91 * @author Grigor Iliev
92 */
93 public class AudioDevicesPage extends NavigationPage {
94 private final Action duplicateAudioDevice = new DuplicateAudioDevice();
95 private final Action removeAudioDevice = new RemoveAudioDevice();
96 private final Action audioDeviceProps = new AudioDeviceProps();
97
98 private final ToolbarButton btnNewDevice = new ToolbarButton(A4n.addAudioDevice);
99 private final ToolbarButton btnDuplicateDevice = new ToolbarButton(duplicateAudioDevice);
100 private final ToolbarButton btnRemoveDevice = new ToolbarButton(removeAudioDevice);
101 private final ToolbarButton btnDeviceProps = new ToolbarButton(audioDeviceProps);
102
103 private final JTable devicesTable = new JTable(new AudioDevicesTableModel());
104
105 private final JLabel lChannels = new JLabel(i18n.getLabel("AudioDevicesPage.lChannels"));
106 private final JComboBox cbChannels = new JComboBox();
107
108 ParameterTable channelParamTable = new ParameterTable();
109
110
111 /** Creates a new instance of <code>AudioDevicesPage</code> */
112 public
113 AudioDevicesPage() {
114 setTitle(i18n.getLabel("AudioDevicesPage.title"));
115
116 cbChannels.setEnabled(false);
117
118 TableColumn tc = devicesTable.getColumnModel().getColumn(ACTIVE_COLUMN_INDEX);
119 tc.setPreferredWidth(tc.getMinWidth());
120
121 NumberCellEditor nce = new NumberCellEditor();
122 nce.setMinimum(0);
123 nce.setMaximum(255);
124 tc = devicesTable.getColumnModel().getColumn(CHANNELS_COLUMN_INDEX);
125 tc.setCellEditor(nce);
126
127 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
128
129 JToolBar tb = new JToolBar();
130 tb.setMaximumSize(new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height));
131 tb.setFloatable(false);
132 tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
133
134 tb.add(btnNewDevice);
135 tb.add(btnDuplicateDevice);
136 tb.add(btnRemoveDevice);
137 tb.addSeparator();
138 tb.add(btnDeviceProps);
139
140 add(tb);
141
142 JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
143
144 devicesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
145 JScrollPane sp = new JScrollPane(devicesTable);
146
147 Dimension d;
148 d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
149 sp.setPreferredSize(d);
150
151 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 sp = new JScrollPane(channelParamTable);
170 d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
171 sp.setPreferredSize(d);
172
173 p = new JPanel();
174 p.setLayout(new BorderLayout());
175 p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
176 p.add(sp);
177 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 private class Handler implements ActionListener, ListSelectionListener,
218 AudioDeviceListener, ParameterListener {
219 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 for(AudioDeviceModel m : CC.getSamplerModel().getAudioDeviceModels()) {
237 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 CC.getTaskQueue().add (
300 new SetAudioChannelParameter(m.getDeviceID(), c, e.getParameter())
301 );
302 }
303 }
304
305 private class DuplicateAudioDevice extends AbstractAction {
306 DuplicateAudioDevice() {
307 super("");
308
309 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttDuplicateAudioDevice"));
310
311 try {
312 URL url = ClassLoader.getSystemClassLoader().getResource (
313 "org/jsampler/view/classic/res/icons/Copy16.gif"
314 );
315
316 ImageIcon icon = new ImageIcon(url);
317 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
318 putValue(Action.SMALL_ICON, icon);
319 } catch(Exception x) {
320 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
321 }
322
323 setEnabled(false);
324 }
325
326 public void
327 actionPerformed(ActionEvent e) {
328 JOptionPane.showMessageDialog (
329 CC.getMainFrame(), "Not implemented yet",
330 "",
331 JOptionPane.INFORMATION_MESSAGE
332 );
333
334 AudioDeviceModel m = getSelectedAudioDeviceModel();
335 if(m == null) {
336 CC.getLogger().warning("No selected audio device to duplicate!");
337 return;
338 }
339
340
341 }
342 }
343
344 private class RemoveAudioDevice extends AbstractAction {
345 RemoveAudioDevice() {
346 super("");
347
348 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttRemoveAudioDevice"));
349
350 try {
351 URL url = ClassLoader.getSystemClassLoader().getResource (
352 "org/jsampler/view/classic/res/icons/Delete16.gif"
353 );
354
355 ImageIcon icon = new ImageIcon(url);
356 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
357 putValue(Action.SMALL_ICON, icon);
358 } catch(Exception x) {
359 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
360 }
361
362 setEnabled(false);
363 }
364
365 public void
366 actionPerformed(ActionEvent e) {
367 AudioDeviceModel m = getSelectedAudioDeviceModel();
368 if(m == null) {
369 CC.getLogger().warning("No selected audio device to remove!");
370 return;
371 }
372
373 CC.getTaskQueue().add(new DestroyAudioDevice(m.getDeviceID()));
374 }
375 }
376
377 private class AudioDeviceProps extends AbstractAction {
378 AudioDeviceProps() {
379 super("");
380
381 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttAudioDeviceProps"));
382
383 try {
384 URL url = ClassLoader.getSystemClassLoader().getResource (
385 "org/jsampler/view/classic/res/icons/Properties16.gif"
386 );
387
388 ImageIcon icon = new ImageIcon(url);
389 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
390 putValue(Action.SMALL_ICON, icon);
391 } catch(Exception x) {
392 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
393 }
394
395 setEnabled(false);
396 }
397
398 public void
399 actionPerformed(ActionEvent e) { new DevicePropsDlg().setVisible(true); }
400 }
401
402 private class DevicePropsDlg extends InformationDialog {
403 DevicePropsDlg() {
404 super(CC.getMainFrame(), i18n.getLabel("AudioDevicesPage.DevicePropsDlg"));
405
406 AudioDeviceModel m = getSelectedAudioDeviceModel();
407 ParameterTable table = new ParameterTable();
408 table.getModel().setParameters (
409 m.getDeviceInfo().getAdditionalParameters()
410 );
411
412 JScrollPane sp = new JScrollPane(table);
413 sp.setPreferredSize(JuifeUtils.getUnionSize (
414 sp.getMinimumSize(), new Dimension(200, 200)
415 ));
416 setMainPane(sp);
417 }
418 }
419 }
420
421 class AudioDevicesTableModel extends AbstractTableModel {
422 protected final static int ACTIVE_COLUMN_INDEX = 0;
423 protected final static int DEVICE_ID_COLUMN_INDEX = 1;
424 protected final static int CHANNELS_COLUMN_INDEX = 2;
425
426 private final String[] columnNames = {
427 "",
428 i18n.getLabel("AudioDevicesTableModel.deviceID"),
429 i18n.getLabel("AudioDevicesTableModel.channels")
430 };
431
432 private AudioDeviceModel[] deviceList;
433
434 AudioDevicesTableModel() {
435 CC.getSamplerModel().addAudioDeviceListListener(new Handler());
436 deviceList = CC.getSamplerModel().getAudioDeviceModels();
437
438 }
439
440 public AudioDeviceModel
441 getAudioDeviceModel(int index) { return deviceList[index]; }
442
443 // The Table Model implementation
444
445 /**
446 * Gets the number of columns in the model.
447 * @return The number of columns in the model.
448 */
449 public int
450 getColumnCount() { return columnNames.length; }
451
452 /**
453 * Gets the number of rows in the model.
454 * @return The number of rows in the model.
455 */
456 public int
457 getRowCount() { return deviceList.length; }
458
459 /**
460 * Gets the name of the column at <code>columnIndex</code>.
461 * @return The name of the column at <code>columnIndex</code>.
462 */
463 public String
464 getColumnName(int col) { return columnNames[col]; }
465
466 /**
467 * Gets the value for the cell at <code>columnIndex</code> and
468 * <code>rowIndex</code>.
469 * @param row The row whose value is to be queried.
470 * @param col The column whose value is to be queried.
471 * @return The value for the cell at <code>columnIndex</code> and
472 * <code>rowIndex</code>.
473 */
474 public Object
475 getValueAt(int row, int col) {
476 switch(col) {
477 case ACTIVE_COLUMN_INDEX:
478 return deviceList[row].getDeviceInfo().isActive();
479 case DEVICE_ID_COLUMN_INDEX:
480 return deviceList[row].getDeviceID();
481 case CHANNELS_COLUMN_INDEX:
482 return deviceList[row].getDeviceInfo().getChannelCount();
483 }
484
485 return null;
486 }
487
488 /**
489 * Sets the value in the cell at <code>columnIndex</code>
490 * and <code>rowIndex</code> to <code>value</code>.
491 */
492 public void
493 setValueAt(Object value, int row, int col) {
494 switch(col) {
495 case ACTIVE_COLUMN_INDEX:
496 boolean active = (Boolean)value;
497 deviceList[row].getDeviceInfo().setActive(active);
498 CC.getTaskQueue().add (
499 new EnableAudioDevice(deviceList[row].getDeviceID(), active)
500 );
501 break;
502 case CHANNELS_COLUMN_INDEX:
503 int deviceID = getAudioDeviceModel(row).getDeviceID();
504 int channels = (Integer)value;
505 CC.getTaskQueue().add(new SetAudioOutputChannelCount(deviceID, channels));
506 break;
507 default: return;
508 }
509
510 fireTableCellUpdated(row, col);
511 }
512
513 /**
514 * Returns <code>true</code> if the cell at
515 * <code>rowIndex</code> and <code>columnIndex</code> is editable.
516 */
517 public boolean
518 isCellEditable(int row, int col) {
519 switch(col) {
520 case ACTIVE_COLUMN_INDEX:
521 return true;
522 case DEVICE_ID_COLUMN_INDEX:
523 return false;
524 case CHANNELS_COLUMN_INDEX:
525 return true;
526 default: return false;
527 }
528 }
529
530 /**
531 * Returns the most specific superclass for all the cell values
532 * in the column. This is used by the <code>JTable</code> to set up a
533 * default renderer and editor for the column.
534 * @param columnIndex The index of the column.
535 * @return The common ancestor class of the object values in the model.
536 */
537 public Class
538 getColumnClass(int columnIndex) {
539 return getValueAt(0, columnIndex).getClass();
540 }
541 ///////
542
543 private class Handler implements AudioDeviceListener, AudioDeviceListListener {
544 /**
545 * Invoked when a new audio device is created.
546 * @param e An <code>AudioDeviceListEvent</code>
547 * instance providing the event information.
548 */
549 public void
550 deviceAdded(AudioDeviceListEvent e) {
551 for(AudioDeviceModel m : deviceList) m.removeAudioDeviceListener(this);
552 deviceList = CC.getSamplerModel().getAudioDeviceModels();
553 for(AudioDeviceModel m : deviceList) m.addAudioDeviceListener(this);
554 fireTableDataChanged();
555 }
556
557 /**
558 * Invoked when an audio device is removed.
559 * @param e An <code>AudioDeviceListEvent</code>
560 * instance providing the event information.
561 */
562 public void
563 deviceRemoved(AudioDeviceListEvent e) {
564 for(AudioDeviceModel m : deviceList) m.removeAudioDeviceListener(this);
565 deviceList = CC.getSamplerModel().getAudioDeviceModels();
566 for(AudioDeviceModel m : deviceList) m.addAudioDeviceListener(this);
567 fireTableDataChanged();
568 }
569
570 /** Invoked when when the settings of a particular audio device have changed. */
571 public void
572 settingsChanged(AudioDeviceEvent e) {
573 for(int i = 0; i < deviceList.length; i++) {
574 AudioOutputDevice d = deviceList[i].getDeviceInfo();
575 AudioOutputDevice d2 = e.getAudioDeviceModel().getDeviceInfo();
576
577 if(d.getDeviceID() == d2.getDeviceID()) {
578 fireTableRowsUpdated(i, i);
579 }
580 }
581 }
582 }
583 }

  ViewVC Help
Powered by ViewVC