/[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 842 - (show annotations) (download)
Thu Mar 16 18:08:34 2006 UTC (18 years ago) by iliev
File size: 17093 byte(s)
Updating to version 0.2a

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
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 p.add(new JScrollPane(portParamTable));
174 portsPane.add(p);
175
176 portsPane.setBorder (
177 BorderFactory.createTitledBorder(i18n.getLabel("MidiDevicesPage.ports"))
178 );
179
180 p = new JPanel();
181 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
182 p.add(Box.createRigidArea(new Dimension(0, 5)));
183 p.add(portsPane);
184
185 splitPane.setBottomComponent(p);
186 splitPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
187 splitPane.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
188 splitPane.setDividerSize(3);
189 add(splitPane);
190
191 splitPane.setDividerLocation(150);
192
193 cbPorts.addActionListener(getHandler());
194
195 devicesTable.getSelectionModel().addListSelectionListener(getHandler());
196 portParamTable.getModel().addParameterListener(getHandler());
197 }
198
199 private MidiDeviceModel
200 getSelectedMidiDeviceModel() {
201 ListSelectionModel lsm = devicesTable.getSelectionModel();
202 if(lsm.isSelectionEmpty()) return null;
203
204 return ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel (
205 lsm.getMinSelectionIndex()
206 );
207 }
208
209 private final Handler handler = new Handler();
210
211 private Handler
212 getHandler() { return handler; }
213
214 private class Handler implements ActionListener, ListSelectionListener,
215 MidiDeviceListener, ParameterListener {
216 public void
217 actionPerformed(ActionEvent e) {
218 Object obj = cbPorts.getSelectedItem();
219 if(obj == null) {
220 portParamTable.getModel().setParameters(new Parameter[0]);
221 return;
222 }
223
224 MidiPort port = (MidiPort)obj;
225
226 portParamTable.getModel().setParameters(port.getAllParameters());
227 }
228
229 public void
230 valueChanged(ListSelectionEvent e) {
231 if(e.getValueIsAdjusting()) return;
232
233 for(MidiDeviceModel m : CC.getSamplerModel().getMidiDeviceModels()) {
234 m.removeMidiDeviceListener(this);
235 }
236
237 ListSelectionModel lsm = (ListSelectionModel)e.getSource();
238
239 if(lsm.isSelectionEmpty()) {
240 duplicateMidiDevice.setEnabled(false);
241 removeMidiDevice.setEnabled(false);
242 midiDeviceProps.setEnabled(false);
243
244 cbPorts.removeAllItems();
245 cbPorts.setEnabled(false);
246 return;
247 }
248
249 duplicateMidiDevice.setEnabled(true);
250 removeMidiDevice.setEnabled(true);
251 midiDeviceProps.setEnabled(true);
252
253 MidiDeviceModel m;
254 m = ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel (
255 lsm.getMinSelectionIndex()
256 );
257
258 cbPorts.removeAllItems();
259 for(MidiPort port : m.getDeviceInfo().getMidiPorts()) cbPorts.addItem(port);
260 cbPorts.setEnabled(true);
261
262 m.addMidiDeviceListener(this);
263 }
264
265 /** Invoked when when the settings of a particular MIDI device have changed. */
266 public void
267 settingsChanged(MidiDeviceEvent e) {
268 MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();
269
270 int idx = cbPorts.getSelectedIndex();
271 cbPorts.removeAllItems();
272 for(MidiPort port : d.getMidiPorts()) cbPorts.addItem(port);
273
274 if(idx >= cbPorts.getModel().getSize()) idx = 0;
275
276 if(cbPorts.getModel().getSize() > 0) cbPorts.setSelectedIndex(idx);
277 }
278
279 /** Invoked when when the value of a particular parameter is changed. */
280 public void
281 parameterChanged(ParameterEvent e) {
282 MidiDeviceModel m = getSelectedMidiDeviceModel();
283 if(m == null) {
284 CC.getLogger().warning("Unexpected null MidiDeviceModel!");
285 return;
286 }
287
288 int port = cbPorts.getSelectedIndex();
289 if(port == -1) {
290 CC.getLogger().warning("There is no MIDI port selected!");
291 return;
292 }
293
294 CC.getTaskQueue().add (
295 new SetMidiPortParameter(m.getDeviceID(), port, e.getParameter())
296 );
297 }
298 }
299
300 private class DuplicateMidiDevice extends AbstractAction {
301 DuplicateMidiDevice() {
302 super("");
303
304 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttDuplicateMidiDevice"));
305
306 try {
307 URL url = ClassLoader.getSystemClassLoader().getResource (
308 "org/jsampler/view/classic/res/icons/Copy16.gif"
309 );
310
311 ImageIcon icon = new ImageIcon(url);
312 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
313 putValue(Action.SMALL_ICON, icon);
314 } catch(Exception x) {
315 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
316 }
317
318 setEnabled(false);
319 }
320
321 public void
322 actionPerformed(ActionEvent e) {
323 int i = devicesTable.getSelectedRow();
324 if(i < 0) {
325 CC.getLogger().info("There's no selected MIDI device to duplicate");
326 return;
327 }
328 MidiDeviceModel m;
329 m = ((MidiDevicesTableModel)devicesTable.getModel()).getMidiDeviceModel(i);
330 String d = m.getDeviceInfo().getDriverName();
331 Parameter[] pS = m.getDeviceInfo().getAdditionalParameters();
332 for(Parameter p : pS) System.out.println(p.getName());
333 CC.getTaskQueue().add(new CreateMidiDevice(d, pS));
334 }
335 }
336
337 private class RemoveMidiDevice extends AbstractAction {
338 RemoveMidiDevice() {
339 super("");
340
341 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttRemoveMidiDevice"));
342
343 try {
344 URL url = ClassLoader.getSystemClassLoader().getResource (
345 "org/jsampler/view/classic/res/icons/Delete16.gif"
346 );
347
348 ImageIcon icon = new ImageIcon(url);
349 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
350 putValue(Action.SMALL_ICON, icon);
351 } catch(Exception x) {
352 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
353 }
354
355 setEnabled(false);
356 }
357
358 public void
359 actionPerformed(ActionEvent e) {
360 MidiDeviceModel m = getSelectedMidiDeviceModel();
361 if(m == null) {
362 CC.getLogger().warning("No selected MIDI device to remove!");
363 return;
364 }
365
366 CC.getTaskQueue().add(new DestroyMidiDevice(m.getDeviceID()));
367 }
368 }
369
370 private class MidiDeviceProps extends AbstractAction {
371 MidiDeviceProps() {
372 super("");
373
374 putValue(SHORT_DESCRIPTION, i18n.getMenuLabel("ttMidiDeviceProps"));
375
376 try {
377 URL url = ClassLoader.getSystemClassLoader().getResource (
378 "org/jsampler/view/classic/res/icons/Properties16.gif"
379 );
380
381 ImageIcon icon = new ImageIcon(url);
382 if(icon.getImageLoadStatus() == MediaTracker.COMPLETE)
383 putValue(Action.SMALL_ICON, icon);
384 } catch(Exception x) {
385 CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
386 }
387
388 setEnabled(false);
389 }
390
391 public void
392 actionPerformed(ActionEvent e) { new DevicePropsDlg().setVisible(true); }
393 }
394
395 private class DevicePropsDlg extends InformationDialog {
396 DevicePropsDlg() {
397 super(CC.getMainFrame(), i18n.getLabel("MidiDevicesPage.DevicePropsDlg"));
398
399 MidiDeviceModel m = getSelectedMidiDeviceModel();
400 ParameterTable table = new ParameterTable();
401 table.getModel().setParameters (
402 m.getDeviceInfo().getAdditionalParameters()
403 );
404
405 JScrollPane sp = new JScrollPane(table);
406 sp.setPreferredSize(JuifeUtils.getUnionSize (
407 sp.getMinimumSize(), new Dimension(200, 200)
408 ));
409 setMainPane(sp);
410 }
411 }
412 }
413
414 class MidiDevicesTableModel extends AbstractTableModel {
415 protected final static int ACTIVE_COLUMN_INDEX = 0;
416 protected final static int DEVICE_ID_COLUMN_INDEX = 1;
417 protected final static int PORTS_COLUMN_INDEX = 2;
418
419 private final String[] columnNames = {
420 "",
421 i18n.getLabel("MidiDevicesTableModel.deviceID"),
422 i18n.getLabel("MidiDevicesTableModel.ports")
423 };
424
425 private MidiDeviceModel[] deviceList;
426
427 MidiDevicesTableModel() {
428 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
429 deviceList = CC.getSamplerModel().getMidiDeviceModels();
430 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(getHandler());
431 }
432
433 public MidiDeviceModel
434 getMidiDeviceModel(int index) { return deviceList[index]; }
435
436 // The Table Model implementation
437
438 /**
439 * Gets the number of columns in the model.
440 * @return The number of columns in the model.
441 */
442 public int
443 getColumnCount() { return columnNames.length; }
444
445 /**
446 * Gets the number of rows in the model.
447 * @return The number of rows in the model.
448 */
449 public int
450 getRowCount() { return deviceList.length; }
451
452 /**
453 * Gets the name of the column at <code>columnIndex</code>.
454 * @return The name of the column at <code>columnIndex</code>.
455 */
456 public String
457 getColumnName(int col) { return columnNames[col]; }
458
459 /**
460 * Gets the value for the cell at <code>columnIndex</code> and
461 * <code>rowIndex</code>.
462 * @param row The row whose value is to be queried.
463 * @param col The column whose value is to be queried.
464 * @return The value for the cell at <code>columnIndex</code> and
465 * <code>rowIndex</code>.
466 */
467 public Object
468 getValueAt(int row, int col) {
469 switch(col) {
470 case ACTIVE_COLUMN_INDEX:
471 return deviceList[row].getDeviceInfo().isActive();
472 case DEVICE_ID_COLUMN_INDEX:
473 return deviceList[row].getDeviceID();
474 case PORTS_COLUMN_INDEX:
475 return deviceList[row].getDeviceInfo().getMidiPortCount();
476 }
477
478 return null;
479 }
480
481 /**
482 * Sets the value in the cell at <code>columnIndex</code>
483 * and <code>rowIndex</code> to <code>value</code>.
484 */
485 public void
486 setValueAt(Object value, int row, int col) {
487 switch(col) {
488 case ACTIVE_COLUMN_INDEX:
489 boolean active = (Boolean)value;
490 deviceList[row].getDeviceInfo().setActive(active);
491 CC.getTaskQueue().add (
492 new EnableMidiDevice(deviceList[row].getDeviceID(), active)
493 );
494 break;
495 case PORTS_COLUMN_INDEX:
496 int deviceID = getMidiDeviceModel(row).getDeviceID();
497 int ports = (Integer)value;
498 CC.getTaskQueue().add(new SetMidiInputPortCount(deviceID, ports));
499 break;
500 default: return;
501 }
502
503 fireTableCellUpdated(row, col);
504 }
505
506 /**
507 * Returns <code>true</code> if the cell at
508 * <code>rowIndex</code> and <code>columnIndex</code> is editable.
509 */
510 public boolean
511 isCellEditable(int row, int col) {
512 switch(col) {
513 case ACTIVE_COLUMN_INDEX:
514 return true;
515 case DEVICE_ID_COLUMN_INDEX:
516 return false;
517 case PORTS_COLUMN_INDEX:
518 return true;
519 default: return false;
520 }
521 }
522
523 /**
524 * Returns the most specific superclass for all the cell values
525 * in the column. This is used by the <code>JTable</code> to set up a
526 * default renderer and editor for the column.
527 * @param columnIndex The index of the column.
528 * @return The common ancestor class of the object values in the model.
529 */
530 public Class
531 getColumnClass(int columnIndex) {
532 return getValueAt(0, columnIndex).getClass();
533 }
534 ///////
535
536 private final Handler handler = new Handler();
537
538 private Handler
539 getHandler() { return handler; }
540
541 private class Handler implements MidiDeviceListener, MidiDeviceListListener {
542 /**
543 * Invoked when a new MIDI device is created.
544 * @param e A <code>MidiDeviceListEvent</code>
545 * instance providing the event information.
546 */
547 public void
548 deviceAdded(MidiDeviceListEvent e) {
549 for(MidiDeviceModel m : deviceList) m.removeMidiDeviceListener(this);
550 deviceList = CC.getSamplerModel().getMidiDeviceModels();
551 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(this);
552 fireTableDataChanged();
553 }
554
555 /**
556 * Invoked when a MIDI device is removed.
557 * @param e A <code>MidiDeviceListEvent</code>
558 * instance providing the event information.
559 */
560 public void
561 deviceRemoved(MidiDeviceListEvent e) {
562 for(MidiDeviceModel m : deviceList) m.removeMidiDeviceListener(this);
563 deviceList = CC.getSamplerModel().getMidiDeviceModels();
564 for(MidiDeviceModel m : deviceList) m.addMidiDeviceListener(this);
565 fireTableDataChanged();
566 }
567
568 /** Invoked when when the settings of a particular MIDI device have changed. */
569 public void
570 settingsChanged(MidiDeviceEvent e) {
571 MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();
572
573 for(int i = 0; i < deviceList.length; i++) {
574 MidiInputDevice d2 = deviceList[i].getDeviceInfo();
575
576 if(d.getDeviceID() == d2.getDeviceID()) {
577 fireTableRowsUpdated(i, i);
578 }
579 }
580 }
581 }
582 }

  ViewVC Help
Powered by ViewVC