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

  ViewVC Help
Powered by ViewVC