frameListener must call close if AlignFrame
[jalview.git] / src / jalview / bin / JalviewLite.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package jalview.bin;\r
20 \r
21 import jalview.appletgui.AlignFrame;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 import jalview.io.*;\r
26 \r
27 import java.applet.*;\r
28 \r
29 import java.awt.*;\r
30 import java.awt.event.*;\r
31 import jalview.appletgui.FeatureSettings;\r
32 \r
33 \r
34 /**\r
35  * Jalview Applet. Runs in Java 1.18 runtime\r
36  *\r
37  * @author $author$\r
38  * @version $Revision$\r
39  */\r
40 public class JalviewLite extends Applet\r
41 {\r
42     static int lastFrameX = 200;\r
43     static int lastFrameY = 200;\r
44     boolean fileFound = true;\r
45     String file = "No file";\r
46     Button launcher = new Button("Start Jalview");\r
47 \r
48     //The currentAlignFrame is static, it will change\r
49     //if and when the user selects a new window\r
50     public static AlignFrame currentAlignFrame;\r
51 \r
52     //This is the first frame to be displayed, and does not change\r
53     AlignFrame initialAlignFrame;\r
54 \r
55     boolean embedded = false;\r
56 \r
57 \r
58     /**\r
59      * init method for Jalview Applet\r
60      */\r
61     public void init()\r
62     {\r
63         int r = 255;\r
64         int g = 255;\r
65         int b = 255;\r
66         String param = getParameter("RGB");\r
67 \r
68         if (param != null)\r
69         {\r
70             try\r
71             {\r
72                 r = Integer.parseInt(param.substring(0, 2), 16);\r
73                 g = Integer.parseInt(param.substring(2, 4), 16);\r
74                 b = Integer.parseInt(param.substring(4, 6), 16);\r
75             }\r
76             catch (Exception ex)\r
77             {\r
78                 r = 255;\r
79                 g = 255;\r
80                 b = 255;\r
81             }\r
82         }\r
83 \r
84         param = getParameter("label");\r
85         if(param != null)\r
86           launcher.setLabel(param);\r
87 \r
88         this.setBackground(new Color(r, g, b));\r
89 \r
90         file = getParameter("file");\r
91 \r
92         if(file==null)\r
93         {\r
94           //Maybe the sequences are added as parameters\r
95           StringBuffer data = new StringBuffer("PASTE");\r
96           int i=1;\r
97           while( (file=getParameter("sequence"+i))!=null)\r
98           {\r
99             data.append(file.toString()+"\n");\r
100             i++;\r
101           }\r
102           if(data.length()>5)\r
103             file = data.toString();\r
104         }\r
105 \r
106         final JalviewLite applet = this;\r
107         if(getParameter("embedded")!=null\r
108            && getParameter("embedded").equalsIgnoreCase("true"))\r
109         {\r
110           embedded = true;\r
111           LoadingThread loader = new LoadingThread(file, applet);\r
112           loader.start();\r
113         }\r
114         else if (file != null)\r
115         {\r
116             add(launcher);\r
117 \r
118             launcher.addActionListener(new java.awt.event.ActionListener()\r
119                 {\r
120                     public void actionPerformed(ActionEvent e)\r
121                     {\r
122                         LoadingThread loader = new LoadingThread(file,\r
123                             applet);\r
124                         loader.start();\r
125                       }\r
126                 });\r
127         }\r
128         else\r
129         {\r
130             file = "NO FILE";\r
131             fileFound = false;\r
132         }\r
133     }\r
134 \r
135 \r
136     public static void main(String [] args)\r
137     {\r
138       if(args.length!=1)\r
139       {\r
140         System.out.println("\nUsage: java -jar jalviewApplet.jar fileName\n");\r
141         System.exit(1);\r
142       }\r
143 \r
144       String format = new jalview.io.IdentifyFile().Identify(args[0],AppletFormatAdapter.FILE);\r
145 \r
146       SequenceI[] sequences = null;\r
147      try{\r
148        sequences = new AppletFormatAdapter().readFile(args[0], AppletFormatAdapter.FILE, format);\r
149      }catch(java.io.IOException ex)\r
150      {\r
151        ex.printStackTrace();\r
152      }\r
153       if ( (sequences != null) && (sequences.length > 0))\r
154       {\r
155         AlignFrame af = new AlignFrame(new Alignment(sequences), null, args[0], false);\r
156         af.statusBar.setText("Successfully loaded file " + args[0]);\r
157       }\r
158     }\r
159 \r
160 \r
161     /**\r
162      * Initialises and displays a new java.awt.Frame\r
163      *\r
164      * @param frame java.awt.Frame to be displayed\r
165      * @param title title of new frame\r
166      * @param width width if new frame\r
167      * @param height height of new frame\r
168      */\r
169     public static void addFrame(final Frame frame, String title, int width,\r
170         int height)\r
171     {\r
172         frame.setLocation(lastFrameX, lastFrameY);\r
173         lastFrameX += 40;\r
174         lastFrameY += 40;\r
175         frame.setSize(width, height);\r
176         frame.setTitle(title);\r
177         frame.addWindowListener(new WindowAdapter()\r
178             {\r
179                 public void windowClosing(WindowEvent e)\r
180                 {\r
181                   if(frame instanceof AlignFrame)\r
182                     ((AlignFrame)frame).closeMenuItem_actionPerformed();\r
183                     if(currentAlignFrame == frame)\r
184                     {\r
185                       currentAlignFrame = null;\r
186                     }\r
187                     lastFrameX -=40;\r
188                     lastFrameY -=40;\r
189                     frame.setMenuBar(null);\r
190                     frame.dispose();\r
191                 }\r
192                 public void windowActivated(WindowEvent e)\r
193                 {\r
194                   if(frame instanceof AlignFrame)\r
195                     currentAlignFrame = (AlignFrame)frame;\r
196                 }\r
197 \r
198             });\r
199         frame.setVisible(true);\r
200     }\r
201 \r
202     public String getSelectedSequences()\r
203     {\r
204       StringBuffer result = new StringBuffer("");\r
205 \r
206       if(initialAlignFrame.viewport.getSelectionGroup()!=null)\r
207       {\r
208         SequenceI[] seqs = initialAlignFrame.viewport.getSelectionGroup().\r
209             getSequencesInOrder(\r
210                 initialAlignFrame.viewport.getAlignment());\r
211 \r
212         for (int i = 0; i < seqs.length; i++)\r
213           result.append(seqs[i].getName() + "¬");\r
214       }\r
215 \r
216       return result.toString();\r
217     }\r
218 \r
219     public String getAlignment(String format)\r
220     {\r
221       return getAlignment(format, "true");\r
222     }\r
223 \r
224     public String getAlignment(String format, String suffix)\r
225     {\r
226       try\r
227       {\r
228         boolean seqlimits = suffix.equalsIgnoreCase("true");\r
229 \r
230         String reply = new AppletFormatAdapter().formatSequences(format,\r
231             currentAlignFrame.viewport.getAlignment().getSequences(), seqlimits);\r
232         return reply;\r
233       }\r
234       catch (Exception ex)\r
235       {\r
236         ex.printStackTrace();\r
237         return "Error retrieving alignment in " + format + " format. ";\r
238       }\r
239     }\r
240 \r
241     /**\r
242      * This paints the background surrounding the "Launch Jalview button"\r
243      * <br>\r
244      * <br>If file given in parameter not found, displays error message\r
245      *\r
246      * @param g graphics context\r
247      */\r
248     public void paint(Graphics g)\r
249     {\r
250         if (!fileFound)\r
251         {\r
252             g.setColor(new Color(200, 200, 200));\r
253             g.setColor(Color.cyan);\r
254             g.fillRect(0, 0, getSize().width, getSize().height);\r
255             g.setColor(Color.red);\r
256             g.drawString("Jalview can't open file", 5, 15);\r
257             g.drawString("\"" + file + "\"", 5, 30);\r
258         }\r
259         else if(embedded)\r
260         {\r
261           g.setColor(Color.black);\r
262           g.setFont(new Font("Arial", Font.BOLD, 24));\r
263           g.drawString("Jalview Applet", 50, this.size().height/2 -30);\r
264           g.drawString("Loading Data...", 50, this.size().height/2);\r
265         }\r
266 \r
267 \r
268     }\r
269 \r
270     class LoadingThread extends Thread\r
271     {\r
272         String file;\r
273         String protocol;\r
274         String format;\r
275         JalviewLite applet;\r
276 \r
277         public LoadingThread(String _file,\r
278                              JalviewLite _applet)\r
279         {\r
280             file = _file;\r
281             if(file.startsWith("PASTE"))\r
282             {\r
283               file = file.substring(5);\r
284               protocol = AppletFormatAdapter.PASTE;\r
285             }\r
286             else if(inArchive(file))\r
287               protocol = AppletFormatAdapter.CLASSLOADER;\r
288             else\r
289             {\r
290               file = addProtocol(file);\r
291               protocol = AppletFormatAdapter.URL;\r
292             }\r
293             format = new jalview.io.IdentifyFile().Identify(file, protocol);\r
294             applet = _applet;\r
295         }\r
296 \r
297         public void run()\r
298         {\r
299             SequenceI[] sequences = null;\r
300             try{\r
301               sequences = new AppletFormatAdapter().readFile(file, protocol,\r
302                   format);\r
303             }catch(java.io.IOException ex)\r
304             {\r
305               ex.printStackTrace();\r
306             }\r
307             if ((sequences != null) && (sequences.length > 0))\r
308             {\r
309               currentAlignFrame = new AlignFrame(new Alignment(sequences),\r
310                                                  applet,\r
311                                                  file,\r
312                                                  embedded);\r
313 \r
314               if(protocol==jalview.io.AppletFormatAdapter.PASTE)\r
315                 currentAlignFrame.setTitle("Sequences from "+getDocumentBase());\r
316 \r
317               initialAlignFrame = currentAlignFrame;\r
318 \r
319               currentAlignFrame.statusBar.setText("Successfully loaded file " + file);\r
320 \r
321 \r
322                 String treeFile = applet.getParameter("tree");\r
323                 if(treeFile==null)\r
324                   treeFile = applet.getParameter("treeFile");\r
325 \r
326                 if (treeFile != null)\r
327                 {\r
328                   try\r
329                   {\r
330                     if(inArchive(treeFile))\r
331                       protocol = AppletFormatAdapter.CLASSLOADER;\r
332                     else\r
333                     {\r
334                       protocol = AppletFormatAdapter.URL;\r
335                       treeFile = addProtocol(treeFile);\r
336                     }\r
337 \r
338                     jalview.io.NewickFile fin = new jalview.io.NewickFile(treeFile, protocol);\r
339 \r
340                     fin.parse();\r
341 \r
342                     if (fin.getTree() != null)\r
343                     {\r
344                       currentAlignFrame.loadTree(fin, treeFile);\r
345                     }\r
346                   }\r
347                   catch (Exception ex)\r
348                   {\r
349                     ex.printStackTrace();\r
350                   }\r
351               }\r
352 \r
353               String param = getParameter("features");\r
354               if (param != null)\r
355               {\r
356                 if( !inArchive(param) )\r
357                   param = addProtocol( param );\r
358 \r
359                 currentAlignFrame.parseFeaturesFile(param, protocol);\r
360               }\r
361 \r
362               param = getParameter("showFeatureSettings");\r
363               if(param !=null && param.equalsIgnoreCase("true"))\r
364               {\r
365                 currentAlignFrame.viewport.showSequenceFeatures(true);\r
366                 new FeatureSettings(currentAlignFrame.alignPanel);\r
367               }\r
368 \r
369              param = getParameter("annotations");\r
370              if (param != null)\r
371              {\r
372                if( !inArchive(param) )\r
373                   param = addProtocol( param );\r
374 \r
375                new AnnotationFile().readAnnotationFile(\r
376                    currentAlignFrame.viewport.getAlignment(),\r
377                    param);\r
378 \r
379                currentAlignFrame.alignPanel.fontChanged();\r
380                currentAlignFrame.alignPanel.setScrollValues(0,0);\r
381 \r
382              }\r
383 \r
384              param = getParameter("jnetfile");\r
385              if (param != null)\r
386              {\r
387                try\r
388                {\r
389                  if (inArchive(param))\r
390                    protocol = AppletFormatAdapter.CLASSLOADER;\r
391                  else\r
392                  {\r
393                    protocol = AppletFormatAdapter.URL;\r
394                    param = addProtocol(param);\r
395                  }\r
396 \r
397                  jalview.io.JPredFile predictions = new jalview.io.JPredFile(\r
398                      param, protocol);\r
399                  new JnetAnnotationMaker().add_annotation(predictions,\r
400                      currentAlignFrame.viewport.getAlignment(),\r
401                      0,false); // do not add sequence profile from concise output\r
402                  currentAlignFrame.alignPanel.fontChanged();\r
403                  currentAlignFrame.alignPanel.setScrollValues(0, 0);\r
404                } catch (Exception ex) {\r
405                  ex.printStackTrace();\r
406                }\r
407              }\r
408 \r
409 \r
410                 String pdbfile = applet.getParameter("PDBFILE");\r
411                 if(pdbfile!=null)\r
412                 {\r
413                   if( inArchive(pdbfile) )\r
414                     protocol = AppletFormatAdapter.CLASSLOADER;\r
415                   else\r
416                   {\r
417                     protocol = AppletFormatAdapter.URL;\r
418                     pdbfile = addProtocol(pdbfile);\r
419                   }\r
420 \r
421                   String sequence = applet.getParameter("PDBSEQ");\r
422 \r
423                   if(sequence!=null)\r
424                   {\r
425                     new MCview.AppletPDBViewer(pdbfile, protocol,\r
426                                                (Sequence)currentAlignFrame.getAlignViewport().getAlignment().findName(sequence),\r
427                                                currentAlignFrame.getSeqcanvas());\r
428                   }\r
429 \r
430                 }\r
431             }\r
432             else\r
433             {\r
434                 fileFound = false;\r
435                 remove(launcher);\r
436                 repaint();\r
437             }\r
438         }\r
439 \r
440         /**\r
441          * Discovers whether the given file is in the Applet Archive\r
442          * @param file String\r
443          * @return boolean\r
444          */\r
445         boolean inArchive(String file)\r
446         {\r
447           //This might throw a security exception in certain browsers\r
448           //Netscape Communicator for instance.\r
449           try{\r
450             return (getClass().getResourceAsStream("/" + file) != null);\r
451           }catch(Exception ex)\r
452           {\r
453             System.out.println("Exception checking resources: "+file+" "+ex);\r
454             return false;\r
455           }\r
456         }\r
457 \r
458         String addProtocol(String file)\r
459         {\r
460           if (file.indexOf("://") == -1)\r
461              file = getCodeBase() + file;\r
462 \r
463           return file;\r
464         }\r
465 \r
466     }\r
467 }\r