/[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 1734 - (show annotations) (download)
Sun May 4 18:40:13 2008 UTC (15 years, 10 months ago) by iliev
File size: 12409 byte(s)
* bugfix: JSampler took forever to load a configuration with
  too many sampler channels
* Implemented option to show different channel view when
  the mouse pointer is over sampler channel
  (choose Edit/Preferences, then click the `Defaults' tab)

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

  ViewVC Help
Powered by ViewVC