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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1776 - (hide annotations) (download)
Thu Sep 11 18:48:36 2008 UTC (15 years, 8 months ago) by iliev
File size: 12515 byte(s)
* Implemented virtual MIDI keyboard

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1143 * Copyright (C) 2005-2006 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 787 *
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 iliev 1318 import java.awt.Rectangle;
28 iliev 787
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 iliev 911 import net.sf.juife.ComponentList;
49     import net.sf.juife.ComponentListModel;
50     import net.sf.juife.DefaultComponentListModel;
51    
52 iliev 787 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 iliev 1318
71     private final JScrollPane scrollPane;
72 iliev 787
73 iliev 911 /**
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 iliev 787 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 iliev 1318 scrollPane = new JScrollPane(chnList);
93     scrollPane.setBorder(BorderFactory.createEmptyBorder());
94     add(scrollPane);
95 iliev 787
96     setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
97    
98     }
99    
100 iliev 1776 public void
101     setSelectedChannel(JSChannel channel) {
102     chnList.setSelectedComponent(channel, true);
103     }
104    
105 iliev 787 /**
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 iliev 1318 scrollToBottom();
116 iliev 787 }
117    
118     /**
119     * Adds the specified channels to this channels pane.
120     * @param chns The channels to be added.
121     */
122 iliev 911 public void
123     addChannels(JSChannel[] chns) {
124     if(chns == null || chns.length == 0) return;
125    
126 iliev 787 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 iliev 1734 /**
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 iliev 787
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 iliev 1318 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 iliev 787 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