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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1786 - (show annotations) (download)
Wed Oct 8 22:38:15 2008 UTC (15 years, 6 months ago) by iliev
File size: 13305 byte(s)
* Implemented option to launch the backend if it is not yet started
  (choose Edit/Preferences, then click the `Backend' tab)
* LSCP scripts can now be run by passing them to jsampler
  as command-line arguments
* The scripts in the `scripts' directory now pass the command-line
  arguments to the respective jsampler distribution
* ant: the default target is now build-fantasia
* bugfix: backend address was always set to 127.0.0.1 when adding
  backend to the backend list

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

  ViewVC Help
Powered by ViewVC