/[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 1867 - (hide annotations) (download)
Mon Mar 16 22:12:32 2009 UTC (15 years, 2 months ago) by iliev
File size: 13922 byte(s)
* proper handling of connection failures
* renamed Channels Panels to Channel Lanes
* code cleanup

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1864 * Copyright (C) 2005-2009 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 iliev 1864 public 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 iliev 1867
120     public abstract void handleConnectionFailure();
121 iliev 1204
122 iliev 1785 protected Vector<ListSelectionListener> channelsPaneListeners =
123     new Vector<ListSelectionListener>();
124    
125 iliev 1204 /**
126 iliev 1785 * Registers the specified listener for receiving event messages.
127     * @param l The <code>ListSelectionListener</code> to register.
128     */
129     public void
130     addChannelsPaneSelectionListener(ListSelectionListener l) {
131     channelsPaneListeners.add(l);
132     }
133    
134     /**
135     * Removes the specified listener.
136     * @param l The <code>ListSelectionListener</code> to remove.
137     */
138     public void
139     removeChannelsPaneSelectionListener(ListSelectionListener l) {
140     channelsPaneListeners.remove(l);
141     }
142    
143     protected void
144     fireChannelsPaneSelectionChanged() {
145     int i = getChannelsPaneIndex(getSelectedChannelsPane());
146     ListSelectionEvent e = new ListSelectionEvent(this, i, i, false);
147     for(ListSelectionListener l : channelsPaneListeners) l.valueChanged(e);
148     }
149    
150     /**
151 iliev 911 * Returns a list containing all <code>JSChannelsPane</code>s added to the view.
152     * @return A list containing all <code>JSChannelsPane</code>s added to the view.
153     * @see #addChannelsPane
154     * @see #removeChannelsPane
155     */
156 iliev 787 public Vector<JSChannelsPane>
157     getChannelsPaneList() { return chnPaneList; }
158    
159 iliev 911 /**
160     * Return the <code>JSChannelsPane</code> at the specified position.
161     * @param idx The position of the <code>JSChannelsPane</code> to be returned.
162     * @return The <code>JSChannelsPane</code> at the specified position.
163     */
164 iliev 787 public JSChannelsPane
165     getChannelsPane(int idx) { return chnPaneList.get(idx); }
166    
167 iliev 911 /**
168     * Adds the specified <code>JSChannelsPane</code> to the view.
169     * @param chnPane The <code>JSChannelsPane</code> to be added.
170     */
171 iliev 787 public void
172     addChannelsPane(JSChannelsPane chnPane) { chnPaneList.add(chnPane); }
173    
174 iliev 911 /**
175     * Removes the specified <code>JSChannelsPane</code> from the view.
176     * Override this method to remove <code>chnPane</code> from the view,
177     * and don't forget to call <code>super.removeChannelsPane(chnPane);</code>.
178     * @param chnPane The <code>JSChannelsPane</code> to be removed.
179     * @return <code>true</code> if the specified code>JSChannelsPane</code>
180     * is actually removed from the view, <code>false</code> otherwise.
181     */
182 iliev 787 public boolean
183     removeChannelsPane(JSChannelsPane chnPane) { return chnPaneList.remove(chnPane); }
184    
185 iliev 911 /**
186     * Gets the current number of <code>JSChannelsPane</code>s added to the view.
187     * @return The current number of <code>JSChannelsPane</code>s added to the view.
188     */
189 iliev 787 public int
190     getChannelsPaneCount() { return chnPaneList.size(); }
191    
192 iliev 911 /**
193 iliev 1785 * Returns the index of the specified channels pane, or -1 if
194     * the specified channels pane is not found.
195     */
196     public int
197     getChannelsPaneIndex(JSChannelsPane chnPane) {
198     return chnPaneList.indexOf(chnPane);
199     }
200    
201     /**
202 iliev 911 * Inserts the specified <code>JSChannelsPane</code> at the specified position
203     * in the view and in the code>JSChannelsPane</code> list.
204     * Where and how this pane will be shown depends on the view/GUI implementation.
205     * Note that some GUI implementation may have only one pane containing sampler channels.
206     * @param pane The <code>JSChannelsPane</code> to be inserted.
207     * @param idx Specifies the position of the <code>JSChannelsPane</code>.
208     * @see #getChannelsPaneList
209     */
210 iliev 787 public abstract void insertChannelsPane(JSChannelsPane pane, int idx);
211 iliev 911
212     /**
213     * Gets the <code>JSChannelsPane</code> that is currently shown,
214     * or has the focus if more than one channels' panes are shown.
215     * If the GUI implementation has only one pane containing sampler channels,
216     * than this method should always return that pane (the <code>JSChannelsPane</code>
217     * with index 0).
218     * @return The selected <code>JSChannelsPane</code>.
219     */
220 iliev 787 public abstract JSChannelsPane getSelectedChannelsPane();
221 iliev 911
222     /**
223 iliev 1688 * Gets the server address to which to connect. If the server should be
224     * manually selected, a dialog asking the user to choose a server is displayed.
225     */
226     public abstract Server getServer();
227    
228     /**
229     * Gets the server address to which to connect. If the server should be
230     * manually selected, a dialog asking the user to choose a server is displayed.
231     * @param manualSelect Determines whether the server should be manually selected.
232     */
233     public abstract Server getServer(boolean manualSelect);
234    
235     /**
236 iliev 911 * Sets the <code>JSChannelsPane</code> to be selected.
237 iliev 1785 * Note that all registered listeners should be notified
238     * when the selection is changed.
239 iliev 911 * @param pane The <code>JSChannelsPane</code> to be shown.
240 iliev 1785 * @see #fireChannelsPaneSelectionChanged
241 iliev 911 */
242 iliev 787 public abstract void setSelectedChannelsPane(JSChannelsPane pane);
243    
244     private class EventHandler implements SamplerChannelListListener {
245     /**
246     * Invoked when a new sampler channel is created.
247     * @param e A <code>SamplerChannelListEvent</code>
248     * instance providing the event information.
249     */
250 iliev 1785 @Override
251 iliev 787 public void
252     channelAdded(SamplerChannelListEvent e) {
253 iliev 1737 if(e.getChannelModel() == null) return;
254 iliev 1143 Integer id = e.getChannelModel().getChannelId();
255 iliev 787 if(findChannel(id) != null) {
256     CC.getLogger().log(Level.WARNING, "JSMainFrame.channelExist!", id);
257     return;
258     }
259    
260 iliev 1818 ChannelConfig config = null;
261     JSViewConfig viewConfig = CC.getViewConfig();
262     if(viewConfig != null && viewConfig.getSessionViewConfig() != null) {
263     config = viewConfig.getSessionViewConfig().pollChannelConfig();
264     }
265    
266     if(config == null) {
267     getSelectedChannelsPane().addChannel(e.getChannelModel());
268     } else {
269     int i = config.channelsPanel;
270     if(i >= 0 && i < getChannelsPaneCount()) {
271     getChannelsPane(i).addChannel(e.getChannelModel(), config);
272     } else {
273     getSelectedChannelsPane().addChannel(e.getChannelModel(), config);
274     }
275     }
276 iliev 787 }
277    
278     /**
279     * Invoked when a sampler channel is removed.
280     * @param e A <code>SamplerChannelListEvent</code>
281     * instance providing the event information.
282     */
283 iliev 1785 @Override
284 iliev 787 public void
285     channelRemoved(SamplerChannelListEvent e) {
286 iliev 1143 removeChannel(e.getChannelModel().getChannelId());
287 iliev 787 }
288     }
289    
290     /**
291     * Searches for the first occurence of a channel with numerical ID <code>id</code>.
292     * @return The first occurence of a channel with numerical ID <code>id</code> or
293     * <code>null</code> if there is no channel with numerical ID <code>id</code>.
294     */
295     public JSChannel
296     findChannel(int id) {
297     if(id < 0) return null;
298    
299     for(JSChannelsPane cp : getChannelsPaneList()) {
300 iliev 1143 for(JSChannel c : cp.getChannels()) if(c.getChannelId() == id) return c;
301 iliev 787 }
302    
303     return null;
304     }
305    
306     /**
307     * Removes the first occurence of a channel with numerical ID <code>id</code>.
308     * This method is invoked when a sampler channel is removed in the back-end.
309     * @return The removed channel or <code>null</code>
310     * if there is no channel with numerical ID <code>id</code>.
311     */
312     public JSChannel
313     removeChannel(int id) {
314     if(id < 0) return null;
315    
316     for(JSChannelsPane cp : getChannelsPaneList()) {
317     for(JSChannel c : cp.getChannels()) {
318 iliev 1143 if(c.getChannelId() == id) {
319 iliev 787 cp.removeChannel(c);
320     return c;
321     }
322     }
323     }
324    
325     return null;
326     }
327 iliev 1734
328     /**
329 iliev 1785 * Gets the zero-based position of the specified sampler channel
330     * in the channels pane, to which the channel is added.
331     * Note that the position may change when adding/removing sampler channels.
332     * @return The zero-based position of the specified sampler channel
333     * in the channels pane, or -1 if the specified channels is not found.
334     */
335     public int
336     getChannelNumber(SamplerChannelModel channel) {
337     if(channel == null) return -1;
338    
339     for(int i = 0; i < getChannelsPaneCount(); i++) {
340     JSChannelsPane chnPane = getChannelsPane(i);
341     for(int j = 0; j < chnPane.getChannelCount(); j++) {
342     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
343     return j;
344     }
345     }
346     }
347    
348     return -1;
349     }
350    
351     /**
352     * Returns a string in the format <code>channelPaneNumber/channelNumber</code>,
353     * where <code>channelPaneNumber</code> is the one-based number of the channels
354     * pane containing the specified channel and <code>channelNumber</code> is the
355     * one-based number of the channel's position in the channels pane.
356     * Note that this path may change when adding/removing channels/channels panes.
357     * @return The channels path, or <code>null</code> if the specified channels is not found.
358     */
359     public String
360     getChannelPath(SamplerChannelModel channel) {
361     if(channel == null) return null;
362    
363     for(int i = 0; i < getChannelsPaneCount(); i++) {
364     JSChannelsPane chnPane = getChannelsPane(i);
365     for(int j = 0; j < chnPane.getChannelCount(); j++) {
366     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
367 iliev 1818 return (i + 1) + "." + (j + 1);
368 iliev 1785 }
369     }
370     }
371    
372     return null;
373     }
374    
375     /**
376     * Gets the zero-based number of the channels pane,
377     * to which the specified sampler channel is added.
378     * Note that the can be moved from one channels pane to another.
379     * @return The zero-based index of the channels pane,
380     * to which the specified sampler channel is added, or
381     * -1 if the specified channels is not found.
382     */
383     public int
384     getChannelsPaneNumber(SamplerChannelModel channel) {
385     if(channel == null) return -1;
386    
387     for(int i = 0; i < getChannelsPaneCount(); i++) {
388     JSChannelsPane chnPane = getChannelsPane(i);
389     for(int j = 0; j < chnPane.getChannelCount(); j++) {
390     if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
391     return i;
392     }
393     }
394     }
395    
396     return -1;
397     }
398    
399     /**
400 iliev 1786 * Sends the specified script to the backend.
401     * @param script The file name of the script to run.
402     */
403     public abstract void runScript(String script);
404    
405     /**
406 iliev 1734 * Determines whether the channel list UI should be automatically updated
407     * when channel is added/removed. The default value is <code>true</code>.
408     */
409     public boolean
410     getAutoUpdateChannelListUI() { return autoUpdateChannelListUI; }
411    
412     /**
413     * Determines whether the channel list UI should be automatically updated
414     * when channel is added/removed.
415     */
416     public void
417     setAutoUpdateChannelListUI(boolean b) {
418     if(b == autoUpdateChannelListUI) return;
419    
420     autoUpdateChannelListUI = b;
421     for(JSChannelsPane cp : getChannelsPaneList()) {
422     cp.setAutoUpdate(b);
423     }
424     }
425    
426     /**
427     * Updates the channel list UI.
428     */
429     public void
430     updateChannelListUI() {
431     for(JSChannelsPane cp : getChannelsPaneList()) {
432     cp.updateChannelListUI();
433     }
434     }
435 iliev 787 }

  ViewVC Help
Powered by ViewVC