/[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 2200 - (show annotations) (download)
Sun Jul 3 22:01:16 2011 UTC (12 years, 9 months ago) by iliev
File size: 13281 byte(s)
* added support for exporting effects to LSCP script
* Sampler Browser (work in progress): initial
  implementation of sampler channels

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2011 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 firePropertyChange("channelAdded", null, channelModel);
115 }
116
117 /**
118 * Adds the specified channels to this channels pane.
119 * @param chns The channels to be added.
120 */
121 @Override
122 public void
123 addChannels(JSChannel[] chns) {
124 if(chns == null || chns.length == 0) return;
125
126 for(JSChannel c : chns) listModel.add(c);
127 chnList.setSelectionInterval (
128 listModel.getSize() - chns.length, listModel.getSize() - 1
129 );
130
131 chnList.ensureIndexIsVisible(listModel.getSize() - 1);
132
133 firePropertyChange("channelsAdded", null, chns);
134 }
135
136 /**
137 * Removes the specified channel from this channels pane.
138 * This method is invoked when a sampler channel is removed in the back-end.
139 * @param chn The channel to be removed from this channels pane.
140 */
141 @Override
142 public void
143 removeChannel(JSChannel chn) {
144 listModel.remove(chn);
145
146 firePropertyChange("channelRemoved", null, chn);
147 }
148
149 /**
150 * Gets the first channel in this channels pane.
151 * @return The first channel in this channels pane or <code>null</code> if
152 * the channels pane is empty.
153 */
154 @Override
155 public JSChannel
156 getFirstChannel() { return listModel.size() == 0 ? null : (JSChannel)listModel.get(0); }
157
158 /**
159 * Gets the last channel in this channels pane.
160 * @return The last channel in this channels pane or <code>null</code> if
161 * the channels pane is empty.
162 */
163 @Override
164 public JSChannel
165 getLastChannel() {
166 return listModel.size() == 0 ? null : (JSChannel)listModel.get(listModel.size()-1);
167 }
168
169 /**
170 * Gets the channel at the specified index.
171 * @return The channel at the specified index.
172 * @throws ArrayIndexOutOfBoundsException If the index is out of range.
173 */
174 @Override
175 public JSChannel
176 getChannel(int idx) { return (JSChannel)listModel.get(idx); }
177
178 /**
179 * Gets an array with all channels in this channels pane.
180 * @return An array with all channels in this channels pane.
181 */
182 @Override
183 public JSChannel[]
184 getChannels() {
185 JSChannel[] chns = new JSChannel[listModel.size()];
186 for(int i = 0; i < listModel.size(); i++) chns[i] = (JSChannel)listModel.get(i);
187 return chns;
188 }
189
190 /**
191 * Gets the number of channels in this channels pane.
192 * @return The number of channels in this channels pane.
193 */
194 @Override
195 public int
196 getChannelCount() { return listModel.size(); }
197
198 /**
199 * Determines whether there is at least one selected channel.
200 * @return <code>true</code> if there is at least one selected channel,
201 * <code>false</code> otherwise.
202 */
203 @Override
204 public boolean
205 hasSelectedChannel() { return !chnList.isSelectionEmpty(); }
206
207 /**
208 * Gets the number of the selected channels.
209 * @return The number of the selected channels.
210 */
211 @Override
212 public int
213 getSelectedChannelCount() { return chnList.getSelectedIndices().length; }
214
215 /**
216 * Gets an array with all selected channels.
217 * The channels are sorted in increasing index order.
218 * @return The selected channels or an empty array if nothing is selected.
219 */
220 @Override
221 public JSChannel[]
222 getSelectedChannels() {
223 Component[] cS = chnList.getSelectedComponents();
224 JSChannel[] chns = new JSChannel[cS.length];
225 for(int i = 0; i < cS.length; i++) chns[i] = (JSChannel)cS[i];
226 return chns;
227 }
228
229 /**
230 * Removes all selected channels in this channels pane.
231 * Notice that this method does not remove any channels in the back-end.
232 * It is invoked after the channels are already removed in the back-end.
233 * @return The number of removed channels.
234 */
235 @Override
236 public int
237 removeSelectedChannels() {
238 int[] l = chnList.getSelectedIndices();
239 ComponentListModel model = chnList.getModel();
240
241 for(;;) {
242 int i = chnList.getMinSelectionIndex();
243 if(i == -1) break;
244 model.remove(i);
245 }
246
247 firePropertyChange("channelsRemoved", null, null);
248
249 return l.length;
250 }
251
252 /** Selects all channels. */
253 @Override
254 public void
255 selectAll() { chnList.selectAll(); }
256
257 /** Deselects all selected channels. */
258 @Override
259 public void
260 clearSelection() { chnList.clearSelection(); }
261
262 /**
263 * Registers the specified listener for receiving list selection events.
264 * @param listener The <code>ListSelectionListener</code> to register.
265 */
266 @Override
267 public void
268 addListSelectionListener(ListSelectionListener listener) {
269 listenerList.add(ListSelectionListener.class, listener);
270 }
271
272 /**
273 * Removes the specified listener.
274 * @param listener The <code>ListSelectionListener</code> to remove.
275 */
276 @Override
277 public void
278 removeListSelectionListener(ListSelectionListener listener) {
279 listenerList.remove(ListSelectionListener.class, listener);
280 }
281
282 /**
283 * Invoked when the selection has changed.
284 * This method implements <code>valueChanged</code>
285 * method of the <code>ListSelectionListener</code> interface.
286 * @param e A <code>ListSelectionEvent</code>
287 * instance providing the event information.
288 */
289 @Override
290 public void
291 valueChanged(ListSelectionEvent e) {
292 ListSelectionEvent e2 = null;
293 Object[] listeners = listenerList.getListenerList();
294
295 for(int i = listeners.length - 2; i >= 0; i -= 2) {
296 if(listeners[i] == ListSelectionListener.class) {
297 if(e2 == null) e2 = new ListSelectionEvent (
298 this,
299 e.getFirstIndex(),
300 e.getLastIndex(),
301 e.getValueIsAdjusting()
302 );
303 ((ListSelectionListener)listeners[i + 1]).valueChanged(e2);
304 }
305 }
306
307 }
308
309 /**
310 * Determines whether the channel list UI should be automatically updated
311 * when channel is added/removed. The default value is <code>true</code>.
312 * @see updateChannelListUI
313 */
314 @Override
315 public boolean
316 getAutoUpdate() { return chnList.getAutoUpdate(); }
317
318 /**
319 * Determines whether the channel list UI should be automatically updated
320 * when channel is added/removed.
321 * @see updateChannelListUI
322 */
323 @Override
324 public void
325 setAutoUpdate(boolean b) { chnList.setAutoUpdate(b); }
326
327 /**
328 * Updates the channel list UI.
329 * @see setAutoUpdate
330 */
331 @Override
332 public void
333 updateChannelListUI() { chnList.updateList(); }
334
335
336 @Override
337 public void
338 moveSelectedChannelsOnTop() {
339 JSChannel[] chns = getSelectedChannels();
340
341 if(chns.length == 0) {
342 CC.getLogger().info("Can't move channel(s) at the beginning");
343 return;
344 }
345
346 for(int i = chns.length - 1; i >= 0; i--) {
347 listModel.remove(chns[i]);
348 listModel.insert(chns[i], 0);
349 }
350
351 chnList.setSelectionInterval(0, chns.length - 1);
352 chnList.ensureIndexIsVisible(0);
353
354 firePropertyChange("channelsPositionChanged", null, chns);
355 }
356
357 @Override
358 public void
359 moveSelectedChannelsUp() {
360 JSChannel[] chns = getSelectedChannels();
361
362 if(chns.length == 0 || chns[0] == getFirstChannel()) {
363 CC.getLogger().info("Can't move channel(s) up");
364 return;
365 }
366
367 for(int i = 0; i < chns.length; i++) listModel.moveUp(chns[i]);
368
369 int[] si = chnList.getSelectedIndices();
370
371 for(int i = 0; i < si.length; i++) si[i] -= 1;
372
373 chnList.setSelectedIndices(si);
374 chnList.ensureIndexIsVisible(si[0]);
375
376 firePropertyChange("channelsPositionChanged", null, chns);
377 }
378
379 @Override
380 public void
381 moveSelectedChannelsDown() {
382 JSChannel[] chns = getSelectedChannels();
383
384 if(chns.length == 0 || chns[chns.length - 1] == getLastChannel()) {
385 CC.getLogger().info("Can't move channel(s) down");
386 return;
387 }
388
389 for(int i = chns.length - 1; i >= 0; i--) listModel.moveDown(chns[i]);
390
391 int[] si = chnList.getSelectedIndices();
392 for(int i = 0; i < si.length; i++) si[i] += 1;
393 chnList.setSelectedIndices(si);
394 chnList.ensureIndexIsVisible(si[si.length - 1]);
395
396 firePropertyChange("channelsPositionChanged", null, chns);
397 }
398
399 @Override
400 public void
401 moveSelectedChannelsAtBottom() {
402 JSChannel[] chns = getSelectedChannels();
403
404 if(chns.length == 0) {
405 CC.getLogger().info("Can't move channel(s) at the end");
406 return;
407 }
408
409 for(int i = 0; i < chns.length; i++) {
410 listModel.remove(chns[i]);
411 listModel.add(chns[i]);
412 }
413
414 chnList.setSelectionInterval (
415 listModel.getSize() - chns.length, listModel.getSize() - 1
416 );
417 chnList.ensureIndexIsVisible(listModel.getSize() - 1);
418
419 firePropertyChange("channelsPositionChanged", null, chns);
420 }
421
422 private void
423 scrollToBottom() {
424 int h = scrollPane.getViewport().getView().getHeight();
425 scrollPane.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
426 }
427
428 class ContextMenu extends MouseAdapter {
429 private final JPopupMenu cmenu = new JPopupMenu();
430 private final JMenu submenu = new JMenu(i18n.getMenuLabel("channels.MoveToTab"));
431
432 ContextMenu() {
433 JMenuItem mi = new JMenuItem(a4n.moveChannelsOnTop);
434 mi.setIcon(null);
435 cmenu.add(mi);
436
437 mi = new JMenuItem(a4n.moveChannelsUp);
438 mi.setIcon(null);
439 cmenu.add(mi);
440
441 mi = new JMenuItem(a4n.moveChannelsDown);
442 mi.setIcon(null);
443 cmenu.add(mi);
444
445 mi = new JMenuItem(a4n.moveChannelsAtBottom);
446 mi.setIcon(null);
447 cmenu.add(mi);
448
449 cmenu.add(submenu);
450
451 cmenu.addSeparator();
452
453 mi = new JMenuItem(a4n.removeChannels);
454 mi.setIcon(null);
455 cmenu.add(mi);
456 }
457
458 @Override
459 public void
460 mousePressed(MouseEvent e) {
461 if(e.isPopupTrigger()) show(e);
462 }
463
464 @Override
465 public void
466 mouseReleased(MouseEvent e) {
467 if(e.isPopupTrigger()) show(e);
468 }
469
470 void
471 show(MouseEvent e) {
472 /*int idx = chnList.locationToIndex(e.getPoint());
473 if(!chnList.isSelectedIndex(idx)) chnList.setSelectedIndex(idx);
474
475 if(idx != -1 && CC.getMainFrame().getChannelsPaneCount() > 1) {
476 updateMenu();
477 submenu.setEnabled(true);
478 } else submenu.setEnabled(false);
479
480 cmenu.show(e.getComponent(), e.getX(), e.getY());*/
481 }
482
483 private void
484 updateMenu() {
485 submenu.removeAll();
486 Vector<JSChannelsPane> v = CC.getMainFrame().getChannelsPaneList();
487 for(JSChannelsPane p : v)
488 if(p != CC.getMainFrame().getSelectedChannelsPane())
489 submenu.add(new JMenuItem(new A4n.MoveChannelsTo(p)));
490 }
491 }
492
493 @Override
494 public void
495 processChannelSelection(JSChannel c, boolean controlDown, boolean shiftDown) {
496
497 }
498 }

  ViewVC Help
Powered by ViewVC