Remove redundancy in Eclipse
[jalview.git] / src / jalview / appletgui / AlignFrame.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 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 \r
20 package jalview.appletgui;\r
21 \r
22 import jalview.jbappletgui.GAlignFrame;\r
23 import jalview.schemes.*;\r
24 import jalview.datamodel.*;\r
25 import jalview.analysis.*;\r
26 import jalview.io.*;\r
27 import java.awt.*;\r
28 import java.awt.event.*;\r
29 import java.util.*;\r
30 import java.io.InputStreamReader;\r
31 import java.io.BufferedReader;\r
32 \r
33 public class AlignFrame\r
34     extends GAlignFrame\r
35 {\r
36   final AlignmentPanel alignPanel;\r
37   final AlignViewport viewport;\r
38   int NEW_WINDOW_WIDTH = 700;\r
39   int NEW_WINDOW_HEIGHT = 500;\r
40   jalview.bin.JalviewLite applet;\r
41 \r
42 \r
43   public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet, String title)\r
44   {\r
45     this.applet = applet;\r
46     viewport = new AlignViewport(al, applet);\r
47     alignPanel = new AlignmentPanel(this, viewport);\r
48     add(alignPanel);\r
49     alignPanel.validate();\r
50 \r
51     if(applet!=null)\r
52     {\r
53       String treeFile = applet.getParameter("treeFile");\r
54       if (treeFile != null)\r
55       {\r
56         try\r
57         {\r
58           jalview.io.NewickFile fin = new jalview.io.NewickFile(applet.\r
59               getCodeBase() + treeFile, "URL");\r
60           fin.parse();\r
61 \r
62           if (fin.getTree() != null)\r
63           {\r
64             TreePanel tp = null;\r
65             tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
66                                fin, "FromFile", applet.getCodeBase() + treeFile);\r
67             jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);\r
68             addTreeMenuItem(tp, treeFile);\r
69           }\r
70         }\r
71         catch (Exception ex)\r
72         {\r
73           ex.printStackTrace();\r
74         }\r
75       }\r
76 \r
77       String param = applet.getParameter("sortBy");\r
78       if (param != null)\r
79       {\r
80         if (param.equalsIgnoreCase("Id"))\r
81           sortIDMenuItem_actionPerformed(null);\r
82         else if (param.equalsIgnoreCase("Pairwise Identity"))\r
83           sortPairwiseMenuItem_actionPerformed(null);\r
84       }\r
85 \r
86       param = applet.getParameter("wrap");\r
87       if (param != null)\r
88       {\r
89         if (param.equalsIgnoreCase("true"))\r
90         {\r
91           wrapMenuItem.setState(true);\r
92           wrapMenuItem_actionPerformed(null);\r
93         }\r
94       }\r
95 \r
96       try\r
97       {\r
98         param = applet.getParameter("windowWidth");\r
99         if (param != null)\r
100         {\r
101           int width = Integer.parseInt(param);\r
102           NEW_WINDOW_WIDTH = width;\r
103         }\r
104         param = applet.getParameter("windowHeight");\r
105         if (param != null)\r
106         {\r
107           int height = Integer.parseInt(param);\r
108           NEW_WINDOW_HEIGHT = height;\r
109         }\r
110       }\r
111       catch (Exception ex)\r
112       {}\r
113 \r
114     }\r
115 \r
116     this.addWindowListener(new WindowAdapter()\r
117     {\r
118       public void windowClosing(WindowEvent e)\r
119           {\r
120             closeMenuItem_actionPerformed(null);\r
121           }\r
122     });\r
123 \r
124     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
125     {\r
126      public void propertyChange(java.beans.PropertyChangeEvent evt)\r
127      {\r
128        if (evt.getPropertyName().equals("alignment"))\r
129        {\r
130          alignmentChanged();\r
131        }\r
132      }\r
133    });\r
134 \r
135    jalview.bin.JalviewLite.addFrame(this, title,\r
136                                     NEW_WINDOW_WIDTH,\r
137                                     NEW_WINDOW_HEIGHT);\r
138 \r
139 \r
140   }\r
141 \r
142   public void inputText_actionPerformed(ActionEvent e)\r
143   {\r
144     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, applet);\r
145     Frame frame = new Frame();\r
146     frame.add(cap);\r
147     jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);\r
148   }\r
149 \r
150   protected void outputText_actionPerformed(ActionEvent e)\r
151   {\r
152     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, applet);\r
153     Frame frame = new Frame();\r
154     frame.add(cap);\r
155     jalview.bin.JalviewLite.addFrame(frame,\r
156                                      "Alignment output - " + e.getActionCommand(),\r
157                                      600, 500);\r
158     cap.setText(new FormatAdapter().formatSequences(e.getActionCommand(),\r
159                                               viewport.getAlignment().\r
160                                               getSequences()));\r
161   }\r
162 \r
163   public void closeMenuItem_actionPerformed(ActionEvent e)\r
164   {\r
165     PaintRefresher.components.remove(viewport.alignment);\r
166     dispose();\r
167     if(PaintRefresher.components.size()==0 && applet==null)\r
168       System.exit(0);\r
169   }\r
170 \r
171   Stack historyList = new Stack();\r
172   Stack redoList = new Stack();\r
173 \r
174   void updateEditMenuBar()\r
175   {\r
176     if (historyList.size() > 0)\r
177     {\r
178       undoMenuItem.setEnabled(true);\r
179       HistoryItem hi = (HistoryItem) historyList.peek();\r
180       undoMenuItem.setLabel("Undo " + hi.getDescription());\r
181     }\r
182     else\r
183     {\r
184       undoMenuItem.setEnabled(false);\r
185       undoMenuItem.setLabel("Undo");\r
186     }\r
187 \r
188     if (redoList.size() > 0)\r
189     {\r
190       redoMenuItem.setEnabled(true);\r
191       HistoryItem hi = (HistoryItem) redoList.peek();\r
192       redoMenuItem.setLabel("Redo " + hi.getDescription());\r
193     }\r
194     else\r
195     {\r
196       redoMenuItem.setEnabled(false);\r
197       redoMenuItem.setLabel("Redo");\r
198     }\r
199   }\r
200 \r
201   public void addHistoryItem(HistoryItem hi)\r
202   {\r
203     historyList.push(hi);\r
204     updateEditMenuBar();\r
205   }\r
206 \r
207   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
208   {\r
209     HistoryItem hi = (HistoryItem) historyList.pop();\r
210     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
211                                   HistoryItem.HIDE));\r
212     restoreHistoryItem(hi);\r
213     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
214   }\r
215 \r
216   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
217   {\r
218     HistoryItem hi = (HistoryItem) redoList.pop();\r
219     restoreHistoryItem(hi);\r
220     updateEditMenuBar();\r
221     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
222   }\r
223 \r
224   // used by undo and redo\r
225   void restoreHistoryItem(HistoryItem hi)\r
226   {\r
227     if (hi.getType() == HistoryItem.SORT)\r
228     {\r
229       for (int i = 0; i < hi.getSequences().size(); i++)\r
230       {\r
231         viewport.alignment.getSequences().setElementAt(hi.getSequences().\r
232             elementAt(i), i);\r
233       }\r
234     }\r
235     else\r
236     {\r
237       for (int i = 0; i < hi.getSequences().size(); i++)\r
238       {\r
239         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
240         if (restore.getLength() == 0)\r
241         {\r
242           // log.System.out.println(hi.getHidden().elementAt(i));\r
243           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
244           viewport.alignment.getSequences().insertElementAt(\r
245               restore,\r
246               hi.getAlignIndex(i));\r
247         }\r
248         else\r
249         {\r
250           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
251         }\r
252       }\r
253       if (hi.getType() == HistoryItem.PASTE)\r
254       {\r
255         for (int i = viewport.alignment.getHeight() - 1;\r
256              i > hi.getSequences().size() - 1; i--)\r
257         {\r
258           viewport.alignment.deleteSequence(i);\r
259         }\r
260       }\r
261     }\r
262 \r
263     updateEditMenuBar();\r
264 \r
265     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
266   }\r
267 \r
268   public void moveSelectedSequences(boolean up)\r
269   {\r
270     SequenceGroup sg = viewport.getSelectionGroup();\r
271     if (sg == null)\r
272     {\r
273       return;\r
274     }\r
275 \r
276     if (up)\r
277     {\r
278       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
279       {\r
280         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
281         if (!sg.sequences.contains(seq))\r
282         {\r
283           continue;\r
284         }\r
285 \r
286         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
287         if (sg.sequences.contains(temp))\r
288         {\r
289           continue;\r
290         }\r
291 \r
292         viewport.alignment.getSequences().setElementAt(temp, i);\r
293         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
294       }\r
295     }\r
296     else\r
297     {\r
298       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
299       {\r
300         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
301         if (!sg.sequences.contains(seq))\r
302         {\r
303           continue;\r
304         }\r
305 \r
306         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
307         if (sg.sequences.contains(temp))\r
308         {\r
309           continue;\r
310         }\r
311 \r
312         viewport.alignment.getSequences().setElementAt(temp, i);\r
313         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
314       }\r
315     }\r
316 \r
317     alignPanel.repaint();\r
318   }\r
319 \r
320   StringBuffer copiedSequences;\r
321   protected void copy_actionPerformed(ActionEvent e)\r
322   {\r
323     if (viewport.getSelectionGroup() == null)\r
324     {\r
325       return;\r
326     }\r
327 \r
328     SequenceGroup sg = viewport.getSelectionGroup();\r
329     copiedSequences = new StringBuffer();\r
330     Hashtable orderedSeqs = new Hashtable();\r
331     for (int i = 0; i < sg.getSize(); i++)\r
332     {\r
333       SequenceI seq = sg.getSequenceAt(i);\r
334       int index = viewport.alignment.findIndex(seq);\r
335       orderedSeqs.put(index + "", seq);\r
336     }\r
337 \r
338     int index = 0, startRes, endRes;\r
339     char ch;\r
340 \r
341     for (int i = 0; i < sg.getSize(); i++)\r
342     {\r
343         SequenceI seq = null;\r
344 \r
345         while (seq == null)\r
346         {\r
347             if (orderedSeqs.containsKey(index + ""))\r
348             {\r
349                 seq = (SequenceI) orderedSeqs.get(index + "");\r
350                 index++;\r
351 \r
352                 break;\r
353             }\r
354             else\r
355             {\r
356                 index++;\r
357             }\r
358         }\r
359 \r
360         //FIND START RES\r
361         //Returns residue following index if gap\r
362         startRes = seq.findPosition(sg.getStartRes());\r
363 \r
364         //FIND END RES\r
365         //Need to find the residue preceeding index if gap\r
366         endRes = 0;\r
367 \r
368         for (int j = 0; j < sg.getEndRes()+1 && j < seq.getLength(); j++)\r
369         {\r
370           ch = seq.getCharAt(j);\r
371           if (!jalview.util.Comparison.isGap( (ch)))\r
372           {\r
373             endRes++;\r
374           }\r
375         }\r
376 \r
377         if(endRes>0)\r
378         {\r
379           endRes += seq.getStart() -1;\r
380         }\r
381 \r
382         copiedSequences.append(seq.getName() + "\t" +\r
383             startRes + "\t" +\r
384             endRes + "\t" +\r
385             seq.getSequence(sg.getStartRes(),\r
386                 sg.getEndRes() + 1) + "\n");\r
387     }\r
388 \r
389   }\r
390 \r
391   protected void pasteNew_actionPerformed(ActionEvent e)\r
392   {\r
393     paste(true);\r
394   }\r
395 \r
396   protected void pasteThis_actionPerformed(ActionEvent e)\r
397   {\r
398     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
399                                    HistoryItem.PASTE));\r
400     paste(false);\r
401   }\r
402 \r
403   void paste(boolean newAlignment)\r
404   {\r
405     try\r
406     {\r
407       if (copiedSequences == null)\r
408       {\r
409         return;\r
410       }\r
411 \r
412       StringTokenizer st = new StringTokenizer(copiedSequences.toString());\r
413       Vector seqs = new Vector();\r
414       while (st.hasMoreElements())\r
415       {\r
416         String name = st.nextToken();\r
417         int start = Integer.parseInt(st.nextToken());\r
418         int end = Integer.parseInt(st.nextToken());\r
419         Sequence sequence = new Sequence(name, st.nextToken(), start, end);\r
420 \r
421         if (!newAlignment)\r
422         {\r
423           viewport.alignment.addSequence(sequence);\r
424         }\r
425         else\r
426         {\r
427           seqs.addElement(sequence);\r
428         }\r
429       }\r
430 \r
431       if (newAlignment)\r
432       {\r
433         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
434         for (int i = 0; i < seqs.size(); i++)\r
435         {\r
436           newSeqs[i] = (SequenceI) seqs.elementAt(i);\r
437         }\r
438 \r
439         String newtitle = new String("Copied sequences");\r
440         if (getTitle().startsWith("Copied sequences"))\r
441         {\r
442           newtitle = getTitle();\r
443         }\r
444         else\r
445         {\r
446           newtitle = newtitle.concat("- from " + getTitle());\r
447         }\r
448         AlignFrame af = new AlignFrame(new Alignment(newSeqs), applet, newtitle);\r
449 \r
450         jalview.bin.JalviewLite.addFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
451                                          NEW_WINDOW_HEIGHT);\r
452       }\r
453       else\r
454       {\r
455         viewport.setEndSeq(viewport.alignment.getHeight());\r
456         viewport.alignment.getWidth();\r
457         viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
458       }\r
459 \r
460     }\r
461     catch (Exception ex)\r
462     {} // could be anything being pasted in here\r
463 \r
464   }\r
465 \r
466   protected void cut_actionPerformed(ActionEvent e)\r
467   {\r
468     copy_actionPerformed(null);\r
469     delete_actionPerformed(null);\r
470   }\r
471 \r
472   protected void delete_actionPerformed(ActionEvent e)\r
473   {\r
474     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
475                                    HistoryItem.HIDE));\r
476     if (viewport.getSelectionGroup() == null)\r
477     {\r
478       return;\r
479     }\r
480 \r
481 \r
482     SequenceGroup sg = viewport.getSelectionGroup();\r
483     boolean allSequences = false;\r
484     if(sg.sequences.size()==viewport.alignment.getHeight())\r
485           allSequences = true;\r
486 \r
487     for (int i = 0; i < sg.sequences.size(); i++)\r
488     {\r
489       SequenceI seq = sg.getSequenceAt(i);\r
490       int index = viewport.getAlignment().findIndex(seq);\r
491       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
492 \r
493       // If the cut affects all sequences, remove highlighted columns\r
494       if (allSequences)\r
495       {\r
496         viewport.getColumnSelection().removeElements(sg.getStartRes(),\r
497                                                      sg.getEndRes() + 1);\r
498       }\r
499 \r
500 \r
501       if (seq.getSequence().length() < 1)\r
502       {\r
503         viewport.getAlignment().deleteSequence(seq);\r
504       }\r
505       else\r
506       {\r
507         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
508       }\r
509     }\r
510 \r
511     viewport.setSelectionGroup(null);\r
512     viewport.alignment.deleteGroup(sg);\r
513     viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getSize().height);\r
514     if (viewport.getAlignment().getHeight() < 1)\r
515     {\r
516       try\r
517       {\r
518         this.setVisible(false);\r
519       }\r
520       catch (Exception ex)\r
521       {}\r
522     }\r
523     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
524 \r
525   }\r
526 \r
527   protected void deleteGroups_actionPerformed(ActionEvent e)\r
528   {\r
529     viewport.alignment.deleteAllGroups();\r
530     viewport.setSelectionGroup(null);\r
531 \r
532     alignPanel.repaint();\r
533   }\r
534 \r
535   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
536   {\r
537     SequenceGroup sg = new SequenceGroup();\r
538     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
539     {\r
540       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
541     }\r
542     sg.setEndRes(viewport.alignment.getWidth()-1);\r
543     viewport.setSelectionGroup(sg);\r
544     alignPanel.repaint();\r
545     PaintRefresher.Refresh(null, viewport.alignment);\r
546   }\r
547 \r
548   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
549   {\r
550     viewport.setSelectionGroup(null);\r
551     viewport.getColumnSelection().clear();\r
552     viewport.setSelectionGroup(null);\r
553     alignPanel.repaint();\r
554     PaintRefresher.Refresh(null, viewport.alignment);\r
555   }\r
556 \r
557   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
558   {\r
559     SequenceGroup sg = viewport.getSelectionGroup();\r
560     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)\r
561     {\r
562       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
563     }\r
564 \r
565     PaintRefresher.Refresh(null, viewport.alignment);\r
566   }\r
567 \r
568   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
569   {\r
570     ColumnSelection colSel = viewport.getColumnSelection();\r
571     if (colSel.size() > 0)\r
572     {\r
573       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
574                                      HistoryItem.HIDE));\r
575       int min = colSel.getMin();\r
576       viewport.getAlignment().trimLeft(min);\r
577       colSel.compensateForEdit(0, min);\r
578 \r
579       if (viewport.getSelectionGroup() != null)\r
580       {\r
581         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
582       }\r
583 \r
584       Vector groups = viewport.alignment.getGroups();\r
585       for (int i = 0; i < groups.size(); i++)\r
586       {\r
587         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
588         if (!sg.adjustForRemoveLeft(min))\r
589         {\r
590           viewport.alignment.deleteGroup(sg);\r
591         }\r
592       }\r
593       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
594     }\r
595   }\r
596 \r
597   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
598   {\r
599     ColumnSelection colSel = viewport.getColumnSelection();\r
600     if (colSel.size() > 0)\r
601     {\r
602       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
603                                      HistoryItem.HIDE));\r
604       int max = colSel.getMax();\r
605       viewport.getAlignment().trimRight(max);\r
606       if (viewport.getSelectionGroup() != null)\r
607       {\r
608         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
609       }\r
610 \r
611       Vector groups = viewport.alignment.getGroups();\r
612       for (int i = 0; i < groups.size(); i++)\r
613       {\r
614         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
615         if (!sg.adjustForRemoveRight(max))\r
616         {\r
617           viewport.alignment.deleteGroup(sg);\r
618         }\r
619       }\r
620       viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
621     }\r
622 \r
623   }\r
624 \r
625   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
626   {\r
627     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
628                                    viewport.alignment,\r
629                                    HistoryItem.HIDE));\r
630 \r
631     //This is to maintain viewport position on first residue\r
632     //of first sequence\r
633     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
634     int startRes = seq.findPosition(viewport.startRes);\r
635 \r
636     viewport.getAlignment().removeGaps();\r
637 \r
638     viewport.setStartRes(seq.findIndex(startRes)-1);\r
639 \r
640     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
641   }\r
642 \r
643   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
644   {\r
645     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
646                                    HistoryItem.HIDE));\r
647 \r
648     //This is to maintain viewport position on first residue\r
649     //of first sequence\r
650     SequenceI seq = viewport.alignment.getSequenceAt(0);\r
651     int startRes = seq.findPosition(viewport.startRes);\r
652 \r
653     SequenceI current;\r
654     int jSize;\r
655 \r
656     Vector seqs=null;\r
657 \r
658     int start=0, end = viewport.alignment.getWidth();\r
659 \r
660     if (viewport.getSelectionGroup() != null\r
661         && viewport.getSelectionGroup().sequences != null\r
662         && viewport.getSelectionGroup().sequences.size()>0)\r
663     {\r
664       seqs = viewport.getSelectionGroup().sequences;\r
665       start = viewport.getSelectionGroup().getStartRes();\r
666       end = viewport.getSelectionGroup().getEndRes()+1;\r
667     }\r
668     else\r
669       seqs = viewport.alignment.getSequences();\r
670 \r
671     for (int i = 0; i < seqs.size(); i++)\r
672     {\r
673       current = (SequenceI) seqs.elementAt(i);\r
674       jSize = current.getLength();\r
675 \r
676       // Removing a range is much quicker than removing gaps\r
677       // one by one for long sequences\r
678       int j = start;\r
679       int rangeStart=-1, rangeEnd=-1;\r
680 \r
681       do\r
682       {\r
683         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
684         {\r
685           if(rangeStart==-1)\r
686            {\r
687              rangeStart = j;\r
688              rangeEnd = j+1;\r
689            }\r
690            else\r
691            {\r
692              rangeEnd++;\r
693            }\r
694            j++;\r
695         }\r
696         else\r
697         {\r
698           if(rangeStart>-1)\r
699           {\r
700             current.deleteChars(rangeStart, rangeEnd);\r
701             j-=rangeEnd-rangeStart;\r
702             jSize-=rangeEnd-rangeStart;\r
703             rangeStart = -1;\r
704             rangeEnd = -1;\r
705           }\r
706           else\r
707             j++;\r
708         }\r
709       }\r
710       while (j < end && j < jSize);\r
711       if(rangeStart>-1)\r
712       {\r
713        current.deleteChars(rangeStart, rangeEnd);\r
714       }\r
715     }\r
716     viewport.setStartRes(seq.findIndex(startRes)-1);\r
717     viewport.firePropertyChange("alignment", null, viewport.getAlignment().getSequences());\r
718   }\r
719 \r
720   public void alignmentChanged()\r
721   {\r
722     viewport.updateConsensus();\r
723     viewport.updateConservation ();\r
724     resetAllColourSchemes();\r
725     if(alignPanel.overviewPanel!=null)\r
726       alignPanel.overviewPanel.updateOverviewImage();\r
727     alignPanel.repaint();\r
728   }\r
729 \r
730   void resetAllColourSchemes()\r
731   {\r
732     ColourSchemeI cs = viewport.globalColourScheme;\r
733     if(cs!=null)\r
734     {\r
735       if (cs instanceof ClustalxColourScheme)\r
736       {\r
737         ( (ClustalxColourScheme) viewport.getGlobalColourScheme()).\r
738             resetClustalX(viewport.alignment.getSequences(),\r
739                           viewport.alignment.getWidth());\r
740       }\r
741 \r
742       cs.setConsensus(viewport.vconsensus);\r
743       if (cs.conservationApplied())\r
744       {\r
745         Alignment al = (Alignment) viewport.alignment;\r
746         Conservation c = new Conservation("All",\r
747                                           ResidueProperties.propHash, 3,\r
748                                           al.getSequences(), 0,\r
749                                           al.getWidth() - 1);\r
750         c.calculate();\r
751         c.verdict(false, viewport.ConsPercGaps);\r
752 \r
753         cs.setConservation(c);\r
754       }\r
755     }\r
756 \r
757     int s, sSize = viewport.alignment.getGroups().size();\r
758     for(s=0; s<sSize; s++)\r
759     {\r
760       SequenceGroup sg = (SequenceGroup)viewport.alignment.getGroups().elementAt(s);\r
761       if(sg.cs!=null && sg.cs instanceof ClustalxColourScheme)\r
762       {\r
763         ((ClustalxColourScheme)sg.cs).resetClustalX(sg.sequences, sg.getWidth());\r
764       }\r
765       sg.recalcConservation();\r
766     }\r
767   }\r
768 \r
769 \r
770 \r
771   public void findMenuItem_actionPerformed(ActionEvent e)\r
772   {\r
773     new Finder(alignPanel);\r
774   }\r
775 \r
776   public void font_actionPerformed(ActionEvent e)\r
777   {\r
778     new FontChooser(alignPanel);\r
779   }\r
780 \r
781   protected void fullSeqId_actionPerformed(ActionEvent e)\r
782   {\r
783     viewport.setShowFullId(fullSeqId.getState());\r
784     alignPanel.fontChanged();\r
785     alignPanel.repaint();\r
786   }\r
787 \r
788   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
789   {\r
790     viewport.setColourText(colourTextMenuItem.getState());\r
791     alignPanel.repaint();\r
792   }\r
793 \r
794   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
795   {\r
796     viewport.setWrapAlignment(wrapMenuItem.getState());\r
797     alignPanel.setWrapAlignment(wrapMenuItem.getState());\r
798     scaleAbove.setEnabled(wrapMenuItem.getState());\r
799     scaleLeft.setEnabled(wrapMenuItem.getState());\r
800     scaleRight.setEnabled(wrapMenuItem.getState());\r
801     alignPanel.repaint();\r
802   }\r
803 \r
804   protected void scaleAbove_actionPerformed(ActionEvent e)\r
805   {\r
806     viewport.setScaleAboveWrapped(scaleAbove.getState());\r
807     alignPanel.repaint();\r
808   }\r
809 \r
810   protected void scaleLeft_actionPerformed(ActionEvent e)\r
811   {\r
812     viewport.setScaleLeftWrapped(scaleLeft.getState());\r
813     alignPanel.repaint();\r
814   }\r
815 \r
816   protected void scaleRight_actionPerformed(ActionEvent e)\r
817   {\r
818     viewport.setScaleRightWrapped(scaleRight.getState());\r
819     alignPanel.repaint();\r
820   }\r
821 \r
822   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
823   {\r
824     viewport.setShowBoxes(viewBoxesMenuItem.getState());\r
825     alignPanel.repaint();\r
826   }\r
827 \r
828   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
829   {\r
830     viewport.setShowText(viewTextMenuItem.getState());\r
831     alignPanel.repaint();\r
832   }\r
833 \r
834   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
835   {\r
836     viewport.setRenderGaps(renderGapsMenuItem.getState());\r
837     alignPanel.repaint();\r
838   }\r
839 \r
840   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
841   {\r
842     viewport.setShowAnnotation(annotationPanelMenuItem.getState());\r
843     alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());\r
844   }\r
845 \r
846   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
847   {\r
848     if (alignPanel.overviewPanel != null)\r
849     {\r
850       return;\r
851     }\r
852 \r
853     Frame frame = new Frame();\r
854     OverviewPanel overview = new OverviewPanel(alignPanel);\r
855     frame.add(overview);\r
856     // +50 must allow for applet frame window\r
857     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),\r
858                                      overview.preferredSize().width,\r
859                                      overview.preferredSize().height + 50);\r
860 \r
861     frame.pack();\r
862     frame.addWindowListener(new WindowAdapter()\r
863     {\r
864       public void windowClosing(WindowEvent e)\r
865       {\r
866         alignPanel.setOverviewPanel(null);\r
867       };\r
868     });\r
869 \r
870     alignPanel.setOverviewPanel(overview);\r
871 \r
872   }\r
873 \r
874   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
875   {\r
876     changeColour(null);\r
877   }\r
878 \r
879   public void clustalColour_actionPerformed(ActionEvent e)\r
880   {\r
881     abovePIDThreshold.setState(false);\r
882     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(),\r
883                                           viewport.alignment.getWidth()));\r
884   }\r
885 \r
886   public void zappoColour_actionPerformed(ActionEvent e)\r
887   {\r
888     changeColour(new ZappoColourScheme());\r
889   }\r
890 \r
891   public void taylorColour_actionPerformed(ActionEvent e)\r
892   {\r
893     changeColour(new TaylorColourScheme());\r
894   }\r
895 \r
896   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
897   {\r
898     changeColour(new HydrophobicColourScheme());\r
899   }\r
900 \r
901   public void helixColour_actionPerformed(ActionEvent e)\r
902   {\r
903     changeColour(new HelixColourScheme());\r
904   }\r
905 \r
906   public void strandColour_actionPerformed(ActionEvent e)\r
907   {\r
908     changeColour(new StrandColourScheme());\r
909   }\r
910 \r
911   public void turnColour_actionPerformed(ActionEvent e)\r
912   {\r
913     changeColour(new TurnColourScheme());\r
914   }\r
915 \r
916   public void buriedColour_actionPerformed(ActionEvent e)\r
917   {\r
918     changeColour(new BuriedColourScheme());\r
919   }\r
920 \r
921   public void nucleotideColour_actionPerformed(ActionEvent e)\r
922   {\r
923     changeColour(new NucleotideColourScheme());\r
924   }\r
925 \r
926   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
927   {\r
928     viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());\r
929   }\r
930 \r
931   void changeColour(ColourSchemeI cs)\r
932   {\r
933     int threshold = 0;\r
934 \r
935     if(cs!=null)\r
936     {\r
937       if (viewport.getAbovePIDThreshold())\r
938       {\r
939         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
940 \r
941         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
942 \r
943         viewport.setGlobalColourScheme(cs);\r
944       }\r
945       else\r
946       {\r
947         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
948       }\r
949 \r
950       if (viewport.getConservationSelected())\r
951       {\r
952 \r
953         Alignment al = (Alignment) viewport.alignment;\r
954         Conservation c = new Conservation("All",\r
955                                           ResidueProperties.propHash, 3,\r
956                                           al.getSequences(), 0,\r
957                                           al.getWidth() - 1);\r
958 \r
959         c.calculate();\r
960         c.verdict(false, viewport.ConsPercGaps);\r
961 \r
962         cs.setConservation(c);\r
963 \r
964         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel, cs,\r
965             "Background"));\r
966 \r
967       }\r
968       else\r
969       {\r
970         cs.setConservation(null);\r
971       }\r
972 \r
973       cs.setConsensus(viewport.vconsensus);\r
974 \r
975     }\r
976     viewport.setGlobalColourScheme(cs);\r
977 \r
978     if (viewport.getColourAppliesToAllGroups())\r
979     {\r
980       Vector groups = viewport.alignment.getGroups();\r
981       for (int i = 0; i < groups.size(); i++)\r
982       {\r
983         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
984 \r
985         if(cs==null)\r
986         {\r
987           sg.cs = null;\r
988           continue;\r
989         }\r
990         if (cs instanceof ClustalxColourScheme)\r
991         {\r
992           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
993         }\r
994         else\r
995         {\r
996           try\r
997           {\r
998             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
999           }\r
1000           catch (Exception ex)\r
1001           {\r
1002             ex.printStackTrace();\r
1003             sg.cs = cs;\r
1004           }\r
1005         }\r
1006 \r
1007         if (viewport.getAbovePIDThreshold()\r
1008             || cs instanceof PIDColourScheme\r
1009             || cs instanceof Blosum62ColourScheme)\r
1010         {\r
1011           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());\r
1012           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
1013         }\r
1014         else\r
1015           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1016 \r
1017         if (viewport.getConservationSelected())\r
1018         {\r
1019           Conservation c = new Conservation("Group",\r
1020                                             ResidueProperties.propHash, 3,\r
1021                                             sg.sequences, 0,\r
1022                                             viewport.alignment.getWidth() - 1);\r
1023           c.calculate();\r
1024           c.verdict(false, viewport.ConsPercGaps);\r
1025           sg.cs.setConservation(c);\r
1026         }\r
1027         else\r
1028         {\r
1029           sg.cs.setConservation(null);\r
1030           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());\r
1031         }\r
1032 \r
1033       }\r
1034     }\r
1035 \r
1036 \r
1037     if (alignPanel.getOverviewPanel() != null)\r
1038     {\r
1039       alignPanel.getOverviewPanel().updateOverviewImage();\r
1040     }\r
1041 \r
1042     alignPanel.repaint();\r
1043   }\r
1044 \r
1045 \r
1046 \r
1047   protected void modifyPID_actionPerformed(ActionEvent e)\r
1048   {\r
1049     if (viewport.getAbovePIDThreshold() && viewport.globalColourScheme!=null)\r
1050     {\r
1051       SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
1052                                      "Background");\r
1053       SliderPanel.showPIDSlider();\r
1054     }\r
1055   }\r
1056 \r
1057   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1058   {\r
1059     if (viewport.getConservationSelected() && viewport.globalColourScheme!=null)\r
1060     {\r
1061       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
1062                                         "Background");\r
1063       SliderPanel.showConservationSlider();\r
1064     }\r
1065   }\r
1066 \r
1067   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1068   {\r
1069     viewport.setConservationSelected(conservationMenuItem.getState());\r
1070 \r
1071     viewport.setAbovePIDThreshold(false);\r
1072     abovePIDThreshold.setState(false);\r
1073 \r
1074     changeColour(viewport.getGlobalColourScheme());\r
1075 \r
1076     modifyConservation_actionPerformed(null);\r
1077   }\r
1078 \r
1079   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1080   {\r
1081     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());\r
1082 \r
1083     conservationMenuItem.setState(false);\r
1084     viewport.setConservationSelected(false);\r
1085 \r
1086     changeColour(viewport.getGlobalColourScheme());\r
1087 \r
1088     modifyPID_actionPerformed(null);\r
1089   }\r
1090 \r
1091   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1092   {\r
1093     new UserDefinedColours(alignPanel, null);\r
1094   }\r
1095 \r
1096   public void PIDColour_actionPerformed(ActionEvent e)\r
1097   {\r
1098     changeColour(new PIDColourScheme());\r
1099   }\r
1100 \r
1101   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1102   {\r
1103     changeColour(new Blosum62ColourScheme());\r
1104   }\r
1105 \r
1106   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1107   {\r
1108     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1109                                    HistoryItem.SORT));\r
1110     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1111                               viewport.getAlignment().getSequenceAt(0));\r
1112     alignPanel.repaint();\r
1113   }\r
1114 \r
1115   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1116   {\r
1117     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1118                                    HistoryItem.SORT));\r
1119     AlignmentSorter.sortByID(viewport.getAlignment());\r
1120     alignPanel.repaint();\r
1121   }\r
1122 \r
1123   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1124   {\r
1125     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1126                                    HistoryItem.SORT));\r
1127     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1128     alignPanel.repaint();\r
1129 \r
1130   }\r
1131 \r
1132   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1133   {\r
1134     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
1135     Frame frame = new Frame();\r
1136     frame.add(sp);\r
1137     jalview.bin.JalviewLite.addFrame(frame, "Redundancy threshold selection",\r
1138                                      400, 120);\r
1139 \r
1140   }\r
1141 \r
1142   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1143   {\r
1144     if (viewport.getSelectionGroup().getSize() > 1)\r
1145     {\r
1146       Frame frame = new Frame();\r
1147       frame.add(new PairwiseAlignPanel(alignPanel));\r
1148       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600, 500);\r
1149     }\r
1150   }\r
1151 \r
1152   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1153   {\r
1154     //are the sequences aligned?\r
1155     if (!viewport.alignment.isAligned())\r
1156     {\r
1157       SequenceI current;\r
1158       int Width = viewport.getAlignment().getWidth();\r
1159 \r
1160       for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1161            i++)\r
1162       {\r
1163         current = viewport.getAlignment().getSequenceAt(i);\r
1164 \r
1165         if (current.getLength() < Width)\r
1166         {\r
1167           current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1168         }\r
1169       }\r
1170       alignPanel.repaint();\r
1171     }\r
1172 \r
1173     if ( (viewport.getSelectionGroup() != null &&\r
1174           viewport.getSelectionGroup().getSize() < 4 &&\r
1175           viewport.getSelectionGroup().getSize() > 0)\r
1176         || viewport.getAlignment().getHeight() < 4)\r
1177     {\r
1178       return;\r
1179     }\r
1180 \r
1181     try\r
1182     {\r
1183       new PCAPanel(viewport);\r
1184     }\r
1185     catch (java.lang.OutOfMemoryError ex)\r
1186     {\r
1187     }\r
1188 \r
1189   }\r
1190 \r
1191   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1192   {\r
1193     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1194   }\r
1195 \r
1196   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1197   {\r
1198     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1199   }\r
1200 \r
1201   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1202   {\r
1203     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1204   }\r
1205 \r
1206   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1207   {\r
1208     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1209   }\r
1210 \r
1211   void NewTreePanel(String type, String pwType, String title)\r
1212   {\r
1213     //are the sequences aligned?\r
1214     if (!viewport.alignment.isAligned())\r
1215     {\r
1216       SequenceI current;\r
1217       int Width = viewport.getAlignment().getWidth();\r
1218 \r
1219       for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
1220            i++)\r
1221       {\r
1222         current = viewport.getAlignment().getSequenceAt(i);\r
1223 \r
1224         if (current.getLength() < Width)\r
1225         {\r
1226           current.insertCharAt(Width - 1, viewport.getGapCharacter());\r
1227         }\r
1228       }\r
1229       alignPanel.repaint();\r
1230 \r
1231     }\r
1232 \r
1233     final TreePanel tp;\r
1234     if (viewport.getSelectionGroup() != null &&\r
1235         viewport.getSelectionGroup().getSize() > 3)\r
1236     {\r
1237       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1238                          pwType,\r
1239                          0, viewport.alignment.getWidth());\r
1240     }\r
1241     else\r
1242     {\r
1243       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1244                          type, pwType, 0, viewport.alignment.getWidth());\r
1245     }\r
1246 \r
1247     addTreeMenuItem(tp, title);\r
1248 \r
1249     jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);\r
1250   }\r
1251 \r
1252   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1253   {\r
1254     final MenuItem item = new MenuItem(title);\r
1255     sortByTreeMenu.add(item);\r
1256     item.addActionListener(new java.awt.event.ActionListener()\r
1257     {\r
1258       public void actionPerformed(ActionEvent e)\r
1259       {\r
1260         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1261                                        HistoryItem.SORT));\r
1262         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1263         alignPanel.repaint();\r
1264       }\r
1265     });\r
1266 \r
1267     treePanel.addWindowListener(new WindowAdapter()\r
1268     {\r
1269       public void windowClosing(WindowEvent e)\r
1270       {\r
1271         sortByTreeMenu.remove(item);\r
1272       };\r
1273     });\r
1274   }\r
1275 \r
1276   protected void documentation_actionPerformed(ActionEvent e)\r
1277   {\r
1278     jalview.bin.JalviewLite.showURL("http://www.jalview.org/help.html");\r
1279   }\r
1280 \r
1281   protected void about_actionPerformed(ActionEvent e)\r
1282   {\r
1283 \r
1284     class AboutPanel extends Canvas\r
1285     {\r
1286       String version;\r
1287       public AboutPanel(String version)\r
1288       { this.version = version; }\r
1289 \r
1290       public void paint(Graphics g)\r
1291       {\r
1292         g.setColor(Color.white);\r
1293         g.fillRect(0, 0, getSize().width, getSize().height);\r
1294         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1295         FontMetrics fm = g.getFontMetrics();\r
1296         int fh = fm.getHeight();\r
1297         int y = 5, x = 7;\r
1298         g.setColor(Color.black);\r
1299         g.setFont(new Font("Helvetica", Font.BOLD, 14));\r
1300         g.drawString("Jalview - Release "+version, 200, y += fh);\r
1301         g.setFont(new Font("Helvetica", Font.PLAIN, 12));\r
1302         g.drawString("Authors:  Michele Clamp, James Cuff, Steve Searle, Andrew Waterhouse, Jim Procter & Geoff Barton.",\r
1303                      x, y += fh * 2);\r
1304         g.drawString("Current development managed by Andrew Waterhouse; Barton Group, University of Dundee.",\r
1305                      x, y += fh);\r
1306         g.drawString(\r
1307             "For any issues relating to Jalview, email help@jalview.org", x,\r
1308             y += fh);\r
1309         g.drawString("If  you use JalView, please cite:", x, y += fh + 8);\r
1310         g.drawString("\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",\r
1311                      x, y += fh);\r
1312         g.drawString("Bioinformatics,  2004 12;426-7.", x, y += fh);\r
1313       }\r
1314     }\r
1315 \r
1316     String version = "test";\r
1317     java.net.URL url = getClass().getResource("/.build_properties");\r
1318     if (url != null)\r
1319     {\r
1320       try\r
1321       {\r
1322         BufferedReader reader = new BufferedReader(new InputStreamReader(\r
1323             url.openStream()));\r
1324         String line;\r
1325         while ( (line = reader.readLine()) != null)\r
1326         {\r
1327           if (line.indexOf("VERSION") > -1)\r
1328           {\r
1329             version = line.substring(line.indexOf("=") + 1);\r
1330           }\r
1331         }\r
1332       }\r
1333       catch (Exception ex)\r
1334       {\r
1335         ex.printStackTrace();\r
1336       }\r
1337     }\r
1338 \r
1339 \r
1340     Frame frame = new Frame();\r
1341     frame.add(new AboutPanel(version));\r
1342     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 200);\r
1343 \r
1344   }\r
1345 }\r