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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2287 by iliev, Sun Jul 3 22:01:16 2011 UTC revision 2288 by iliev, Wed Nov 23 21:19:44 2011 UTC
# Line 1  Line 1 
1  /*  /*
2   *   JSampler - a java front-end for LinuxSampler   *   JSampler - a java front-end for LinuxSampler
3   *   *
4   *   Copyright (C) 2005-2009 Grigor Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2011 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 22  Line 22 
22    
23  package org.jsampler.view;  package org.jsampler.view;
24    
 import java.awt.Dialog;  
 import java.awt.Frame;  
   
 import java.awt.event.ActionEvent;  
 import java.awt.event.KeyEvent;  
 import java.awt.event.WindowAdapter;  
 import java.awt.event.WindowEvent;  
   
25  import java.util.Vector;  import java.util.Vector;
 import java.util.logging.Level;  
   
 import javax.swing.AbstractAction;  
 import javax.swing.JComponent;  
 import javax.swing.JFrame;  
 import javax.swing.KeyStroke;  
   
 import javax.swing.event.ListSelectionEvent;  
 import javax.swing.event.ListSelectionListener;  
26    
27  import org.jsampler.CC;  import org.jsampler.CC;
 import org.jsampler.JSampler;  
28  import org.jsampler.LSConsoleModel;  import org.jsampler.LSConsoleModel;
29  import org.jsampler.SamplerChannelModel;  import org.jsampler.SamplerChannelModel;
30  import org.jsampler.Server;  import org.jsampler.Server;
31    import org.jsampler.event.ListSelectionListener;
 import org.jsampler.event.SamplerChannelListEvent;  
 import org.jsampler.event.SamplerChannelListListener;  
   
 import org.jsampler.view.SessionViewConfig.ChannelConfig;  
32    
33    
34  /**  /**
35   * Defines the skeleton of a JSampler's main frame.   * Defines the skeleton of a JSampler's main frame.
36   * @author Grigor Iliev   * @author Grigor Iliev
37   */   */
38  public abstract class JSMainFrame extends JFrame {  public interface JSMainFrame<CP extends JSChannelsPane> {
         private final Vector<JSChannelsPane> chnPaneList = new Vector<JSChannelsPane>();  
         private boolean autoUpdateChannelListUI = true;  
           
         /** Creates a new instance of <code>JSMainFrame</code>. */  
         public  
         JSMainFrame() {  
                 super(JSampler.NAME + ' ' + JSampler.VERSION);  
                   
                 setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);  
                 addWindowListener(new WindowAdapter() {  
                         public void  
                         windowClosing(WindowEvent we) { onWindowClose(); }  
                 });  
                   
                 CC.getSamplerModel().addSamplerChannelListListener(new EventHandler());  
                   
                 getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (  
                         KeyStroke.getKeyStroke(KeyEvent.VK_G, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK),  
                         "RunGarbageCollector"  
                 );  
                   
                 getRootPane().getActionMap().put ("RunGarbageCollector", new AbstractAction() {  
                         public void  
                         actionPerformed(ActionEvent e) {  
                                 System.gc();  
                         }  
                 });  
         }  
           
39          /**          /**
40           * Invoked when this window is about to close.           * Invoked when this window is about to close.
41           * Don't forget to call <code>super.onWindowClose()</code> at the end,           * Don't forget to call <code>super.onWindowClose()</code> at the end,
42           * when override this method.           * when override this method.
43           */           */
44          public void          public void onWindowClose();
         onWindowClose() {  
                 CC.cleanExit();  
         }  
45                    
46          /**          /**
47           * Invoked on startup when no JSampler home directory is specified           * Invoked on startup when no JSampler home directory is specified
# Line 106  public abstract class JSMainFrame extend Line 52  public abstract class JSMainFrame extend
52           * @see org.jsampler.CC#getJSamplerHome           * @see org.jsampler.CC#getJSamplerHome
53           * @see org.jsampler.CC#setJSamplerHome           * @see org.jsampler.CC#setJSamplerHome
54           */           */
55          public abstract void installJSamplerHome();          public void installJSamplerHome();
           
         /**  
          * Shows a detailed error information about the specified exception.  
          */  
         public abstract void showDetailedErrorMessage(Frame owner, String err, String details);  
56                    
57          /**          /** Shows a detailed error information about the specified exception. */
58           * Shows a detailed error information about the specified exception.          public void showDetailedErrorMessage(String err, String details);
          */  
         public abstract void showDetailedErrorMessage(Dialog owner, String err, String details);  
   
         public abstract void handleConnectionFailure();  
59                    
60          protected Vector<ListSelectionListener> channelsPaneListeners =          public void handleConnectionFailure();
                 new Vector<ListSelectionListener>();  
61                    
62          /**          /**
63           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
64           * @param l The <code>ListSelectionListener</code> to register.           * @param l The <code>ListSelectionListener</code> to register.
65           */           */
66          public void          public void
67          addChannelsPaneSelectionListener(ListSelectionListener l) {          addChannelsPaneSelectionListener(ListSelectionListener l);
                 channelsPaneListeners.add(l);  
         }  
68                    
69          /**          /**
70           * Removes the specified listener.           * Removes the specified listener.
71           * @param l The <code>ListSelectionListener</code> to remove.           * @param l The <code>ListSelectionListener</code> to remove.
72           */           */
73          public void          public void
74          removeChannelsPaneSelectionListener(ListSelectionListener l) {          removeChannelsPaneSelectionListener(ListSelectionListener l);
                 channelsPaneListeners.remove(l);  
         }  
           
         protected void  
         fireChannelsPaneSelectionChanged() {  
                 int i = getChannelsPaneIndex(getSelectedChannelsPane());  
                 ListSelectionEvent e = new ListSelectionEvent(this, i, i, false);  
                 for(ListSelectionListener l : channelsPaneListeners) l.valueChanged(e);  
         }  
75                    
76          /**          /**
77           * Returns a list containing all <code>JSChannelsPane</code>s added to the view.           * Returns a list containing all channels' panes added to the view.
78           * @return A list containing all <code>JSChannelsPane</code>s added to the view.           * @return A list containing all channels' panes added to the view.
79           * @see #addChannelsPane           * @see #addChannelsPane
80           * @see #removeChannelsPane           * @see #removeChannelsPane
81           */           */
82          public Vector<JSChannelsPane>          public Vector<CP> getChannelsPaneList();
         getChannelsPaneList() { return chnPaneList; }  
83                    
84          /**          /**
85           * Return the <code>JSChannelsPane</code> at the specified position.           * Return the channels' pane at the specified position.
86           * @param idx The position of the <code>JSChannelsPane</code> to be returned.           * @param idx The position of the channels' pane to be returned.
87           * @return The <code>JSChannelsPane</code> at the specified position.           * @return The channels' pane at the specified position.
88           */           */
89          public JSChannelsPane          public CP getChannelsPane(int idx);
         getChannelsPane(int idx) { return chnPaneList.get(idx); }  
90                    
91          /**          /**
92           * Adds the specified <code>JSChannelsPane</code> to the view.           * Adds the specified channels' pane to the view.
93           * @param chnPane The <code>JSChannelsPane</code> to be added.           * @param chnPane The channels' pane to be added.
94           */           */
95          public void          public void addChannelsPane(CP chnPane);
         addChannelsPane(JSChannelsPane chnPane) {  
                 chnPaneList.add(chnPane);  
                 firePropertyChange("channelLaneAdded", null, chnPane);  
         }  
96                    
97          /**          /**
98           * Removes the specified <code>JSChannelsPane</code> from the view.           * Removes the specified channels' pane from the view.
99           * Override this method to remove <code>chnPane</code> from the view,           * Override this method to remove <code>chnPane</code> from the view,
100           * and don't forget to call <code>super.removeChannelsPane(chnPane);</code>.           * and don't forget to call <code>super.removeChannelsPane(chnPane);</code>.
101           * @param chnPane The <code>JSChannelsPane</code> to be removed.           * @param chnPane The channels' pane to be removed.
102           * @return <code>true</code> if the specified code>JSChannelsPane</code>           * @return <code>true</code> if the specified code>JSChannelsPane</code>
103           * is actually removed from the view, <code>false</code> otherwise.           * is actually removed from the view, <code>false</code> otherwise.
104           */           */
105          public boolean          public boolean removeChannelsPane(CP chnPane);
         removeChannelsPane(JSChannelsPane chnPane) {  
                 boolean b = chnPaneList.remove(chnPane);  
                 firePropertyChange("channelLaneRemoved", null, chnPane);  
                 return b;  
         }  
106                    
107          /**          /**
108           * Gets the current number of <code>JSChannelsPane</code>s added to the view.           * Gets the current number of channels' panes added to the view.
109           * @return The current number of <code>JSChannelsPane</code>s added to the view.           * @return The current number of channels' panes added to the view.
110           */           */
111          public int          public int getChannelsPaneCount();
         getChannelsPaneCount() { return chnPaneList.size(); }  
112                    
113          /**          /**
114           * Returns the index of the specified channels pane, or -1 if           * Returns the index of the specified channels pane, or -1 if
115           * the specified channels pane is not found.           * the specified channels pane is not found.
116           */           */
117          public int          public int getChannelsPaneIndex(CP chnPane);
118          getChannelsPaneIndex(JSChannelsPane chnPane) {          
119                  return chnPaneList.indexOf(chnPane);          public void setVisible(boolean b);
         }  
120                    
121          /**          /**
122           * Inserts the specified <code>JSChannelsPane</code> at the specified position           * Inserts the specified channels' pane at the specified position
123           * in the view and in the <code>JSChannelsPane</code> list.           * in the view and in the channels' pane list.
124           * Where and how this pane will be shown depends on the view/GUI implementation.           * Where and how this pane will be shown depends on the view/GUI implementation.
125           * Note that some GUI implementation may have only one pane containing sampler channels.           * Note that some GUI implementation may have only one pane containing sampler channels.
126           * @param pane The <code>JSChannelsPane</code> to be inserted.           * @param pane The channels' pane to be inserted.
127           * @param idx Specifies the position of the <code>JSChannelsPane</code>.           * @param idx Specifies the position of the channels' pane.
128           * @see #getChannelsPaneList           * @see #getChannelsPaneList
129           */           */
130          public abstract void insertChannelsPane(JSChannelsPane pane, int idx);          public void insertChannelsPane(CP pane, int idx);
131                    
132          /**          /**
133           * Gets the <code>JSChannelsPane</code> that is currently shown,           * Gets the channels' pane that is currently shown,
134           * or has the focus if more than one channels' panes are shown.           * or has the focus if more than one channels' panes are shown.
135           * If the GUI implementation has only one pane containing sampler channels,           * If the GUI implementation has only one pane containing sampler channels,
136           * than this method should always return that pane (the <code>JSChannelsPane</code>           * than this method should always return that pane (the channels' pane
137           * with index 0).           * with index 0).
138           * @return The selected <code>JSChannelsPane</code>.           * @return The selected channels' pane.
139           */           */
140          public abstract JSChannelsPane getSelectedChannelsPane();          public CP getSelectedChannelsPane();
141            
142            /**
143             * Get the server address to which to connect (asynchronously if needed)
144             * and pass it to <code>r.run()</code>.
145             * If the server should be manually selected, a dialog asking
146             * the user to choose a server is displayed.
147             */
148            public void getServer(CC.Run<Server> r);
149            
150            /**
151             * Get the server address to which to connect (asynchronously if needed)
152             * and pass it to <code>r.run()</code>.
153             * If the server should be manually selected, a dialog asking
154             * the user to choose a server is displayed.
155             * @param manualSelect Determines whether the server should be manually selected.
156             */
157            public void getServer(CC.Run<Server> r, boolean manualSelect);
158                    
159          /**          /**
160           * Gets the server address to which to connect. If the server should be           * Gets the server address to which to connect. If the server should be
161           * manually selected, a dialog asking the user to choose a server is displayed.           * manually selected, a dialog asking the user to choose a server is displayed.
162           */           */
163          public abstract Server getServer();          public Server getServer();
164                    
165          /**          /**
166           * Gets the server address to which to connect. If the server should be           * Gets the server address to which to connect. If the server should be
167           * manually selected, a dialog asking the user to choose a server is displayed.           * manually selected, a dialog asking the user to choose a server is displayed.
168           * @param manualSelect Determines whether the server should be manually selected.           * @param manualSelect Determines whether the server should be manually selected.
169           */           */
170          public abstract Server getServer(boolean manualSelect);          public Server getServer(boolean manualSelect);
171    
172          /**          /**
173           * Gets the LS Console model.           * Gets the LS Console model.
174           * @return The LS Console model or <code>null</code>.           * @return The LS Console model or <code>null</code>.
175           */           */
176          public LSConsoleModel          public LSConsoleModel getLSConsoleModel();
         getLSConsoleModel() { return null; }  
177                    
178          /**          /**
179           * Sets the <code>JSChannelsPane</code> to be selected.           * Sets the channels' pane to be selected.
180           * Note that all registered listeners should be notified           * Note that all registered listeners should be notified
181           * when the selection is changed.           * when the selection is changed.
182           * @param pane The <code>JSChannelsPane</code> to be shown.           * @param pane The channels' pane to be shown.
183           * @see #fireChannelsPaneSelectionChanged           * @see #fireChannelsPaneSelectionChanged
184           */           */
185          public abstract void setSelectedChannelsPane(JSChannelsPane pane);          public void setSelectedChannelsPane(CP pane);
           
         private class EventHandler implements SamplerChannelListListener {  
                 /**  
                  * Invoked when a new sampler channel is created.  
                  * @param e A <code>SamplerChannelListEvent</code>  
                  * instance providing the event information.  
                  */  
                 @Override  
                 public void  
                 channelAdded(SamplerChannelListEvent e) {  
                         if(e.getChannelModel() == null) return;  
                         Integer id = e.getChannelModel().getChannelId();  
                         if(findChannel(id) != null) {  
                                 CC.getLogger().log(Level.WARNING, "JSMainFrame.channelExist!", id);  
                                 return;  
                         }  
                           
                         ChannelConfig config = null;  
                         JSViewConfig viewConfig = CC.getViewConfig();  
                         if(viewConfig != null && viewConfig.getSessionViewConfig() != null) {  
                                 config = viewConfig.getSessionViewConfig().pollChannelConfig();  
                         }  
                           
                         if(config == null) {  
                                 getSelectedChannelsPane().addChannel(e.getChannelModel());  
                         } else {  
                                 int i = config.channelsPanel;  
                                 if(i >= 0 && i < getChannelsPaneCount()) {  
                                         getChannelsPane(i).addChannel(e.getChannelModel(), config);  
                                 } else {  
                                         getSelectedChannelsPane().addChannel(e.getChannelModel(), config);  
                                 }  
                         }  
                 }  
           
                 /**  
                  * Invoked when a sampler channel is removed.  
                  * @param e A <code>SamplerChannelListEvent</code>  
                  * instance providing the event information.  
                  */  
                 @Override  
                 public void  
                 channelRemoved(SamplerChannelListEvent e) {  
                         removeChannel(e.getChannelModel().getChannelId());  
                 }  
         }  
186                    
187          /**          /**
188           * Searches for the first occurence of a channel with numerical ID <code>id</code>.           * Searches for the first occurence of a channel with numerical ID <code>id</code>.
189           * @return The first occurence of a channel with numerical ID <code>id</code> or           * @return The first occurence of a channel with numerical ID <code>id</code> or
190           * <code>null</code> if there is no channel with numerical ID <code>id</code>.           * <code>null</code> if there is no channel with numerical ID <code>id</code>.
191           */           */
192          public JSChannel          public JSChannel findChannel(int id);
         findChannel(int id) {  
                 if(id < 0) return null;  
                   
                 for(JSChannelsPane cp : getChannelsPaneList()) {  
                         for(JSChannel c : cp.getChannels()) if(c.getChannelId() == id) return c;  
                 }  
                   
                 return null;  
         }  
193                    
194          /**          /**
195           * Removes the first occurrence of a channel with numerical ID <code>id</code>.           * Removes the first occurrence of a channel with numerical ID <code>id</code>.
# Line 324  public abstract class JSMainFrame extend Line 197  public abstract class JSMainFrame extend
197           * @return The removed channel or <code>null</code>           * @return The removed channel or <code>null</code>
198           * if there is no channel with numerical ID <code>id</code>.           * if there is no channel with numerical ID <code>id</code>.
199           */           */
200          public JSChannel          public JSChannel removeChannel(int id);
         removeChannel(int id) {  
                 if(id < 0) return null;  
                   
                 for(JSChannelsPane cp : getChannelsPaneList()) {  
                         for(JSChannel c : cp.getChannels()) {  
                                 if(c.getChannelId() == id) {  
                                         cp.removeChannel(c);  
                                         firePropertyChange("channelRemoved", null, c);  
                                         return c;  
                                 }  
                         }  
                 }  
                   
                 return null;  
         }  
201                    
202          /**          /**
203           * Gets the zero-based position of the specified sampler channel           * Gets the zero-based position of the specified sampler channel
# Line 348  public abstract class JSMainFrame extend Line 206  public abstract class JSMainFrame extend
206           * @return The zero-based position of the specified sampler channel           * @return The zero-based position of the specified sampler channel
207           * in the channels pane, or -1 if the specified channels is not found.           * in the channels pane, or -1 if the specified channels is not found.
208           */           */
209          public int          public int getChannelNumber(SamplerChannelModel channel);
         getChannelNumber(SamplerChannelModel channel) {  
                 if(channel == null) return -1;  
                   
                 for(int i = 0; i < getChannelsPaneCount(); i++) {  
                         JSChannelsPane chnPane = getChannelsPane(i);  
                         for(int j = 0; j < chnPane.getChannelCount(); j++) {  
                                 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {  
                                         return j;  
                                 }  
                         }  
                 }  
                   
                 return -1;  
         }  
210                    
211          /**          /**
212           * Returns a string in the format <code>channelPaneNumber.channelNumber</code>,           * Returns a string in the format <code>channelPaneNumber.channelNumber</code>,
# Line 372  public abstract class JSMainFrame extend Line 216  public abstract class JSMainFrame extend
216           * Note that this path may change when adding/removing channels/channels panes.           * Note that this path may change when adding/removing channels/channels panes.
217           * @return The channels path, or <code>null</code> if the specified channels is not found.           * @return The channels path, or <code>null</code> if the specified channels is not found.
218           */           */
219          public String          public String getChannelPath(SamplerChannelModel channel);
         getChannelPath(SamplerChannelModel channel) {  
                 if(channel == null) return null;  
                   
                 for(int i = 0; i < getChannelsPaneCount(); i++) {  
                         JSChannelsPane chnPane = getChannelsPane(i);  
                         for(int j = 0; j < chnPane.getChannelCount(); j++) {  
                                 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {  
                                         return (i + 1) + "." + (j + 1);  
                                 }  
                         }  
                 }  
                   
                 return null;  
         }  
220                    
221          /**          /**
222           * Gets the zero-based number of the channels pane,           * Gets the zero-based number of the channels pane,
# Line 396  public abstract class JSMainFrame extend Line 226  public abstract class JSMainFrame extend
226           * to which the specified sampler channel is added, or           * to which the specified sampler channel is added, or
227           * -1 if the specified channels is not found.           * -1 if the specified channels is not found.
228           */           */
229          public int          public int getChannelsPaneNumber(SamplerChannelModel channel);
         getChannelsPaneNumber(SamplerChannelModel channel) {  
                 if(channel == null) return -1;  
                   
                 for(int i = 0; i < getChannelsPaneCount(); i++) {  
                         JSChannelsPane chnPane = getChannelsPane(i);  
                         for(int j = 0; j < chnPane.getChannelCount(); j++) {  
                                 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {  
                                         return i;  
                                 }  
                         }  
                 }  
                   
                 return -1;  
         }  
230                    
231          /**          /**
232           * Sends the specified script to the backend.           * Sends the specified script to the backend.
233           * @param script The file name of the script to run.           * @param script The file name of the script to run.
234           */           */
235          public abstract void runScript(String script);          public void runScript(String script);
236                    
237          /**          /**
238           * Determines whether the channel list UI should be automatically updated           * Determines whether the channel list UI should be automatically updated
239           * when channel is added/removed. The default value is <code>true</code>.           * when channel is added/removed. The default value is <code>true</code>.
240           */           */
241          public boolean          public boolean getAutoUpdateChannelListUI();
         getAutoUpdateChannelListUI() { return autoUpdateChannelListUI; }  
242                    
243          /**          /**
244           * Determines whether the channel list UI should be automatically updated           * Determines whether the channel list UI should be automatically updated
245           * when channel is added/removed.           * when channel is added/removed.
246           */           */
247          public void          public void setAutoUpdateChannelListUI(boolean b);
         setAutoUpdateChannelListUI(boolean b) {  
                 if(b == autoUpdateChannelListUI) return;  
                   
                 autoUpdateChannelListUI = b;  
                 for(JSChannelsPane cp : getChannelsPaneList()) {  
                         cp.setAutoUpdate(b);  
                 }  
         }  
248                    
249          /**          /**
250           * Updates the channel list UI.           * Updates the channel list UI.
251           */           */
252          public void          public void updateChannelListUI();
         updateChannelListUI() {  
                 for(JSChannelsPane cp : getChannelsPaneList()) {  
                         cp.updateChannelListUI();  
                 }  
         }  
253  }  }

Legend:
Removed from v.2287  
changed lines
  Added in v.2288

  ViewVC Help
Powered by ViewVC