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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1204 - (show annotations) (download)
Thu May 24 21:43:45 2007 UTC (16 years, 11 months ago) by iliev
File size: 16072 byte(s)
upgrading to version 0.5a

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2006 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.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.JButton;
43 import javax.swing.JComboBox;
44 import javax.swing.JLabel;
45 import javax.swing.JOptionPane;
46 import javax.swing.JPanel;
47 import javax.swing.JScrollPane;
48 import javax.swing.JSeparator;
49 import javax.swing.JSplitPane;
50 import javax.swing.JTable;
51 import javax.swing.JToolBar;
52 import javax.swing.ListSelectionModel;
53
54 import javax.swing.event.ListSelectionEvent;
55 import javax.swing.event.ListSelectionListener;
56
57 import javax.swing.table.AbstractTableModel;
58 import javax.swing.table.TableColumn;
59
60 import net.sf.juife.InformationDialog;
61 import net.sf.juife.JuifeUtils;
62 import net.sf.juife.NavigationPage;
63
64 import org.jsampler.CC;
65 import org.jsampler.HF;
66 import org.jsampler.MidiDeviceModel;
67
68 import org.jsampler.event.MidiDeviceEvent;
69 import org.jsampler.event.MidiDeviceListEvent;
70 import org.jsampler.event.MidiDeviceListListener;
71 import org.jsampler.event.MidiDeviceListener;
72 import org.jsampler.event.ParameterEvent;
73 import org.jsampler.event.ParameterListener;
74
75 import org.jsampler.view.NumberCellEditor;
76 import org.jsampler.view.ParameterTable;
77
78 import org.linuxsampler.lscp.MidiInputDevice;
79 import org.linuxsampler.lscp.MidiPort;
80 import org.linuxsampler.lscp.Parameter;
81
82 import static org.jsampler.view.classic.ClassicI18n.i18n;
83 import static org.jsampler.view.classic.MidiDevicesTableModel.*;
84
85
86 /**
87 *
88 * @author Grigor Iliev
89 */
90 public class MidiDevicesPage extends NavigationPage {
91 private final Action duplicateMidiDevice = new DuplicateMidiDevice();
92 private final Action removeMidiDevice = new RemoveMidiDevice();
93 private final Action midiDeviceProps = new MidiDeviceProps();
94
95 private final ToolbarButton btnNewDevice = new ToolbarButton(A4n.addMidiDevice);
96 private final ToolbarButton btnDuplicateDevice = new ToolbarButton(duplicateMidiDevice);
97 private final ToolbarButton btnRemoveDevice = new ToolbarButton(removeMidiDevice);
98 private final ToolbarButton btnDeviceProps = new ToolbarButton(midiDeviceProps);
99
100 private final JTable devicesTable = new JTable(new MidiDevicesTableModel());
101
102 private final JLabel lPorts = new JLabel(i18n.getLabel("MidiDevicesPage.lPorts"));
103 private final JComboBox cbPorts = new JComboBox();
104
105 ParameterTable portParamTable = new ParameterTable();
106
107
108 /** Creates a new instance of <code>MidiDevicesPage</code> */
109 public
110 MidiDevicesPage() {
111 setTitle(i18n.getLabel("MidiDevicesPage.title"));
112
113 cbPorts.setEnabled(false);
114
115 TableColumn tc = devicesTable.getColumnModel().getColumn(ACTIVE_COLUMN_INDEX);
116 tc.setPreferredWidth(tc.getMinWidth());
117
118 NumberCellEditor nce = new NumberCellEditor();
119 nce.setMinimum(0);
120 nce.setMaximum(255);
121 tc = devicesTable.getColumnModel().getColumn(PORTS_COLUMN_INDEX);
122 tc.setCellEditor(nce);
123
124 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
125
126 JToolBar tb = new JToolBar();
127 tb.setMaximumSize(new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height));
128 tb.setFloatable(false);
129 tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
130
131 tb.add(Box.createRigidArea(new Dimension(3, 0)));
132 tb.add(new JLabel(Res.iconMidi24));
133 tb.add(Box.createRigidArea(new Dimension(3, 0)));
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 Dimension d;
147 d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
148 sp.setPreferredSize(d);
149
150 JPanel p = new JPanel();
151 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
152 p.add(sp);
153 p.add(Box.createRigidArea(new Dimension(0, 8)));
154
155 splitPane.setTopComponent(p);
156
157 //add(Box.createRigidArea(new Dimension(0, 12)));
158
159 JPanel portsPane = new JPanel();
160 portsPane.setLayout(new BoxLayout(portsPane, BoxLayout.Y_AXIS));
161
162 p = new JPanel();
163 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
164 p.add(lPorts);
165 p.add(Box.createRigidArea(new Dimension(5, 0)));
166 p.add(cbPorts);
167 p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
168 portsPane.add(p);
169
170 p = new JPanel();
171 p.setLayout(new BorderLayout());
172 p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
173
174 sp = new JScrollPane(portParamTable);
175 d = new Dimension(sp.getMinimumSize().width, sp.getPreferredSize().height);
176 sp.setPreferredSize(d);
177
178 p.add(sp);
179 portsPane.add(p);
180
181 portsPane.setBorder (
182 BorderFactory.createTitledBorder(i18n.getLabel("MidiDevicesPage.ports"))
183 );
184
185 p = new JPanel();
186 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
187 p.add(Box.createRigidArea(new Dimension(0, 5)));
188 p.add(portsPane);
189
190 splitPane.setBottomComponent(p);
191 splitPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
192 splitPane.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
193 splitPane.setDividerSize(3);
194 splitPane.setContinuousLayout(true);
195 add(splitPane);
196
197 splitPane.setDividerLocation(150);
198
199 cbPorts.addActionListener(getHandler());
200
201 devicesTable.getSelectionModel().addListSelectionListener(getHandler());
202 portParamTable.getModel().addParameterListener(getHandler());
203 }
204
205 private MidiDeviceModel
206 getSelectedMidiDeviceModel() {
207 ListSelectionModel lsm = devicesTable.getSelectionModel();
208 if(lsm.isSelectionEmpty()) return null;
209
210 return ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel (
211 lsm.getMinSelectionIndex()
212 );
213 }
214
215 private final Handler handler = new Handler();
216
217 private Handler
218 getHandler() { return handler; }
219
220 private class Handler implements ActionListener, ListSelectionListener,
221 MidiDeviceListener, ParameterListener {
222 public void
223 actionPerformed(ActionEvent e) {
224 Object obj = cbPorts.getSelectedItem();
225 if(obj == null) {
226 portParamTable.getModel().setParameters(new Parameter[0]);
227 return;
228 }
229
230 MidiPort port = (MidiPort)obj;
231
232 portParamTable.getModel().setParameters(port.getAllParameters());
233 }
234
235 public void
236 valueChanged(ListSelectionEvent e) {
237 if(e.getValueIsAdjusting()) return;
238
239 for(MidiDeviceModel m : CC.getSamplerModel().getMidiDevices()) {
240 m.removeMidiDeviceListener(this);
241 }
242
243 ListSelectionModel lsm = (ListSelectionModel)e.getSource();
244
245 if(lsm.isSelectionEmpty()) {
246 duplicateMidiDevice.setEnabled(false);
247 removeMidiDevice.setEnabled(false);
248 midiDeviceProps.setEnabled(false);
249
250 cbPorts.removeAllItems();
251 cbPorts.setEnabled(false);
252 return;
253 }
254
255 duplicateMidiDevice.setEnabled(true);
256 removeMidiDevice.setEnabled(true);
257 midiDeviceProps.setEnabled(true);
258
259 MidiDeviceModel m;
260 m = ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel (
261 lsm.getMinSelectionIndex()
262 );
263
264 cbPorts.removeAllItems();
265 for(MidiPort port : m.getDeviceInfo().getMidiPorts()) cbPorts.addItem(port);
266 cbPorts.setEnabled(true);
267
268 m.addMidiDeviceListener(this);
269 }
270
271 /** Invoked when when the settings of a particular MIDI device have changed. */
272 public void
273 settingsChanged(MidiDeviceEvent e) {
274 MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();
275
276 int idx = cbPorts.getSelectedIndex();
277 cbPorts.removeAllItems();
278 for(MidiPort port : d.getMidiPorts()) cbPorts.addItem(port);
279
280 if(idx >= cbPorts.getModel().getSize()) idx = 0;
281
282 if(cbPorts.getModel().getSize() > 0) cbPorts.setSelectedIndex(idx);
283 }
284
285 /** Invoked when when the value of a particular parameter is changed. */
286 public void
287 parameterChanged(ParameterEvent e) {
288 MidiDeviceModel m = getSelectedMidiDeviceModel();
289 if(m == null) {
290 CC.getLogger().warning("Unexpected null MidiDeviceModel!");
291 return;
292 }
293
294 int port = cbPorts.getSelectedIndex();
295 if(port == -1) {
296 CC.getLogger().warning("There is no MIDI port selected!");
297 return;
298 }
299
300 m.setBackendPortParameter(port, e.getParameter());
301 }
302 }
303
304 private class DuplicateMidiDevice extends AbstractAction {
305 DuplicateMidiDevice() {
306 super("");
307
308 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttDuplicateMidiDevice"));
309 putValue(Action.SMALL_ICON, Res.iconCopy16);
310
311 setEnabled(false);
312 }
313
314 public void
315 actionPerformed(ActionEvent e) {
316 int i = devicesTable.getSelectedRow();
317 if(i < 0) {
318 CC.getLogger().info("There's no selected MIDI device to duplicate");
319 return;
320 }
321 MidiDeviceModel m;
322 m = ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel(i);
323 String d = m.getDeviceInfo().getDriverName();
324 Parameter[] pS = m.getDeviceInfo().getAdditionalParameters();
325 CC.getSamplerModel().addBackendMidiDevice(d, pS);
326 }
327 }
328
329 private class RemoveMidiDevice extends AbstractAction {
330 RemoveMidiDevice() {
331 super("");
332
333 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttRemoveMidiDevice"));
334 putValue(Action.SMALL_ICON, Res.iconDelete16);
335
336 setEnabled(false);
337 }
338
339 public void
340 actionPerformed(ActionEvent e) {
341 MidiDeviceModel m = getSelectedMidiDeviceModel();
342 if(m == null) {
343 CC.getLogger().warning("No selected MIDI device to remove!");
344 return;
345 }
346
347 CC.getSamplerModel().removeBackendMidiDevice(m.getDeviceId());
348 }
349 }
350
351 private class MidiDeviceProps extends AbstractAction {
352 MidiDeviceProps() {
353 super("");
354
355 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttMidiDeviceProps"));
356 putValue(Action.SMALL_ICON, Res.iconProps16);
357
358 setEnabled(false);
359 }
360
361 public void
362 actionPerformed(ActionEvent e) { new DevicePropsDlg().setVisible(true); }
363 }
364
365 private class DevicePropsDlg extends InformationDialog {
366 DevicePropsDlg() {
367 super(CC.getMainFrame(), i18n.getLabel("MidiDevicesPage.DevicePropsDlg"));
368
369 MidiDeviceModel m = getSelectedMidiDeviceModel();
370 ParameterTable table = new ParameterTable();
371 table.getModel().setParameters (
372 m.getDeviceInfo().getAdditionalParameters()
373 );
374
375 JScrollPane sp = new JScrollPane(table);
376 sp.setPreferredSize(JuifeUtils.getUnionSize (
377 sp.getMinimumSize(), new Dimension(200, 200)
378 ));
379 setMainPane(sp);
380 }
381 }
382 }
383
384 class MidiDevicesTableModel extends AbstractTableModel {
385 protected final static int ACTIVE_COLUMN_INDEX = 0;
386 protected final static int DEVICE_ID_COLUMN_INDEX = 1;
387 protected final static int PORTS_COLUMN_INDEX = 2;
388
389 private final String[] columnNames = {
390 "",
391 i18n.getLabel("MidiDevicesTableModel.deviceID"),
392 i18n.getLabel("MidiDevicesTableModel.ports")
393 };
394
395 private MidiDeviceModel[] deviceList;
396
397 MidiDevicesTableModel() {
398 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
399 deviceList = CC.getSamplerModel().getMidiDevices();
400 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(getHandler());
401 }
402
403 public MidiDeviceModel
404 getMidiDeviceModel(int index) { return deviceList[index]; }
405
406 // The Table Model implementation
407
408 /**
409 * Gets the number of columns in the model.
410 * @return The number of columns in the model.
411 */
412 public int
413 getColumnCount() { return columnNames.length; }
414
415 /**
416 * Gets the number of rows in the model.
417 * @return The number of rows in the model.
418 */
419 public int
420 getRowCount() { return deviceList.length; }
421
422 /**
423 * Gets the name of the column at <code>columnIndex</code>.
424 * @return The name of the column at <code>columnIndex</code>.
425 */
426 public String
427 getColumnName(int col) { return columnNames[col]; }
428
429 /**
430 * Gets the value for the cell at <code>columnIndex</code> and
431 * <code>rowIndex</code>.
432 * @param row The row whose value is to be queried.
433 * @param col The column whose value is to be queried.
434 * @return The value for the cell at <code>columnIndex</code> and
435 * <code>rowIndex</code>.
436 */
437 public Object
438 getValueAt(int row, int col) {
439 switch(col) {
440 case ACTIVE_COLUMN_INDEX:
441 return deviceList[row].getDeviceInfo().isActive();
442 case DEVICE_ID_COLUMN_INDEX:
443 return deviceList[row].getDeviceId();
444 case PORTS_COLUMN_INDEX:
445 return deviceList[row].getDeviceInfo().getMidiPortCount();
446 }
447
448 return null;
449 }
450
451 /**
452 * Sets the value in the cell at <code>columnIndex</code>
453 * and <code>rowIndex</code> to <code>value</code>.
454 */
455 public void
456 setValueAt(Object value, int row, int col) {
457 switch(col) {
458 case ACTIVE_COLUMN_INDEX:
459 boolean active = (Boolean)value;
460 deviceList[row].getDeviceInfo().setActive(active);
461 deviceList[row].setBackendActive(active);
462 break;
463 case PORTS_COLUMN_INDEX:
464 int ports = (Integer)value;
465 getMidiDeviceModel(row).setBackendPortCount(ports);
466 break;
467 default: return;
468 }
469
470 fireTableCellUpdated(row, col);
471 }
472
473 /**
474 * Returns <code>true</code> if the cell at
475 * <code>rowIndex</code> and <code>columnIndex</code> is editable.
476 */
477 public boolean
478 isCellEditable(int row, int col) {
479 switch(col) {
480 case ACTIVE_COLUMN_INDEX:
481 return true;
482 case DEVICE_ID_COLUMN_INDEX:
483 return false;
484 case PORTS_COLUMN_INDEX:
485 return true;
486 default: return false;
487 }
488 }
489
490 /**
491 * Returns the most specific superclass for all the cell values
492 * in the column. This is used by the <code>JTable</code> to set up a
493 * default renderer and editor for the column.
494 * @param columnIndex The index of the column.
495 * @return The common ancestor class of the object values in the model.
496 */
497 public Class
498 getColumnClass(int columnIndex) {
499 return getValueAt(0, columnIndex).getClass();
500 }
501 ///////
502
503 private final Handler handler = new Handler();
504
505 private Handler
506 getHandler() { return handler; }
507
508 private class Handler implements MidiDeviceListener, MidiDeviceListListener {
509 /**
510 * Invoked when a new MIDI device is created.
511 * @param e A <code>MidiDeviceListEvent</code>
512 * instance providing the event information.
513 */
514 public void
515 deviceAdded(MidiDeviceListEvent e) {
516 for(MidiDeviceModel m : deviceList) m.removeMidiDeviceListener(this);
517 deviceList = CC.getSamplerModel().getMidiDevices();
518 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(this);
519 fireTableDataChanged();
520 }
521
522 /**
523 * Invoked when a MIDI device is removed.
524 * @param e A <code>MidiDeviceListEvent</code>
525 * instance providing the event information.
526 */
527 public void
528 deviceRemoved(MidiDeviceListEvent e) {
529 for(MidiDeviceModel m : deviceList) m.removeMidiDeviceListener(this);
530 deviceList = CC.getSamplerModel().getMidiDevices();
531 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(this);
532 fireTableDataChanged();
533 }
534
535 /** Invoked when when the settings of a particular MIDI device have changed. */
536 public void
537 settingsChanged(MidiDeviceEvent e) {
538 MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();
539
540 for(int i = 0; i < deviceList.length; i++) {
541 MidiInputDevice d2 = deviceList[i].getDeviceInfo();
542
543 if(d.getDeviceId() == d2.getDeviceId()) {
544 fireTableRowsUpdated(i, i);
545 }
546 }
547 }
548 }
549 }

  ViewVC Help
Powered by ViewVC