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

Annotation of /jsampler/trunk/src/org/jsampler/view/JSMainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1818 - (hide annotations) (download)
Wed Dec 24 17:29:47 2008 UTC (15 years, 4 months ago) by iliev
File size: 13875 byte(s)
* Added support for controlling the global sampler-wide limit of
  maximum voices and disk streams
  (choose Edit/Preferences, then click the `General' tab)
* Fantasia: store the view configuration of audio/MIDI devices and sampler
  channels in the LSCP script when exporting sampler configuration
* Fantasia: Implemented multiple sampler channels' selection
* Fantasia: Added option to move sampler channels up and down
  in the channels list
* Fantasia: Added option to move sampler channels
  to another channels panels

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1785 * Copyright (C) 2005-2008 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;
24    
25 iliev 1204 import java.awt.Dialog;
26     import java.awt.Frame;
27 iliev 842
28 iliev 1734 import java.awt.event.ActionEvent;
29     import java.awt.event.KeyEvent;
30 iliev 787 import java.awt.event.WindowAdapter;
31     import java.awt.event.WindowEvent;
32    
33     import java.util.Vector;
34     import java.util.logging.Level;
35    
36 iliev 1734 import javax.swing.AbstractAction;
37     import javax.swing.JComponent;
38 iliev 787 import javax.swing.JFrame;
39 iliev 1734 import javax.swing.KeyStroke;
40 iliev 787
41 iliev 1785 import javax.swing.event.ListSelectionEvent;
42     import javax.swing.event.ListSelectionListener;
43 iliev 1818
44 iliev 787 import org.jsampler.CC;
45     import org.jsampler.JSampler;
46 iliev 1785 import org.jsampler.SamplerChannelModel;
47 iliev 1688 import org.jsampler.Server;
48 iliev 787
49     import org.jsampler.event.SamplerChannelListEvent;
50     import org.jsampler.event.SamplerChannelListListener;
51    
52 iliev 1818 import org.jsampler.view.SessionViewConfig.ChannelConfig;
53 iliev 1204
54 iliev 1818
55 iliev 787 /**
56 iliev 911 * Defines the skeleton of a JSampler's main frame.
57 iliev 787 * @author Grigor Iliev
58     */
59     public abstract class JSMainFrame extends JFrame {
60     private final Vector<JSChannelsPane> chnPaneList = new Vector<JSChannelsPane>();
61 iliev 1734 private boolean autoUpdateChannelListUI = true;
62 iliev 787
63 iliev 911 /** Creates a new instance of <code>JSMainFrame</code>. */
64 iliev 787 public
65     JSMainFrame() {
66     super(JSampler.NAME + ' ' + JSampler.VERSION);
67    
68     setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
69     addWindowListener(new WindowAdapter() {
70     public void
71 iliev 842 windowClosing(WindowEvent we) { onWindowClose(); }
72 iliev 787 });
73    
74     CC.getSamplerModel().addSamplerChannelListListener(new EventHandler());
75 iliev 1734
76     getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
77     KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK),
78     "RunGarbageCollector"
79     );
80    
81     getRootPane().getActionMap().put ("RunGarbageCollector", new AbstractAction() {
82     public void
83     actionPerformed(ActionEvent e) {
84     System.gc();
85     }
86     });
87 iliev 787 }
88    
89 iliev 911 /**
90     * Invoked when this window is about to close.
91     * Don't forget to call <code>super.onWindowClose()</code> at the end,
92     * when override this method.
93     */
94     protected void
95 iliev 842 onWindowClose() {
96     CC.cleanExit();
97     }
98    
99 iliev 911 /**
100 iliev 1143 * Invoked on startup when no JSampler home directory is specified
101     * or the specified JSampler home directory doesn't exist.
102     * This method should ask the user to specify a JSampler
103     * home directory and then set the specified JSampler home directory using
104     * {@link org.jsampler.CC#setJSamplerHome} method.
105     * @see org.jsampler.CC#getJSamplerHome
106     * @see org.jsampler.CC#setJSamplerHome
107     */
108     public abstract void installJSamplerHome();
109    
110     /**
111 iliev 1204 * Shows a detailed error information about the specified exception.
112     */
113     public abstract void showDetailedErrorMessage(Frame owner, String err, String details);
114    
115     /**
116     * Shows a detailed error information about the specified exception.
117     */
118     public abstract void showDetailedErrorMessage(Dialog owner, String err, String details);
119    
120 iliev 1785 protected Vector<ListSelectionListener> channelsPaneListeners =
121     new Vector<ListSelectionListener>();
122    
123 iliev 1204 /**
124 iliev 1785 * Registers the specified listener for receiving event messages.
125     * @param l The <code>ListSelectionListener</code> to register.
126     */
127     public void
128     addChannelsPaneSelectionListener(ListSelectionListener l) {
129     channelsPaneListeners.add(l);
130     }
131    
132     /**
133     * Removes the specified listener.
134     * @param l The <code>ListSelectionListener</code> to remove.
135     */
136     public void
137     removeChannelsPaneSelectionListener(ListSelectionListener l) {
138     channelsPaneListeners.remove(l);
139     }
140    
141     protected void
142     fireChannelsPaneSelectionChanged() {
143     int i = getChannelsPaneIndex(getSelectedChannelsPane());
144     ListSelectionEvent e = new ListSelectionEvent(this, i, i, false);
145     for(ListSelectionListener l : channelsPaneListeners) l.valueChanged(e);
146     }
147    
148     /**
149 iliev 911 * Returns a list containing all <code>JSChannelsPane</code>s added to the view.
150     * @return A list containing all <code>JSChannelsPane</code>s added to the view.
151     * @see #addChannelsPane
152     * @see #removeChannelsPane
153     */
154 iliev 787 public Vector<JSChannelsPane>
155     getChannelsPaneList() { return chnPaneList; }
156    
157 iliev 911 /**
158     * Return the <code>JSChannelsPane</code> at the specified position.
159     * @param idx The position of the <code>JSChannelsPane</code> to be returned.
160     * @return The <code>JSChannelsPane</code> at the specified position.
161     */
162 iliev 787 public JSChannelsPane
163     getChannelsPane(int idx) { return chnPaneList.get(idx); }
164    
165 iliev 911 /**
166     * Adds the specified <code>JSChannelsPane</code> to the view.
167     * @param chnPane The <code>JSChannelsPane</code> to be added.
168     */
169 iliev 787 public void
170     addChannelsPane(JSChannelsPane chnPane) { chnPaneList.add(chnPane); }
171    
172 iliev 911 /**
173     * Removes the specified <code>JSChannelsPane</code> from the view.
174     * Override this method to remove <code>chnPane</code> from the view,
175     * and don't forget to call <code>super.removeChannelsPane(chnPane);</code>.
176     * @param chnPane The <code>JSChannelsPane</code> to be removed.
177     * @return <code>true</code> if the specified code>JSChannelsPane</code>
178     * is actually removed from the view, <code>false</code> otherwise.
179     */
180 iliev 787 public boolean
181     removeChannelsPane(JSChannelsPane chnPane) { return chnPaneList.remove(chnPane); }
182    
183 iliev 911 /**
184     * Gets the current number of <code>JSChannelsPane</code>s added to the view.
185     * @return The current number of <code>JSChannelsPane</code>s added to the view.
186     */
187 iliev 787 public int
188     getChannelsPaneCount() { return chnPaneList.size(); }
189    
190 iliev 911 /**
191 iliev 1785 * Returns the index of the specified channels pane, or -1 if
192     * the specified channels pane is not found.
193     */
194     public int
195     getChannelsPaneIndex(JSChannelsPane chnPane) {
196     return chnPaneList.indexOf(chnPane);
197     }
198    
199     /**
200 iliev 911 * Inserts the specified <code>JSChannelsPane</code> at the specified position
201     * in the view and in the code>JSChannelsPane</code> list.
202     * Where and how this pane will be shown depends on the view/GUI implementation.
203     * Note that some GUI implementation may have only one pane containing sampler channels.
204     * @param pane The <code>JSChannelsPane</code> to be inserted.
205     * @param idx Specifies the position of the <code>JSChannelsPane</code>.
206     * @see #getChannelsPaneList
207     */
208 iliev 787 public abstract void insertChannelsPane(JSChannelsPane pane, int idx);
209 iliev 911
210     /**
211     * Gets the <code>JSChannelsPane</code> that is currently shown,
212     * or has the focus if more than one channels' panes are shown.
213     * If the GUI implementation has only one pane containing sampler channels,
214     * than this method should always return that pane (the <code>JSChannelsPane</code>
215     * with index 0).
216     * @return The selected <code>JSChannelsPane</code>.
217     */
218 iliev 787 public abstract JSChannelsPane getSelectedChannelsPane();
219 iliev 911
220     /**
221 iliev 1688 * Gets the server address to which to connect. If the server should be
222     * manually selected, a dialog asking the user to choose a server is displayed.
223     */
224     public abstract Server getServer();
225    
226     /**
227     * Gets the server address to which to connect. If the server should be
228     * manually selected, a dialog asking the user to choose a server is displayed.
229     * @param manualSelect Determines whether the server should be manually selected.
230     */
231     public abstract Server getServer(boolean manualSelect);
232    
233     /**
234 iliev 911 * Sets the <code>JSChannelsPane</code> to be selected.
235 iliev 1785 * Note that all registered listeners should be notified
236     * when the selection is changed.
237 iliev 911 * @param pane The <code>JSChannelsPane</code> to be shown.
238 iliev 1785 * @see #fireChannelsPaneSelectionChanged
239 iliev 911 */
240 iliev 787 public abstract void setSelectedChannelsPane(JSChannelsPane pane);
241    
242     private class EventHandler implements SamplerChannelListListener {
243     /**
244     * Invoked when a new sampler channel is created.
245     * @param e A <code>SamplerChannelListEvent</code>
246     * instance providing the event information.
247     */
248 iliev 1785 @Override
249 iliev 787 public void
250     channelAdded(SamplerChannelListEvent e) {
251 iliev 1737 if(e.getChannelModel() == null) return;
252 iliev 1143 Integer id = e.getChannelModel().getChannelId();
253 iliev 787 if(findChannel(id) != null) {
254     CC.getLogger().log(Level.WARNING, "JSMainFrame.channelExist!", id);
255     return;
256     }
257    
258 iliev 1818 ChannelConfig config = null;
259     JSViewConfig viewConfig = CC.getViewConfig();
260     if(viewConfig != null && viewConfig.getSessionViewConfig() != null) {
261     config = viewConfig.getSessionViewConfig().pollChannelConfig();
262     }
263    
264     if(config == null) {
265     getSelectedChannelsPane().addChannel(e.getChannelModel());
266     } else {
267     int i = config.channelsPanel;
268     if(i >= 0 && i < getChannelsPaneCount()) {
269     getChannelsPane(i).addChannel(e.getChannelModel(), config);
270     } else {
271     getSelectedChannelsPane().addChannel(e.getChannelModel(), config);
272     }
273     }
274 iliev 787 }
275    
276     /**
277     * Invoked when a sampler channel is removed.
278     * @param e A <code>SamplerChannelListEvent</code>
279     * instance providing the event information.
280     */
281 iliev 1785 @Override
282 iliev 787 public void
283     channelRemoved(SamplerChannelListEvent e) {
284 iliev 1143 removeChannel(e.getChannelModel().getChannelId());
285 iliev 787 }
286     }
287    
288     /**
289     * Searches for the first occurence of a channel with numerical ID <code>id</code>.
290     * @return The first occurence of a channel with numerical ID <code>id</code> or
291     * <code>null</code> if there is no channel with numerical ID <code>id</code>.
292     */
293     public JSChannel
294     findChannel(int id) {
295     if(id < 0) return null;
296    
297     for(JSChannelsPane cp : getChannelsPaneList()) {
298 iliev 1143 for(JSChannel c : cp.getChannels()) if(c.getChannelId() == id) return c;
299 iliev 787 }
300    
301     return null;
302     }
303    
304     /**
305     * Removes the first occurence of a channel with numerical ID <code>id</code>.
306     * This method is invoked when a sampler channel is removed in the back-end.
307     * @return The removed channel or <code>null</code>
308     * if there is no channel with numerical ID <code>id</code>.
309     */
310     public JSChannel
311     removeChannel(int id) {
312     if(id < 0) return null;
313    
314     for(JSChannelsPane cp : getChannelsPaneList()) {
315     for(JSChannel c : cp.getChannels()) {
316 iliev 1143 if(c.getChannelId() == id) {
317 iliev 787 cp.removeChannel(c);
318     return c;
319     }
320     }
321     }
322    
323     return null;
324     }
325 iliev 1734
326     /**
327 iliev 1785 * Gets the zero-based position of the specified sampler channel
328     * in the channels pane, to which the channel is added.
329     * Note that the position may change when adding/removing sampler channels.
330     * @return The zero-based position of the specified sampler channel
331     * in the channels pane, or -1 if the specified channels is not found.
332     */
333     public int
334     getChannelNumber(SamplerChannelModel channel) {
335     if(channel == null) return -1;
336    
337     for(int i = 0; i < getChannelsPaneCount(); i++) {
338     JSChannelsPane chnPane = getChannelsPane(i);
339     for(int j = 0; j < chnPane.getChannelCount(); j++) {
340     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
341     return j;
342     }
343     }
344     }
345    
346     return -1;
347     }
348    
349     /**
350     * Returns a string in the format <code>channelPaneNumber/channelNumber</code>,
351     * where <code>channelPaneNumber</code> is the one-based number of the channels
352     * pane containing the specified channel and <code>channelNumber</code> is the
353     * one-based number of the channel's position in the channels pane.
354     * Note that this path may change when adding/removing channels/channels panes.
355     * @return The channels path, or <code>null</code> if the specified channels is not found.
356     */
357     public String
358     getChannelPath(SamplerChannelModel channel) {
359     if(channel == null) return null;
360    
361     for(int i = 0; i < getChannelsPaneCount(); i++) {
362     JSChannelsPane chnPane = getChannelsPane(i);
363     for(int j = 0; j < chnPane.getChannelCount(); j++) {
364     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
365 iliev 1818 return (i + 1) + "." + (j + 1);
366 iliev 1785 }
367     }
368     }
369    
370     return null;
371     }
372    
373     /**
374     * Gets the zero-based number of the channels pane,
375     * to which the specified sampler channel is added.
376     * Note that the can be moved from one channels pane to another.
377     * @return The zero-based index of the channels pane,
378     * to which the specified sampler channel is added, or
379     * -1 if the specified channels is not found.
380     */
381     public int
382     getChannelsPaneNumber(SamplerChannelModel channel) {
383     if(channel == null) return -1;
384    
385     for(int i = 0; i < getChannelsPaneCount(); i++) {
386     JSChannelsPane chnPane = getChannelsPane(i);
387     for(int j = 0; j < chnPane.getChannelCount(); j++) {
388     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
389     return i;
390     }
391     }
392     }
393    
394     return -1;
395     }
396    
397     /**
398 iliev 1786 * Sends the specified script to the backend.
399     * @param script The file name of the script to run.
400     */
401     public abstract void runScript(String script);
402    
403     /**
404 iliev 1734 * Determines whether the channel list UI should be automatically updated
405     * when channel is added/removed. The default value is <code>true</code>.
406     */
407     public boolean
408     getAutoUpdateChannelListUI() { return autoUpdateChannelListUI; }
409    
410     /**
411     * Determines whether the channel list UI should be automatically updated
412     * when channel is added/removed.
413     */
414     public void
415     setAutoUpdateChannelListUI(boolean b) {
416     if(b == autoUpdateChannelListUI) return;
417    
418     autoUpdateChannelListUI = b;
419     for(JSChannelsPane cp : getChannelsPaneList()) {
420     cp.setAutoUpdate(b);
421     }
422     }
423    
424     /**
425     * Updates the channel list UI.
426     */
427     public void
428     updateChannelListUI() {
429     for(JSChannelsPane cp : getChannelsPaneList()) {
430     cp.updateChannelListUI();
431     }
432     }
433 iliev 787 }

  ViewVC Help
Powered by ViewVC