/[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 787 - (show annotations) (download)
Mon Oct 10 16:03:12 2005 UTC (18 years, 6 months ago) by iliev
File size: 16648 byte(s)
* The first alpha-release of JSampler

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

  ViewVC Help
Powered by ViewVC