/[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 1318 - (show annotations) (download)
Sat Sep 1 13:46:04 2007 UTC (16 years, 8 months ago) by iliev
File size: 11799 byte(s)
* Fantasia: Added scrollbar to the channels pane
* Implemented automatic scrolling when new channel is
  created to ensure that it is visible on the screen

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 public void
283 moveSelectedChannelsOnTop() {
284 JSChannel[] chns = getSelectedChannels();
285
286 if(chns.length == 0) {
287 CC.getLogger().info("Can't move channel(s) at the beginning");
288 return;
289 }
290
291 for(int i = chns.length - 1; i >= 0; i--) {
292 listModel.remove(chns[i]);
293 listModel.insert(chns[i], 0);
294 }
295
296 chnList.setSelectionInterval(0, chns.length - 1);
297 chnList.ensureIndexIsVisible(0);
298 }
299
300 public void
301 moveSelectedChannelsUp() {
302 JSChannel[] chns = getSelectedChannels();
303
304 if(chns.length == 0 || chns[0] == getFirstChannel()) {
305 CC.getLogger().info("Can't move channel(s) up");
306 return;
307 }
308
309 for(int i = 0; i < chns.length; i++) listModel.moveUp(chns[i]);
310
311 int[] si = chnList.getSelectedIndices();
312
313 for(int i = 0; i < si.length; i++) si[i] -= 1;
314
315 chnList.setSelectedIndices(si);
316 chnList.ensureIndexIsVisible(si[0]);
317 }
318
319 public void
320 moveSelectedChannelsDown() {
321 JSChannel[] chns = getSelectedChannels();
322
323 if(chns.length == 0 || chns[chns.length - 1] == getLastChannel()) {
324 CC.getLogger().info("Can't move channel(s) down");
325 return;
326 }
327
328 for(int i = chns.length - 1; i >= 0; i--) listModel.moveDown(chns[i]);
329
330 int[] si = chnList.getSelectedIndices();
331 for(int i = 0; i < si.length; i++) si[i] += 1;
332 chnList.setSelectedIndices(si);
333 chnList.ensureIndexIsVisible(si[si.length - 1]);
334 }
335
336 public void
337 moveSelectedChannelsAtBottom() {
338 JSChannel[] chns = getSelectedChannels();
339
340 if(chns.length == 0) {
341 CC.getLogger().info("Can't move channel(s) at the end");
342 return;
343 }
344
345 for(int i = 0; i < chns.length; i++) {
346 listModel.remove(chns[i]);
347 listModel.add(chns[i]);
348 }
349
350 chnList.setSelectionInterval (
351 listModel.getSize() - chns.length, listModel.getSize() - 1
352 );
353 chnList.ensureIndexIsVisible(listModel.getSize() - 1);
354 }
355
356 private void
357 scrollToBottom() {
358 int h = scrollPane.getViewport().getView().getHeight();
359 scrollPane.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
360 }
361
362 class ContextMenu extends MouseAdapter {
363 private final JPopupMenu cmenu = new JPopupMenu();
364 private final JMenu submenu = new JMenu(i18n.getMenuLabel("channels.MoveToTab"));
365
366 ContextMenu() {
367 JMenuItem mi = new JMenuItem(A4n.moveChannelsOnTop);
368 mi.setIcon(null);
369 cmenu.add(mi);
370
371 mi = new JMenuItem(A4n.moveChannelsUp);
372 mi.setIcon(null);
373 cmenu.add(mi);
374
375 mi = new JMenuItem(A4n.moveChannelsDown);
376 mi.setIcon(null);
377 cmenu.add(mi);
378
379 mi = new JMenuItem(A4n.moveChannelsAtBottom);
380 mi.setIcon(null);
381 cmenu.add(mi);
382
383 cmenu.add(submenu);
384
385 cmenu.addSeparator();
386
387 mi = new JMenuItem(A4n.removeChannels);
388 mi.setIcon(null);
389 cmenu.add(mi);
390 }
391
392 public void
393 mousePressed(MouseEvent e) {
394 if(e.isPopupTrigger()) show(e);
395 }
396
397 public void
398 mouseReleased(MouseEvent e) {
399 if(e.isPopupTrigger()) show(e);
400 }
401
402 void
403 show(MouseEvent e) {
404 /*int idx = chnList.locationToIndex(e.getPoint());
405 if(!chnList.isSelectedIndex(idx)) chnList.setSelectedIndex(idx);
406
407 if(idx != -1 && CC.getMainFrame().getChannelsPaneCount() > 1) {
408 updateMenu();
409 submenu.setEnabled(true);
410 } else submenu.setEnabled(false);
411
412 cmenu.show(e.getComponent(), e.getX(), e.getY());*/
413 }
414
415 private void
416 updateMenu() {
417 submenu.removeAll();
418 Vector<JSChannelsPane> v = CC.getMainFrame().getChannelsPaneList();
419 for(JSChannelsPane p : v)
420 if(p != CC.getMainFrame().getSelectedChannelsPane())
421 submenu.add(new JMenuItem(new A4n.MoveChannelsTo(p)));
422 }
423 }
424 }

  ViewVC Help
Powered by ViewVC