/[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 1776 - (show annotations) (download)
Thu Sep 11 18:48:36 2008 UTC (15 years, 7 months ago) by iliev
File size: 12515 byte(s)
* Implemented virtual MIDI keyboard

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

  ViewVC Help
Powered by ViewVC