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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1818 - (show annotations) (download)
Wed Dec 24 17:29:47 2008 UTC (15 years, 4 months ago) by iliev
File size: 12778 byte(s)
* Added support for controlling the global sampler-wide limit of
  maximum voices and disk streams
  (choose Edit/Preferences, then click the `General' tab)
* Fantasia: store the view configuration of audio/MIDI devices and sampler
  channels in the LSCP script when exporting sampler configuration
* Fantasia: Implemented multiple sampler channels' selection
* Fantasia: Added option to move sampler channels up and down
  in the channels list
* Fantasia: Added option to move sampler channels
  to another channels panels

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2008 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.Component;
27 import java.awt.Rectangle;
28
29 import java.awt.event.MouseAdapter;
30 import java.awt.event.MouseEvent;
31
32 import java.util.Vector;
33
34 import javax.swing.BorderFactory;
35 import javax.swing.JMenu;
36 import javax.swing.JMenuItem;
37 import javax.swing.JPopupMenu;
38 import javax.swing.JScrollPane;
39 import javax.swing.ListSelectionModel;
40
41 import javax.swing.event.ListSelectionEvent;
42 import javax.swing.event.ListSelectionListener;
43
44 import net.sf.juife.ComponentList;
45 import net.sf.juife.ComponentListModel;
46 import net.sf.juife.DefaultComponentListModel;
47
48 import org.jsampler.CC;
49 import org.jsampler.SamplerChannelModel;
50
51 import org.jsampler.view.JSChannel;
52 import org.jsampler.view.JSChannelsPane;
53
54 import static org.jsampler.view.classic.A4n.a4n;
55 import static org.jsampler.view.classic.ClassicI18n.i18n;
56
57
58 /**
59 *
60 * @author Grigor Iliev
61 */
62 public class ChannelsPane extends JSChannelsPane implements ListSelectionListener {
63 private final ComponentList chnList = new ComponentList();
64 private final DefaultComponentListModel listModel = new DefaultComponentListModel();
65
66 private final JScrollPane scrollPane;
67
68 /**
69 * Creates a new instance of <code>ChannelsPane</code> with
70 * the specified <code>title</code>.
71 * @param title The title of this <code>ChannelsPane</code>
72 */
73 public
74 ChannelsPane(String title) {
75 super(title);
76
77 setLayout(new BorderLayout());
78
79 chnList.setOpaque(false);
80 //chnList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
81 chnList.setModel(listModel);
82 chnList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
83 chnList.addListSelectionListener(this);
84 chnList.addMouseListener(new ContextMenu());
85 //chnList.setDragEnabled(true);
86
87 scrollPane = new JScrollPane(chnList);
88 scrollPane.setBorder(BorderFactory.createEmptyBorder());
89 add(scrollPane);
90
91 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
92
93 }
94
95 @Override
96 public void
97 setSelectedChannel(JSChannel channel) {
98 chnList.setSelectedComponent(channel, true);
99 }
100
101 /**
102 * Adds new channel to this channels pane.
103 * @param channelModel The sampler channel model to be used by the new channel.
104 */
105 @Override
106 public void
107 addChannel(SamplerChannelModel channelModel) {
108 Channel channel = new Channel(channelModel);
109 listModel.add(channel);
110 if(channel.getChannelInfo().getEngine() == null) channel.expandChannel();
111 chnList.setSelectedComponent(channel, true);
112 scrollToBottom();
113 }
114
115 /**
116 * Adds the specified channels to this channels pane.
117 * @param chns The channels to be added.
118 */
119 @Override
120 public void
121 addChannels(JSChannel[] chns) {
122 if(chns == null || chns.length == 0) return;
123
124 for(JSChannel c : chns) listModel.add(c);
125 chnList.setSelectionInterval (
126 listModel.getSize() - chns.length, listModel.getSize() - 1
127 );
128
129 chnList.ensureIndexIsVisible(listModel.getSize() - 1);
130 }
131
132 /**
133 * Removes the specified channel from this channels pane.
134 * This method is invoked when a sampler channel is removed in the back-end.
135 * @param chn The channel to be removed from this channels pane.
136 */
137 @Override
138 public void
139 removeChannel(JSChannel chn) { listModel.remove(chn); }
140
141 /**
142 * Gets the first channel in this channels pane.
143 * @return The first channel in this channels pane or <code>null</code> if
144 * the channels pane is empty.
145 */
146 @Override
147 public JSChannel
148 getFirstChannel() { return listModel.size() == 0 ? null : (JSChannel)listModel.get(0); }
149
150 /**
151 * Gets the last channel in this channels pane.
152 * @return The last channel in this channels pane or <code>null</code> if
153 * the channels pane is empty.
154 */
155 @Override
156 public JSChannel
157 getLastChannel() {
158 return listModel.size() == 0 ? null : (JSChannel)listModel.get(listModel.size()-1);
159 }
160
161 /**
162 * Gets the channel at the specified index.
163 * @return The channel at the specified index.
164 * @throws ArrayIndexOutOfBoundsException If the index is out of range.
165 */
166 @Override
167 public JSChannel
168 getChannel(int idx) { return (JSChannel)listModel.get(idx); }
169
170 /**
171 * Gets an array with all channels in this channels pane.
172 * @return An array with all channels in this channels pane.
173 */
174 @Override
175 public JSChannel[]
176 getChannels() {
177 JSChannel[] chns = new JSChannel[listModel.size()];
178 for(int i = 0; i < listModel.size(); i++) chns[i] = (JSChannel)listModel.get(i);
179 return chns;
180 }
181
182 /**
183 * Gets the number of channels in this channels pane.
184 * @return The number of channels in this channels pane.
185 */
186 @Override
187 public int
188 getChannelCount() { return listModel.size(); }
189
190 /**
191 * Determines whether there is at least one selected channel.
192 * @return <code>true</code> if there is at least one selected channel,
193 * <code>false</code> otherwise.
194 */
195 @Override
196 public boolean
197 hasSelectedChannel() { return !chnList.isSelectionEmpty(); }
198
199 /**
200 * Gets the number of the selected channels.
201 * @return The number of the selected channels.
202 */
203 @Override
204 public int
205 getSelectedChannelCount() { return chnList.getSelectedIndices().length; }
206
207 /**
208 * Gets an array with all selected channels.
209 * The channels are sorted in increasing index order.
210 * @return The selected channels or an empty array if nothing is selected.
211 */
212 @Override
213 public JSChannel[]
214 getSelectedChannels() {
215 Component[] cS = chnList.getSelectedComponents();
216 JSChannel[] chns = new JSChannel[cS.length];
217 for(int i = 0; i < cS.length; i++) chns[i] = (JSChannel)cS[i];
218 return chns;
219 }
220
221 /**
222 * Removes all selected channels in this channels pane.
223 * Notice that this method does not remove any channels in the back-end.
224 * It is invoked after the channels are already removed in the back-end.
225 * @return The number of removed channels.
226 */
227 @Override
228 public int
229 removeSelectedChannels() {
230 int[] l = chnList.getSelectedIndices();
231 ComponentListModel model = chnList.getModel();
232
233 for(;;) {
234 int i = chnList.getMinSelectionIndex();
235 if(i == -1) break;
236 model.remove(i);
237 }
238
239 return l.length;
240 }
241
242 /** Selects all channels. */
243 @Override
244 public void
245 selectAll() { chnList.selectAll(); }
246
247 /** Deselects all selected channels. */
248 @Override
249 public void
250 clearSelection() { chnList.clearSelection(); }
251
252 /**
253 * Registers the specified listener for receiving list selection events.
254 * @param listener The <code>ListSelectionListener</code> to register.
255 */
256 @Override
257 public void
258 addListSelectionListener(ListSelectionListener listener) {
259 listenerList.add(ListSelectionListener.class, listener);
260 }
261
262 /**
263 * Removes the specified listener.
264 * @param listener The <code>ListSelectionListener</code> to remove.
265 */
266 @Override
267 public void
268 removeListSelectionListener(ListSelectionListener listener) {
269 listenerList.remove(ListSelectionListener.class, listener);
270 }
271
272 /**
273 * Invoked when the selection has changed.
274 * This method implements <code>valueChanged</code>
275 * method of the <code>ListSelectionListener</code> interface.
276 * @param e A <code>ListSelectionEvent</code>
277 * instance providing the event information.
278 */
279 @Override
280 public void
281 valueChanged(ListSelectionEvent e) {
282 ListSelectionEvent e2 = null;
283 Object[] listeners = listenerList.getListenerList();
284
285 for(int i = listeners.length - 2; i >= 0; i -= 2) {
286 if(listeners[i] == ListSelectionListener.class) {
287 if(e2 == null) e2 = new ListSelectionEvent (
288 this,
289 e.getFirstIndex(),
290 e.getLastIndex(),
291 e.getValueIsAdjusting()
292 );
293 ((ListSelectionListener)listeners[i + 1]).valueChanged(e2);
294 }
295 }
296
297 }
298
299 /**
300 * Determines whether the channel list UI should be automatically updated
301 * when channel is added/removed. The default value is <code>true</code>.
302 * @see updateChannelListUI
303 */
304 @Override
305 public boolean
306 getAutoUpdate() { return chnList.getAutoUpdate(); }
307
308 /**
309 * Determines whether the channel list UI should be automatically updated
310 * when channel is added/removed.
311 * @see updateChannelListUI
312 */
313 @Override
314 public void
315 setAutoUpdate(boolean b) { chnList.setAutoUpdate(b); }
316
317 /**
318 * Updates the channel list UI.
319 * @see setAutoUpdate
320 */
321 @Override
322 public void
323 updateChannelListUI() { chnList.updateList(); }
324
325
326 @Override
327 public void
328 moveSelectedChannelsOnTop() {
329 JSChannel[] chns = getSelectedChannels();
330
331 if(chns.length == 0) {
332 CC.getLogger().info("Can't move channel(s) at the beginning");
333 return;
334 }
335
336 for(int i = chns.length - 1; i >= 0; i--) {
337 listModel.remove(chns[i]);
338 listModel.insert(chns[i], 0);
339 }
340
341 chnList.setSelectionInterval(0, chns.length - 1);
342 chnList.ensureIndexIsVisible(0);
343 }
344
345 @Override
346 public void
347 moveSelectedChannelsUp() {
348 JSChannel[] chns = getSelectedChannels();
349
350 if(chns.length == 0 || chns[0] == getFirstChannel()) {
351 CC.getLogger().info("Can't move channel(s) up");
352 return;
353 }
354
355 for(int i = 0; i < chns.length; i++) listModel.moveUp(chns[i]);
356
357 int[] si = chnList.getSelectedIndices();
358
359 for(int i = 0; i < si.length; i++) si[i] -= 1;
360
361 chnList.setSelectedIndices(si);
362 chnList.ensureIndexIsVisible(si[0]);
363 }
364
365 @Override
366 public void
367 moveSelectedChannelsDown() {
368 JSChannel[] chns = getSelectedChannels();
369
370 if(chns.length == 0 || chns[chns.length - 1] == getLastChannel()) {
371 CC.getLogger().info("Can't move channel(s) down");
372 return;
373 }
374
375 for(int i = chns.length - 1; i >= 0; i--) listModel.moveDown(chns[i]);
376
377 int[] si = chnList.getSelectedIndices();
378 for(int i = 0; i < si.length; i++) si[i] += 1;
379 chnList.setSelectedIndices(si);
380 chnList.ensureIndexIsVisible(si[si.length - 1]);
381 }
382
383 @Override
384 public void
385 moveSelectedChannelsAtBottom() {
386 JSChannel[] chns = getSelectedChannels();
387
388 if(chns.length == 0) {
389 CC.getLogger().info("Can't move channel(s) at the end");
390 return;
391 }
392
393 for(int i = 0; i < chns.length; i++) {
394 listModel.remove(chns[i]);
395 listModel.add(chns[i]);
396 }
397
398 chnList.setSelectionInterval (
399 listModel.getSize() - chns.length, listModel.getSize() - 1
400 );
401 chnList.ensureIndexIsVisible(listModel.getSize() - 1);
402 }
403
404 private void
405 scrollToBottom() {
406 int h = scrollPane.getViewport().getView().getHeight();
407 scrollPane.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
408 }
409
410 class ContextMenu extends MouseAdapter {
411 private final JPopupMenu cmenu = new JPopupMenu();
412 private final JMenu submenu = new JMenu(i18n.getMenuLabel("channels.MoveToTab"));
413
414 ContextMenu() {
415 JMenuItem mi = new JMenuItem(a4n.moveChannelsOnTop);
416 mi.setIcon(null);
417 cmenu.add(mi);
418
419 mi = new JMenuItem(a4n.moveChannelsUp);
420 mi.setIcon(null);
421 cmenu.add(mi);
422
423 mi = new JMenuItem(a4n.moveChannelsDown);
424 mi.setIcon(null);
425 cmenu.add(mi);
426
427 mi = new JMenuItem(a4n.moveChannelsAtBottom);
428 mi.setIcon(null);
429 cmenu.add(mi);
430
431 cmenu.add(submenu);
432
433 cmenu.addSeparator();
434
435 mi = new JMenuItem(a4n.removeChannels);
436 mi.setIcon(null);
437 cmenu.add(mi);
438 }
439
440 @Override
441 public void
442 mousePressed(MouseEvent e) {
443 if(e.isPopupTrigger()) show(e);
444 }
445
446 @Override
447 public void
448 mouseReleased(MouseEvent e) {
449 if(e.isPopupTrigger()) show(e);
450 }
451
452 void
453 show(MouseEvent e) {
454 /*int idx = chnList.locationToIndex(e.getPoint());
455 if(!chnList.isSelectedIndex(idx)) chnList.setSelectedIndex(idx);
456
457 if(idx != -1 && CC.getMainFrame().getChannelsPaneCount() > 1) {
458 updateMenu();
459 submenu.setEnabled(true);
460 } else submenu.setEnabled(false);
461
462 cmenu.show(e.getComponent(), e.getX(), e.getY());*/
463 }
464
465 private void
466 updateMenu() {
467 submenu.removeAll();
468 Vector<JSChannelsPane> v = CC.getMainFrame().getChannelsPaneList();
469 for(JSChannelsPane p : v)
470 if(p != CC.getMainFrame().getSelectedChannelsPane())
471 submenu.add(new JMenuItem(new A4n.MoveChannelsTo(p)));
472 }
473 }
474
475 public void
476 processChannelSelection(JSChannel c, boolean controlDown, boolean shiftDown) {
477
478 }
479 }

  ViewVC Help
Powered by ViewVC