3280815a1c459e0cbb7a5aeeab0f49f20bb7b293
[jalview.git] / src / jalview / appletgui / AlignFrame.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.appletgui;
20
21 import java.io.*;
22 import java.net.*;
23 import java.util.*;
24
25 import java.awt.*;
26 import java.awt.event.*;
27
28 import jalview.analysis.*;
29 import jalview.commands.*;
30 import jalview.datamodel.*;
31 import jalview.io.*;
32 import jalview.schemes.*;
33
34 public class AlignFrame extends EmbmenuFrame implements ActionListener,
35         ItemListener, KeyListener
36 {
37   public AlignmentPanel alignPanel;
38
39   public AlignViewport viewport;
40
41   int DEFAULT_WIDTH = 700;
42
43   int DEFAULT_HEIGHT = 500;
44
45   String jalviewServletURL;
46
47   public AlignFrame(AlignmentI al, jalview.bin.JalviewLite applet,
48           String title, boolean embedded)
49   {
50
51     if (applet != null)
52     {
53       jalviewServletURL = applet.getParameter("APPLICATION_URL");
54     }
55
56     try
57     {
58       jbInit();
59     } catch (Exception ex)
60     {
61       ex.printStackTrace();
62     }
63
64     viewport = new AlignViewport(al, applet);
65     alignPanel = new AlignmentPanel(this, viewport);
66
67     viewport.updateConservation(alignPanel);
68     viewport.updateConsensus(alignPanel);
69
70     annotationPanelMenuItem.setState(viewport.showAnnotation);
71
72     seqLimits.setState(viewport.showJVSuffix);
73
74     if (applet != null)
75     {
76       String param = applet.getParameter("sortBy");
77       if (param != null)
78       {
79         if (param.equalsIgnoreCase("Id"))
80         {
81           sortIDMenuItem_actionPerformed();
82         }
83         else if (param.equalsIgnoreCase("Pairwise Identity"))
84         {
85           sortPairwiseMenuItem_actionPerformed();
86         }
87       }
88
89       param = applet.getParameter("wrap");
90       if (param != null)
91       {
92         if (param.equalsIgnoreCase("true"))
93         {
94           wrapMenuItem.setState(true);
95           wrapMenuItem_actionPerformed();
96         }
97       }
98       param = applet.getParameter("centrecolumnlabels");
99       if (param != null)
100       {
101         centreColumnLabelFlag.setState(true);
102         centreColumnLabelFlag_stateChanged();
103       }
104
105       try
106       {
107         param = applet.getParameter("windowWidth");
108         if (param != null)
109         {
110           int width = Integer.parseInt(param);
111           DEFAULT_WIDTH = width;
112         }
113         param = applet.getParameter("windowHeight");
114         if (param != null)
115         {
116           int height = Integer.parseInt(param);
117           DEFAULT_HEIGHT = height;
118         }
119       } catch (Exception ex)
120       {
121       }
122
123     }
124
125     // Some JVMS send keyevents to Top frame or lowest panel,
126     // Havent worked out why yet. So add to both this frame and seqCanvas for
127     // now
128     this.addKeyListener(this);
129     alignPanel.seqPanel.seqCanvas.addKeyListener(this);
130     alignPanel.idPanel.idCanvas.addKeyListener(this);
131     alignPanel.scalePanel.addKeyListener(this);
132     alignPanel.annotationPanel.addKeyListener(this);
133     createAlignFrameWindow(embedded, title);
134     alignPanel.validate();
135     alignPanel.paintAlignment(true);
136   }
137
138   public AlignViewport getAlignViewport()
139   {
140     return viewport;
141   }
142
143   public SeqCanvas getSeqcanvas()
144   {
145     return alignPanel.seqPanel.seqCanvas;
146   }
147
148   /**
149    * DOCUMENT ME!
150    * 
151    * @param String
152    *                DOCUMENT ME!
153    */
154
155   public void parseFeaturesFile(String file, String type)
156   {
157     Hashtable featureLinks = new Hashtable();
158     boolean featuresFile = false;
159     try
160     {
161       featuresFile = new jalview.io.FeaturesFile(file, type).parse(
162               viewport.alignment, alignPanel.seqPanel.seqCanvas
163                       .getFeatureRenderer().featureColours, featureLinks,
164               true);
165     } catch (Exception ex)
166     {
167       ex.printStackTrace();
168     }
169
170     if (featuresFile)
171     {
172       if (featureLinks.size() > 0)
173       {
174         alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureLinks = featureLinks;
175       }
176       viewport.showSequenceFeatures = true;
177       sequenceFeatures.setState(true);
178       alignPanel.paintAlignment(true);
179     }
180
181   }
182
183   public void keyPressed(KeyEvent evt)
184   {
185     if (viewport.cursorMode
186             && ((evt.getKeyCode() >= KeyEvent.VK_0 && evt.getKeyCode() <= KeyEvent.VK_9) || (evt
187                     .getKeyCode() >= KeyEvent.VK_NUMPAD0 && evt
188                     .getKeyCode() <= KeyEvent.VK_NUMPAD9))
189             && Character.isDigit(evt.getKeyChar()))
190       alignPanel.seqPanel.numberPressed(evt.getKeyChar());
191
192     switch (evt.getKeyCode())
193     {
194     case 27: // escape key
195       deselectAllSequenceMenuItem_actionPerformed();
196       break;
197     case KeyEvent.VK_X:
198       if (evt.isControlDown() || evt.isMetaDown())
199       {
200         cut_actionPerformed();
201       }
202       break;
203     case KeyEvent.VK_C:
204       if (viewport.cursorMode && !evt.isControlDown())
205       {
206         alignPanel.seqPanel.setCursorColumn();
207       }
208       if (evt.isControlDown() || evt.isMetaDown())
209       {
210         copy_actionPerformed();
211       }
212       break;
213     case KeyEvent.VK_V:
214       if (evt.isControlDown())
215       {
216         paste(evt.isShiftDown());
217       }
218       break;
219     case KeyEvent.VK_A:
220       if (evt.isControlDown() || evt.isMetaDown())
221       {
222         selectAllSequenceMenuItem_actionPerformed();
223       }
224       break;
225     case KeyEvent.VK_DOWN:
226       if (viewport.cursorMode)
227       {
228         alignPanel.seqPanel.moveCursor(0, 1);
229       }
230       else
231       {
232         moveSelectedSequences(false);
233       }
234       break;
235
236     case KeyEvent.VK_UP:
237       if (viewport.cursorMode)
238       {
239         alignPanel.seqPanel.moveCursor(0, -1);
240       }
241       else
242       {
243         moveSelectedSequences(true);
244       }
245       break;
246
247     case KeyEvent.VK_LEFT:
248       if (evt.isAltDown() || !viewport.cursorMode)
249         slideSequences(false, alignPanel.seqPanel.getKeyboardNo1());
250       else
251         alignPanel.seqPanel.moveCursor(-1, 0);
252       break;
253
254     case KeyEvent.VK_RIGHT:
255       if (evt.isAltDown() || !viewport.cursorMode)
256         slideSequences(true, alignPanel.seqPanel.getKeyboardNo1());
257       else
258         alignPanel.seqPanel.moveCursor(1, 0);
259       break;
260
261     case KeyEvent.VK_SPACE:
262       if (viewport.cursorMode)
263       {
264         alignPanel.seqPanel.insertGapAtCursor(evt.isControlDown()
265                 || evt.isShiftDown() || evt.isAltDown());
266       }
267       break;
268
269     case KeyEvent.VK_DELETE:
270     case KeyEvent.VK_BACK_SPACE:
271       if (viewport.cursorMode)
272       {
273         alignPanel.seqPanel.deleteGapAtCursor(evt.isControlDown()
274                 || evt.isShiftDown() || evt.isAltDown());
275       }
276       else
277       {
278         cut_actionPerformed();
279         alignPanel.seqPanel.seqCanvas.repaint();
280       }
281       break;
282
283     case KeyEvent.VK_S:
284       if (viewport.cursorMode)
285       {
286         alignPanel.seqPanel.setCursorRow();
287       }
288       break;
289     case KeyEvent.VK_P:
290       if (viewport.cursorMode)
291       {
292         alignPanel.seqPanel.setCursorPosition();
293       }
294       break;
295
296     case KeyEvent.VK_ENTER:
297     case KeyEvent.VK_COMMA:
298       if (viewport.cursorMode)
299       {
300         alignPanel.seqPanel.setCursorRowAndColumn();
301       }
302       break;
303
304     case KeyEvent.VK_Q:
305       if (viewport.cursorMode)
306       {
307         alignPanel.seqPanel.setSelectionAreaAtCursor(true);
308       }
309       break;
310     case KeyEvent.VK_M:
311       if (viewport.cursorMode)
312       {
313         alignPanel.seqPanel.setSelectionAreaAtCursor(false);
314       }
315       break;
316
317     case KeyEvent.VK_F2:
318       viewport.cursorMode = !viewport.cursorMode;
319       statusBar.setText("Keyboard editing mode is "
320               + (viewport.cursorMode ? "on" : "off"));
321       if (viewport.cursorMode)
322       {
323         alignPanel.seqPanel.seqCanvas.cursorX = viewport.startRes;
324         alignPanel.seqPanel.seqCanvas.cursorY = viewport.startSeq;
325       }
326       break;
327
328     case KeyEvent.VK_F:
329       if (evt.isControlDown())
330       {
331         findMenuItem_actionPerformed();
332       }
333       break;
334
335     case KeyEvent.VK_H:
336     {
337       boolean toggleSeqs = !evt.isControlDown();
338       boolean toggleCols = !evt.isShiftDown();
339       boolean hide = false;
340       SequenceGroup sg = viewport.getSelectionGroup();
341
342       if (toggleSeqs)
343       {
344         if (sg != null && sg.getSize() != viewport.alignment.getHeight())
345         {
346           hide = true;
347           viewport.hideAllSelectedSeqs();
348         }
349         else if (!(toggleCols && viewport.colSel.getSelected().size() > 0))
350         {
351           viewport.showAllHiddenSeqs();
352         }
353       }
354
355       if (toggleCols)
356       {
357         if (viewport.colSel.getSelected().size() > 0)
358         {
359           viewport.hideSelectedColumns();
360           if (!toggleSeqs)
361           {
362             viewport.selectionGroup = sg;
363           }
364         }
365         else if (!hide)
366         {
367           viewport.showAllHiddenColumns();
368         }
369       }
370       break;
371     }
372
373     case KeyEvent.VK_PAGE_UP:
374       if (viewport.wrapAlignment)
375       {
376         alignPanel.scrollUp(true);
377       }
378       else
379       {
380         alignPanel.setScrollValues(viewport.startRes, viewport.startSeq
381                 - viewport.endSeq + viewport.startSeq);
382       }
383       break;
384
385     case KeyEvent.VK_PAGE_DOWN:
386       if (viewport.wrapAlignment)
387       {
388         alignPanel.scrollUp(false);
389       }
390       else
391       {
392         alignPanel.setScrollValues(viewport.startRes, viewport.startSeq
393                 + viewport.endSeq - viewport.startSeq);
394       }
395       break;
396
397     case KeyEvent.VK_Z:
398       if (evt.isControlDown())
399       {
400         undoMenuItem_actionPerformed();
401       }
402       break;
403
404     case KeyEvent.VK_Y:
405       if (evt.isControlDown())
406       {
407         redoMenuItem_actionPerformed();
408       }
409       break;
410
411     case KeyEvent.VK_L:
412       if (evt.isControlDown())
413       {
414         trimAlignment(true);
415       }
416       break;
417
418     case KeyEvent.VK_R:
419       if (evt.isControlDown())
420       {
421         trimAlignment(false);
422       }
423       break;
424
425     case KeyEvent.VK_E:
426       if (evt.isControlDown())
427       {
428         if (evt.isShiftDown())
429         {
430           this.removeAllGapsMenuItem_actionPerformed();
431         }
432         else
433         {
434           removeGappedColumnMenuItem_actionPerformed();
435         }
436       }
437       break;
438     case KeyEvent.VK_I:
439       if (evt.isControlDown())
440       {
441         if (evt.isAltDown())
442         {
443           viewport.invertColumnSelection();
444         }
445         else
446         {
447           this.invertSequenceMenuItem_actionPerformed();
448         }
449       }
450       break;
451
452     case KeyEvent.VK_U:
453       if (evt.isControlDown())
454       {
455         this.deleteGroups_actionPerformed();
456       }
457       break;
458
459     case KeyEvent.VK_T:
460       if (evt.isControlDown())
461       {
462         newView(null);
463       }
464       break;
465
466     }
467     alignPanel.paintAlignment(true);
468   }
469
470   public void keyReleased(KeyEvent evt)
471   {
472   }
473
474   public void keyTyped(KeyEvent evt)
475   {
476   }
477
478   public void itemStateChanged(ItemEvent evt)
479   {
480     if (evt.getSource() == colourTextMenuItem)
481     {
482       colourTextMenuItem_actionPerformed();
483     }
484     else if (evt.getSource() == wrapMenuItem)
485     {
486       wrapMenuItem_actionPerformed();
487     }
488     else if (evt.getSource() == scaleAbove)
489     {
490       viewport.setScaleAboveWrapped(scaleAbove.getState());
491     }
492     else if (evt.getSource() == scaleLeft)
493     {
494       viewport.setScaleLeftWrapped(scaleLeft.getState());
495     }
496     else if (evt.getSource() == scaleRight)
497     {
498       viewport.setScaleRightWrapped(scaleRight.getState());
499     }
500     else if (evt.getSource() == seqLimits)
501     {
502       seqLimits_itemStateChanged();
503     }
504     else if (evt.getSource() == viewBoxesMenuItem)
505     {
506       viewport.setShowBoxes(viewBoxesMenuItem.getState());
507     }
508     else if (evt.getSource() == viewTextMenuItem)
509     {
510       viewport.setShowText(viewTextMenuItem.getState());
511     }
512     else if (evt.getSource() == renderGapsMenuItem)
513     {
514       viewport.setRenderGaps(renderGapsMenuItem.getState());
515     }
516     else if (evt.getSource() == annotationPanelMenuItem)
517     {
518       viewport.setShowAnnotation(annotationPanelMenuItem.getState());
519       alignPanel.setAnnotationVisible(annotationPanelMenuItem.getState());
520     }
521     else if (evt.getSource() == sequenceFeatures)
522     {
523       viewport.showSequenceFeatures(sequenceFeatures.getState());
524       alignPanel.seqPanel.seqCanvas.repaint();
525     }
526     else if (evt.getSource() == conservationMenuItem)
527     {
528       conservationMenuItem_actionPerformed();
529     }
530     else if (evt.getSource() == abovePIDThreshold)
531     {
532       abovePIDThreshold_actionPerformed();
533     }
534     else if (evt.getSource() == applyToAllGroups)
535     {
536       viewport.setColourAppliesToAllGroups(applyToAllGroups.getState());
537     }
538     else if (evt.getSource() == autoCalculate)
539     {
540       viewport.autocalculateConsensus = autoCalculate.getState();
541     }
542     else if (evt.getSource() == this.centreColumnLabelFlag)
543     {
544       centreColumnLabelFlag_stateChanged();
545     } else if (evt.getSource() == this.followMouseOverFlag)
546     {
547       mouseOverFlag_stateChanged();
548     }
549
550     alignPanel.paintAlignment(true);
551   }
552
553   private void mouseOverFlag_stateChanged()
554   {
555     viewport.followHighlight = followMouseOverFlag.getState();
556     // TODO: could kick the scrollTo mechanism to reset view for current searchresults.
557   }
558
559   private void centreColumnLabelFlag_stateChanged()
560   {
561     viewport.centreColumnLabels = centreColumnLabelFlag.getState();
562     this.alignPanel.annotationPanel.repaint();
563   }
564
565   public void actionPerformed(ActionEvent evt)
566   {
567     Object source = evt.getSource();
568
569     if (source == inputText)
570     {
571       inputText_actionPerformed();
572     }
573     else if (source == loadTree)
574     {
575       loadTree_actionPerformed();
576     }
577     else if (source == loadApplication)
578     {
579       launchFullApplication();
580     }
581     else if (source == loadAnnotations)
582     {
583       loadAnnotations();
584     }
585     else if (source == outputAnnotations)
586     {
587       outputAnnotations(true);
588     }
589     else if (source == outputFeatures)
590     {
591       outputFeatures(true, "Jalview");
592     }
593     else if (source == closeMenuItem)
594     {
595       closeMenuItem_actionPerformed();
596     }
597     else if (source == copy)
598     {
599       copy_actionPerformed();
600     }
601     else if (source == undoMenuItem)
602     {
603       undoMenuItem_actionPerformed();
604     }
605     else if (source == redoMenuItem)
606     {
607       redoMenuItem_actionPerformed();
608     }
609     else if (source == inputText)
610     {
611       inputText_actionPerformed();
612     }
613     else if (source == closeMenuItem)
614     {
615       closeMenuItem_actionPerformed();
616     }
617     else if (source == undoMenuItem)
618     {
619       undoMenuItem_actionPerformed();
620     }
621     else if (source == redoMenuItem)
622     {
623       redoMenuItem_actionPerformed();
624     }
625     else if (source == copy)
626     {
627       copy_actionPerformed();
628     }
629     else if (source == pasteNew)
630     {
631       pasteNew_actionPerformed();
632     }
633     else if (source == pasteThis)
634     {
635       pasteThis_actionPerformed();
636     }
637     else if (source == cut)
638     {
639       cut_actionPerformed();
640     }
641     else if (source == delete)
642     {
643       delete_actionPerformed();
644     }
645     else if (source == deleteGroups)
646     {
647       deleteGroups_actionPerformed();
648     }
649     else if (source == selectAllSequenceMenuItem)
650     {
651       selectAllSequenceMenuItem_actionPerformed();
652     }
653     else if (source == deselectAllSequenceMenuItem)
654     {
655       deselectAllSequenceMenuItem_actionPerformed();
656     }
657     else if (source == invertSequenceMenuItem)
658     {
659       invertSequenceMenuItem_actionPerformed();
660     }
661     else if (source == invertColSel)
662     {
663       viewport.invertColumnSelection();
664       alignPanel.paintAlignment(true);
665     }
666     else if (source == remove2LeftMenuItem)
667     {
668       trimAlignment(true);
669     }
670     else if (source == remove2RightMenuItem)
671     {
672       trimAlignment(false);
673     }
674     else if (source == removeGappedColumnMenuItem)
675     {
676       removeGappedColumnMenuItem_actionPerformed();
677     }
678     else if (source == removeAllGapsMenuItem)
679     {
680       removeAllGapsMenuItem_actionPerformed();
681     }
682     else if (source == findMenuItem)
683     {
684       findMenuItem_actionPerformed();
685     }
686     else if (source == font)
687     {
688       new FontChooser(alignPanel);
689     }
690     else if (source == newView)
691     {
692       newView(null);
693     }
694     else if (source == showColumns)
695     {
696       viewport.showAllHiddenColumns();
697       alignPanel.paintAlignment(true);
698     }
699     else if (source == showSeqs)
700     {
701       viewport.showAllHiddenSeqs();
702     }
703     else if (source == hideColumns)
704     {
705       viewport.hideSelectedColumns();
706       alignPanel.paintAlignment(true);
707     }
708     else if (source == hideSequences
709             && viewport.getSelectionGroup() != null)
710     {
711       viewport.hideAllSelectedSeqs();
712     }
713     else if (source == featureSettings)
714     {
715       new FeatureSettings(alignPanel);
716     }
717     else if (source == alProperties)
718     {
719       StringBuffer contents = new StringBuffer();
720
721       float avg = 0;
722       int min = Integer.MAX_VALUE, max = 0;
723       for (int i = 0; i < viewport.alignment.getHeight(); i++)
724       {
725         int size = viewport.alignment.getSequenceAt(i).getEnd()
726                 - viewport.alignment.getSequenceAt(i).getStart();
727         avg += size;
728         if (size > max)
729           max = size;
730         if (size < min)
731           min = size;
732       }
733       avg = avg / (float) viewport.alignment.getHeight();
734
735       contents.append("\nSequences: " + viewport.alignment.getHeight());
736       contents.append("\nMinimum Sequence Length: " + min);
737       contents.append("\nMaximum Sequence Length: " + max);
738       contents.append("\nAverage Length: " + (int) avg);
739
740       if (((Alignment) viewport.alignment).alignmentProperties != null)
741       {
742         Hashtable props = ((Alignment) viewport.alignment).alignmentProperties;
743         Enumeration en = props.keys();
744         while (en.hasMoreElements())
745         {
746           String key = en.nextElement().toString();
747           contents.append("\n" + key + "\t" + props.get(key));
748         }
749       }
750
751       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
752       cap.setText(contents.toString());
753       Frame frame = new Frame();
754       frame.add(cap);
755       jalview.bin.JalviewLite.addFrame(frame, "Alignment Properties: "
756               + getTitle(), 400, 250);
757     }
758     else if (source == overviewMenuItem)
759     {
760       overviewMenuItem_actionPerformed();
761     }
762     else if (source == noColourmenuItem)
763     {
764       changeColour(null);
765     }
766     else if (source == clustalColour)
767     {
768       abovePIDThreshold.setState(false);
769       changeColour(new ClustalxColourScheme(viewport.alignment
770               .getSequences(), viewport.alignment.getWidth()));
771     }
772     else if (source == zappoColour)
773     {
774       changeColour(new ZappoColourScheme());
775     }
776     else if (source == taylorColour)
777     {
778       changeColour(new TaylorColourScheme());
779     }
780     else if (source == hydrophobicityColour)
781     {
782       changeColour(new HydrophobicColourScheme());
783     }
784     else if (source == helixColour)
785     {
786       changeColour(new HelixColourScheme());
787     }
788     else if (source == strandColour)
789     {
790       changeColour(new StrandColourScheme());
791     }
792     else if (source == turnColour)
793     {
794       changeColour(new TurnColourScheme());
795     }
796     else if (source == buriedColour)
797     {
798       changeColour(new BuriedColourScheme());
799     }
800     else if (source == nucleotideColour)
801     {
802       changeColour(new NucleotideColourScheme());
803     }
804     else if (source == modifyPID)
805     {
806       modifyPID_actionPerformed();
807     }
808     else if (source == modifyConservation)
809     {
810       modifyConservation_actionPerformed();
811     }
812     else if (source == userDefinedColour)
813     {
814       new UserDefinedColours(alignPanel, null);
815     }
816     else if (source == PIDColour)
817     {
818       changeColour(new PIDColourScheme());
819     }
820     else if (source == BLOSUM62Colour)
821     {
822       changeColour(new Blosum62ColourScheme());
823     }
824     else if (source == annotationColour)
825     {
826       new AnnotationColourChooser(viewport, alignPanel);
827     }
828     else if (source == sortPairwiseMenuItem)
829     {
830       sortPairwiseMenuItem_actionPerformed();
831     }
832     else if (source == sortIDMenuItem)
833     {
834       sortIDMenuItem_actionPerformed();
835     }
836     else if (source == sortGroupMenuItem)
837     {
838       sortGroupMenuItem_actionPerformed();
839     }
840     else if (source == removeRedundancyMenuItem)
841     {
842       removeRedundancyMenuItem_actionPerformed();
843     }
844     else if (source == pairwiseAlignmentMenuItem)
845     {
846       pairwiseAlignmentMenuItem_actionPerformed();
847     }
848     else if (source == PCAMenuItem)
849     {
850       PCAMenuItem_actionPerformed();
851     }
852     else if (source == averageDistanceTreeMenuItem)
853     {
854       averageDistanceTreeMenuItem_actionPerformed();
855     }
856     else if (source == neighbourTreeMenuItem)
857     {
858       neighbourTreeMenuItem_actionPerformed();
859     }
860     else if (source == njTreeBlosumMenuItem)
861     {
862       njTreeBlosumMenuItem_actionPerformed();
863     }
864     else if (source == avDistanceTreeBlosumMenuItem)
865     {
866       avTreeBlosumMenuItem_actionPerformed();
867     }
868     else if (source == documentation)
869     {
870       documentation_actionPerformed();
871     }
872     else if (source == about)
873     {
874       about_actionPerformed();
875     }
876
877   }
878
879   public void inputText_actionPerformed()
880   {
881     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
882     Frame frame = new Frame();
883     frame.add(cap);
884     jalview.bin.JalviewLite.addFrame(frame, "Cut & Paste Input", 500, 500);
885   }
886
887   protected void outputText_actionPerformed(ActionEvent e)
888   {
889     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
890     Frame frame = new Frame();
891     frame.add(cap);
892     jalview.bin.JalviewLite.addFrame(frame, "Alignment output - "
893             + e.getActionCommand(), 600, 500);
894     cap.setText(new AppletFormatAdapter().formatSequences(e
895             .getActionCommand(), viewport.getAlignment(),
896             viewport.showJVSuffix));
897   }
898
899   public void loadAnnotations()
900   {
901     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
902     cap.setText("Paste your features / annotations file here.");
903     cap.setAnnotationImport();
904     Frame frame = new Frame();
905     frame.add(cap);
906     jalview.bin.JalviewLite.addFrame(frame, "Paste Annotations ", 400, 300);
907
908   }
909
910   public String outputAnnotations(boolean displayTextbox)
911   {
912     String annotation = new AnnotationFile().printAnnotations(
913             viewport.showAnnotation ? viewport.alignment
914                     .getAlignmentAnnotation() : null, viewport.alignment
915                     .getGroups(),
916             ((Alignment) viewport.alignment).alignmentProperties);
917
918     if (displayTextbox)
919     {
920       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
921       Frame frame = new Frame();
922       frame.add(cap);
923       jalview.bin.JalviewLite.addFrame(frame, "Annotations", 600, 500);
924       cap.setText(annotation);
925     }
926
927     return annotation;
928   }
929
930   public String outputFeatures(boolean displayTextbox, String format)
931   {
932     String features;
933     if (format.equalsIgnoreCase("Jalview"))
934     {
935       features = new FeaturesFile().printJalviewFormat(viewport.alignment
936               .getSequencesArray(), viewport.featuresDisplayed);
937     }
938     else
939     {
940       features = new FeaturesFile().printGFFFormat(viewport.alignment
941               .getSequencesArray(), viewport.featuresDisplayed);
942     }
943
944     if (displayTextbox)
945     {
946       CutAndPasteTransfer cap = new CutAndPasteTransfer(false, this);
947       Frame frame = new Frame();
948       frame.add(cap);
949       jalview.bin.JalviewLite.addFrame(frame, "Features", 600, 500);
950
951       cap.setText(features);
952     }
953
954     return features;
955   }
956
957   void launchFullApplication()
958   {
959     StringBuffer url = new StringBuffer(jalviewServletURL);
960
961     url.append("?open="
962             + appendProtocol(viewport.applet.getParameter("file")));
963
964     if (viewport.applet.getParameter("features") != null)
965     {
966       url.append("&features=");
967       url.append(appendProtocol(viewport.applet.getParameter("features")));
968     }
969
970     if (viewport.applet.getParameter("annotations") != null)
971     {
972       url.append("&annotations=");
973       url
974               .append(appendProtocol(viewport.applet
975                       .getParameter("annotations")));
976     }
977
978     if (viewport.applet.getParameter("jnetfile") != null)
979     {
980       url.append("&annotations=");
981       url.append(appendProtocol(viewport.applet.getParameter("jnetfile")));
982     }
983
984     if (viewport.applet.getParameter("defaultColour") != null)
985     {
986       url.append("&colour="
987               + removeWhiteSpace(viewport.applet
988                       .getParameter("defaultColour")));
989     }
990
991     if (viewport.applet.getParameter("userDefinedColour") != null)
992     {
993       url.append("&colour="
994               + removeWhiteSpace(viewport.applet
995                       .getParameter("userDefinedColour")));
996     }
997     if (viewport.applet.getParameter("tree") != null)
998     {
999       url.append("&tree="
1000               + appendProtocol(viewport.applet.getParameter("tree")));
1001     }
1002     if (viewport.applet.getParameter("treeFile") != null)
1003     {
1004       url.append("&tree="
1005               + appendProtocol(viewport.applet.getParameter("treeFile")));
1006     }
1007
1008     showURL(url.toString(), "FULL_APP");
1009   }
1010
1011   String removeWhiteSpace(String colour)
1012   {
1013     StringBuffer sb = new StringBuffer();
1014     for (int i = 0; i < colour.length(); i++)
1015     {
1016       if (Character.isWhitespace(colour.charAt(i)))
1017       {
1018         sb.append("%20");
1019       }
1020       else
1021       {
1022         sb.append(colour.charAt(i));
1023       }
1024     }
1025
1026     return sb.toString();
1027   }
1028
1029   String appendProtocol(String url)
1030   {
1031     try
1032     {
1033       new URL(url);
1034       url = URLEncoder.encode(url);
1035     }
1036     /*
1037      * When we finally deprecate 1.1 compatibility, we can start to use
1038      * URLEncoder.encode(url,"UTF-8") and then we'll need this catch: catch
1039      * (UnsupportedEncodingException ex) { System.err.println("WARNING -
1040      * IMPLEMENTATION ERROR - UNSUPPORTED ENCODING EXCEPTION FOR "+url);
1041      * ex.printStackTrace(); }
1042      */
1043     catch (java.net.MalformedURLException ex)
1044     {
1045       url = viewport.applet.getCodeBase() + url;
1046     }
1047     return url;
1048   }
1049
1050   public void closeMenuItem_actionPerformed()
1051   {
1052     PaintRefresher.RemoveComponent(alignPanel);
1053     PaintRefresher.RemoveComponent(alignPanel.seqPanel.seqCanvas);
1054     PaintRefresher.RemoveComponent(alignPanel.idPanel.idCanvas);
1055
1056     if (PaintRefresher.components.size() == 0 && viewport.applet == null)
1057     {
1058       System.exit(0);
1059     }
1060
1061     this.dispose();
1062   }
1063
1064   /**
1065    * DOCUMENT ME!
1066    */
1067   void updateEditMenuBar()
1068   {
1069
1070     if (viewport.historyList.size() > 0)
1071     {
1072       undoMenuItem.setEnabled(true);
1073       CommandI command = (CommandI) viewport.historyList.peek();
1074       undoMenuItem.setLabel("Undo " + command.getDescription());
1075     }
1076     else
1077     {
1078       undoMenuItem.setEnabled(false);
1079       undoMenuItem.setLabel("Undo");
1080     }
1081
1082     if (viewport.redoList.size() > 0)
1083     {
1084       redoMenuItem.setEnabled(true);
1085
1086       CommandI command = (CommandI) viewport.redoList.peek();
1087       redoMenuItem.setLabel("Redo " + command.getDescription());
1088     }
1089     else
1090     {
1091       redoMenuItem.setEnabled(false);
1092       redoMenuItem.setLabel("Redo");
1093     }
1094   }
1095
1096   public void addHistoryItem(CommandI command)
1097   {
1098     if (command.getSize() > 0)
1099     {
1100       viewport.historyList.push(command);
1101       viewport.redoList.removeAllElements();
1102       updateEditMenuBar();
1103       viewport.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1104     }
1105   }
1106
1107   /**
1108    * DOCUMENT ME!
1109    * 
1110    * @param e
1111    *                DOCUMENT ME!
1112    */
1113   protected void undoMenuItem_actionPerformed()
1114   {
1115     if (viewport.historyList.size() < 1)
1116     {
1117       return;
1118     }
1119
1120     CommandI command = (CommandI) viewport.historyList.pop();
1121     viewport.redoList.push(command);
1122     command.undoCommand(null);
1123
1124     AlignViewport originalSource = getOriginatingSource(command);
1125
1126     originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1127     updateEditMenuBar();
1128     originalSource.firePropertyChange("alignment", null,
1129             originalSource.alignment.getSequences());
1130   }
1131
1132   /**
1133    * DOCUMENT ME!
1134    * 
1135    * @param e
1136    *                DOCUMENT ME!
1137    */
1138   protected void redoMenuItem_actionPerformed()
1139   {
1140     if (viewport.redoList.size() < 1)
1141     {
1142       return;
1143     }
1144
1145     CommandI command = (CommandI) viewport.redoList.pop();
1146     viewport.historyList.push(command);
1147     command.doCommand(null);
1148
1149     AlignViewport originalSource = getOriginatingSource(command);
1150     originalSource.hasHiddenColumns = viewport.colSel.getHiddenColumns() != null;
1151
1152     updateEditMenuBar();
1153     originalSource.firePropertyChange("alignment", null,
1154             originalSource.alignment.getSequences());
1155   }
1156
1157   AlignViewport getOriginatingSource(CommandI command)
1158   {
1159     AlignViewport originalSource = null;
1160     // For sequence removal and addition, we need to fire
1161     // the property change event FROM the viewport where the
1162     // original alignment was altered
1163     AlignmentI al = null;
1164     if (command instanceof EditCommand)
1165     {
1166       EditCommand editCommand = (EditCommand) command;
1167       al = editCommand.getAlignment();
1168       Vector comps = (Vector) PaintRefresher.components.get(viewport
1169               .getSequenceSetId());
1170       for (int i = 0; i < comps.size(); i++)
1171       {
1172         if (comps.elementAt(i) instanceof AlignmentPanel)
1173         {
1174           if (al == ((AlignmentPanel) comps.elementAt(i)).av.alignment)
1175           {
1176             originalSource = ((AlignmentPanel) comps.elementAt(i)).av;
1177             break;
1178           }
1179         }
1180       }
1181     }
1182
1183     if (originalSource == null)
1184     {
1185       // The original view is closed, we must validate
1186       // the current view against the closed view first
1187       if (al != null)
1188       {
1189         PaintRefresher.validateSequences(al, viewport.alignment);
1190       }
1191
1192       originalSource = viewport;
1193     }
1194
1195     return originalSource;
1196   }
1197
1198   public void moveSelectedSequences(boolean up)
1199   {
1200     SequenceGroup sg = viewport.getSelectionGroup();
1201     if (sg == null)
1202     {
1203       return;
1204     }
1205
1206     if (up)
1207     {
1208       for (int i = 1; i < viewport.alignment.getHeight(); i++)
1209       {
1210         SequenceI seq = viewport.alignment.getSequenceAt(i);
1211         if (!sg.getSequences(null).contains(seq))
1212         {
1213           continue;
1214         }
1215
1216         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);
1217         if (sg.getSequences(null).contains(temp))
1218         {
1219           continue;
1220         }
1221
1222         viewport.alignment.getSequences().setElementAt(temp, i);
1223         viewport.alignment.getSequences().setElementAt(seq, i - 1);
1224       }
1225     }
1226     else
1227     {
1228       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)
1229       {
1230         SequenceI seq = viewport.alignment.getSequenceAt(i);
1231         if (!sg.getSequences(viewport.hiddenRepSequences).contains(seq))
1232         {
1233           continue;
1234         }
1235
1236         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);
1237         if (sg.getSequences(viewport.hiddenRepSequences).contains(temp))
1238         {
1239           continue;
1240         }
1241
1242         viewport.alignment.getSequences().setElementAt(temp, i);
1243         viewport.alignment.getSequences().setElementAt(seq, i + 1);
1244       }
1245     }
1246
1247     alignPanel.paintAlignment(true);
1248   }
1249
1250   synchronized void slideSequences(boolean right, int size)
1251   {
1252     Vector sg = new Vector();
1253     if (viewport.cursorMode)
1254     {
1255       sg.addElement(viewport.alignment
1256               .getSequenceAt(alignPanel.seqPanel.seqCanvas.cursorY));
1257     }
1258     else if (viewport.getSelectionGroup() != null
1259             && viewport.getSelectionGroup().getSize() != viewport.alignment
1260                     .getHeight())
1261     {
1262       sg = viewport.getSelectionGroup().getSequences(
1263               viewport.hiddenRepSequences);
1264     }
1265
1266     if (sg.size() < 1)
1267     {
1268       return;
1269     }
1270
1271     Vector invertGroup = new Vector();
1272
1273     for (int i = 0; i < viewport.alignment.getHeight(); i++)
1274     {
1275       if (!sg.contains(viewport.alignment.getSequenceAt(i)))
1276         invertGroup.addElement(viewport.alignment.getSequenceAt(i));
1277     }
1278
1279     SequenceI[] seqs1 = new SequenceI[sg.size()];
1280     for (int i = 0; i < sg.size(); i++)
1281       seqs1[i] = (SequenceI) sg.elementAt(i);
1282
1283     SequenceI[] seqs2 = new SequenceI[invertGroup.size()];
1284     for (int i = 0; i < invertGroup.size(); i++)
1285       seqs2[i] = (SequenceI) invertGroup.elementAt(i);
1286
1287     SlideSequencesCommand ssc;
1288     if (right)
1289       ssc = new SlideSequencesCommand("Slide Sequences", seqs2, seqs1,
1290               size, viewport.getGapCharacter());
1291     else
1292       ssc = new SlideSequencesCommand("Slide Sequences", seqs1, seqs2,
1293               size, viewport.getGapCharacter());
1294
1295     int groupAdjustment = 0;
1296     if (ssc.getGapsInsertedBegin() && right)
1297     {
1298       if (viewport.cursorMode)
1299         alignPanel.seqPanel.moveCursor(size, 0);
1300       else
1301         groupAdjustment = size;
1302     }
1303     else if (!ssc.getGapsInsertedBegin() && !right)
1304     {
1305       if (viewport.cursorMode)
1306         alignPanel.seqPanel.moveCursor(-size, 0);
1307       else
1308         groupAdjustment = -size;
1309     }
1310
1311     if (groupAdjustment != 0)
1312     {
1313       viewport.getSelectionGroup().setStartRes(
1314               viewport.getSelectionGroup().getStartRes() + groupAdjustment);
1315       viewport.getSelectionGroup().setEndRes(
1316               viewport.getSelectionGroup().getEndRes() + groupAdjustment);
1317     }
1318
1319     boolean appendHistoryItem = false;
1320     if (viewport.historyList != null && viewport.historyList.size() > 0
1321             && viewport.historyList.peek() instanceof SlideSequencesCommand)
1322     {
1323       appendHistoryItem = ssc
1324               .appendSlideCommand((SlideSequencesCommand) viewport.historyList
1325                       .peek());
1326     }
1327
1328     if (!appendHistoryItem)
1329       addHistoryItem(ssc);
1330
1331     repaint();
1332   }
1333
1334   static StringBuffer copiedSequences;
1335
1336   static Vector copiedHiddenColumns;
1337
1338   protected void copy_actionPerformed()
1339   {
1340     if (viewport.getSelectionGroup() == null)
1341     {
1342       return;
1343     }
1344
1345     SequenceGroup sg = viewport.getSelectionGroup();
1346     copiedSequences = new StringBuffer();
1347     Hashtable orderedSeqs = new Hashtable();
1348     for (int i = 0; i < sg.getSize(); i++)
1349     {
1350       SequenceI seq = sg.getSequenceAt(i);
1351       int index = viewport.alignment.findIndex(seq);
1352       orderedSeqs.put(index + "", seq);
1353     }
1354
1355     int index = 0, startRes, endRes;
1356     char ch;
1357
1358     if (viewport.hasHiddenColumns && viewport.getSelectionGroup() != null)
1359     {
1360       copiedHiddenColumns = new Vector();
1361       int hiddenOffset = viewport.getSelectionGroup().getStartRes();
1362       for (int i = 0; i < viewport.getColumnSelection().getHiddenColumns()
1363               .size(); i++)
1364       {
1365         int[] region = (int[]) viewport.getColumnSelection()
1366                 .getHiddenColumns().elementAt(i);
1367
1368         copiedHiddenColumns.addElement(new int[]
1369         { region[0] - hiddenOffset, region[1] - hiddenOffset });
1370       }
1371     }
1372     else
1373     {
1374       copiedHiddenColumns = null;
1375     }
1376
1377     for (int i = 0; i < sg.getSize(); i++)
1378     {
1379       SequenceI seq = null;
1380
1381       while (seq == null)
1382       {
1383         if (orderedSeqs.containsKey(index + ""))
1384         {
1385           seq = (SequenceI) orderedSeqs.get(index + "");
1386           index++;
1387
1388           break;
1389         }
1390         else
1391         {
1392           index++;
1393         }
1394       }
1395
1396       // FIND START RES
1397       // Returns residue following index if gap
1398       startRes = seq.findPosition(sg.getStartRes());
1399
1400       // FIND END RES
1401       // Need to find the residue preceeding index if gap
1402       endRes = 0;
1403
1404       for (int j = 0; j < sg.getEndRes() + 1 && j < seq.getLength(); j++)
1405       {
1406         ch = seq.getCharAt(j);
1407         if (!jalview.util.Comparison.isGap((ch)))
1408         {
1409           endRes++;
1410         }
1411       }
1412
1413       if (endRes > 0)
1414       {
1415         endRes += seq.getStart() - 1;
1416       }
1417
1418       copiedSequences.append(seq.getName()
1419               + "\t"
1420               + startRes
1421               + "\t"
1422               + endRes
1423               + "\t"
1424               + seq.getSequenceAsString(sg.getStartRes(),
1425                       sg.getEndRes() + 1) + "\n");
1426     }
1427
1428   }
1429
1430   protected void pasteNew_actionPerformed()
1431   {
1432     paste(true);
1433   }
1434
1435   protected void pasteThis_actionPerformed()
1436   {
1437     paste(false);
1438   }
1439
1440   void paste(boolean newAlignment)
1441   {
1442     try
1443     {
1444
1445       if (copiedSequences == null)
1446       {
1447         return;
1448       }
1449
1450       StringTokenizer st = new StringTokenizer(copiedSequences.toString());
1451       Vector seqs = new Vector();
1452       while (st.hasMoreElements())
1453       {
1454         String name = st.nextToken();
1455         int start = Integer.parseInt(st.nextToken());
1456         int end = Integer.parseInt(st.nextToken());
1457         seqs.addElement(new Sequence(name, st.nextToken(), start, end));
1458       }
1459       SequenceI[] newSeqs = new SequenceI[seqs.size()];
1460       for (int i = 0; i < seqs.size(); i++)
1461       {
1462         newSeqs[i] = (SequenceI) seqs.elementAt(i);
1463       }
1464
1465       if (newAlignment)
1466       {
1467         String newtitle = new String("Copied sequences");
1468         if (getTitle().startsWith("Copied sequences"))
1469         {
1470           newtitle = getTitle();
1471         }
1472         else
1473         {
1474           newtitle = newtitle.concat("- from " + getTitle());
1475         }
1476         AlignFrame af = new AlignFrame(new Alignment(newSeqs),
1477                 viewport.applet, newtitle, false);
1478         if (copiedHiddenColumns != null)
1479         {
1480           for (int i = 0; i < copiedHiddenColumns.size(); i++)
1481           {
1482             int[] region = (int[]) copiedHiddenColumns.elementAt(i);
1483             af.viewport.hideColumns(region[0], region[1]);
1484           }
1485         }
1486
1487         jalview.bin.JalviewLite.addFrame(af, newtitle, DEFAULT_WIDTH,
1488                 DEFAULT_HEIGHT);
1489       }
1490       else
1491       {
1492         addSequences(newSeqs);
1493       }
1494
1495     } catch (Exception ex)
1496     {
1497     } // could be anything being pasted in here
1498
1499   }
1500
1501   void addSequences(SequenceI[] seqs)
1502   {
1503     for (int i = 0; i < seqs.length; i++)
1504     {
1505       viewport.alignment.addSequence(seqs[i]);
1506     }
1507
1508     // !newAlignment
1509     addHistoryItem(new EditCommand("Add sequences", EditCommand.PASTE,
1510             seqs, 0, viewport.alignment.getWidth(), viewport.alignment));
1511
1512     viewport.setEndSeq(viewport.alignment.getHeight());
1513     viewport.alignment.getWidth();
1514     viewport.firePropertyChange("alignment", null, viewport.alignment
1515             .getSequences());
1516
1517   }
1518
1519   protected void cut_actionPerformed()
1520   {
1521     copy_actionPerformed();
1522     delete_actionPerformed();
1523   }
1524
1525   protected void delete_actionPerformed()
1526   {
1527
1528     SequenceGroup sg = viewport.getSelectionGroup();
1529     if (sg == null)
1530     {
1531       return;
1532     }
1533
1534     Vector seqs = new Vector();
1535     SequenceI seq;
1536     for (int i = 0; i < sg.getSize(); i++)
1537     {
1538       seq = sg.getSequenceAt(i);
1539       seqs.addElement(seq);
1540     }
1541
1542     // If the cut affects all sequences, remove highlighted columns
1543     if (sg.getSize() == viewport.alignment.getHeight())
1544     {
1545       viewport.getColumnSelection().removeElements(sg.getStartRes(),
1546               sg.getEndRes() + 1);
1547     }
1548
1549     SequenceI[] cut = new SequenceI[seqs.size()];
1550     for (int i = 0; i < seqs.size(); i++)
1551     {
1552       cut[i] = (SequenceI) seqs.elementAt(i);
1553     }
1554
1555     /*
1556      * //ADD HISTORY ITEM
1557      */
1558     addHistoryItem(new EditCommand("Cut Sequences", EditCommand.CUT, cut,
1559             sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
1560             viewport.alignment));
1561
1562     viewport.setSelectionGroup(null);
1563     viewport.alignment.deleteGroup(sg);
1564
1565     viewport.firePropertyChange("alignment", null, viewport.getAlignment()
1566             .getSequences());
1567
1568     if (viewport.getAlignment().getHeight() < 1)
1569     {
1570       this.setVisible(false);
1571     }
1572   }
1573
1574   protected void deleteGroups_actionPerformed()
1575   {
1576     viewport.alignment.deleteAllGroups();
1577     viewport.sequenceColours = null;
1578     viewport.setSelectionGroup(null);
1579
1580     alignPanel.paintAlignment(true);
1581   }
1582
1583   public void selectAllSequenceMenuItem_actionPerformed()
1584   {
1585     SequenceGroup sg = new SequenceGroup();
1586     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
1587     {
1588       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
1589     }
1590     sg.setEndRes(viewport.alignment.getWidth() - 1);
1591     viewport.setSelectionGroup(sg);
1592     alignPanel.paintAlignment(true);
1593     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1594   }
1595
1596   public void deselectAllSequenceMenuItem_actionPerformed()
1597   {
1598     if (viewport.cursorMode)
1599     {
1600       alignPanel.seqPanel.keyboardNo1 = null;
1601       alignPanel.seqPanel.keyboardNo2 = null;
1602     }
1603     viewport.setSelectionGroup(null);
1604     viewport.getColumnSelection().clear();
1605     viewport.setSelectionGroup(null);
1606     alignPanel.idPanel.idCanvas.searchResults = null;
1607     alignPanel.seqPanel.seqCanvas.highlightSearchResults(null);
1608     alignPanel.paintAlignment(true);
1609     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1610   }
1611
1612   public void invertSequenceMenuItem_actionPerformed()
1613   {
1614     SequenceGroup sg = viewport.getSelectionGroup();
1615     for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
1616     {
1617       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);
1618     }
1619
1620     PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
1621   }
1622
1623   void trimAlignment(boolean trimLeft)
1624   {
1625     ColumnSelection colSel = viewport.getColumnSelection();
1626     int column;
1627
1628     if (colSel.size() > 0)
1629     {
1630       if (trimLeft)
1631       {
1632         column = colSel.getMin();
1633       }
1634       else
1635       {
1636         column = colSel.getMax();
1637       }
1638
1639       SequenceI[] seqs;
1640       if (viewport.getSelectionGroup() != null)
1641       {
1642         seqs = viewport.getSelectionGroup().getSequencesAsArray(
1643                 viewport.hiddenRepSequences);
1644       }
1645       else
1646       {
1647         seqs = viewport.alignment.getSequencesArray();
1648       }
1649
1650       TrimRegionCommand trimRegion;
1651       if (trimLeft)
1652       {
1653         trimRegion = new TrimRegionCommand("Remove Left",
1654                 TrimRegionCommand.TRIM_LEFT, seqs, column,
1655                 viewport.alignment, viewport.colSel,
1656                 viewport.selectionGroup);
1657         viewport.setStartRes(0);
1658       }
1659       else
1660       {
1661         trimRegion = new TrimRegionCommand("Remove Right",
1662                 TrimRegionCommand.TRIM_RIGHT, seqs, column,
1663                 viewport.alignment, viewport.colSel,
1664                 viewport.selectionGroup);
1665       }
1666
1667       statusBar.setText("Removed " + trimRegion.getSize() + " columns.");
1668
1669       addHistoryItem(trimRegion);
1670
1671       Vector groups = viewport.alignment.getGroups();
1672
1673       for (int i = 0; i < groups.size(); i++)
1674       {
1675         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
1676
1677         if ((trimLeft && !sg.adjustForRemoveLeft(column))
1678                 || (!trimLeft && !sg.adjustForRemoveRight(column)))
1679         {
1680           viewport.alignment.deleteGroup(sg);
1681         }
1682       }
1683
1684       viewport.firePropertyChange("alignment", null, viewport
1685               .getAlignment().getSequences());
1686     }
1687   }
1688
1689   public void removeGappedColumnMenuItem_actionPerformed()
1690   {
1691     int start = 0, end = viewport.alignment.getWidth() - 1;
1692
1693     SequenceI[] seqs;
1694     if (viewport.getSelectionGroup() != null)
1695     {
1696       seqs = viewport.getSelectionGroup().getSequencesAsArray(
1697               viewport.hiddenRepSequences);
1698       start = viewport.getSelectionGroup().getStartRes();
1699       end = viewport.getSelectionGroup().getEndRes();
1700     }
1701     else
1702     {
1703       seqs = viewport.alignment.getSequencesArray();
1704     }
1705
1706     RemoveGapColCommand removeGapCols = new RemoveGapColCommand(
1707             "Remove Gapped Columns", seqs, start, end, viewport.alignment);
1708
1709     addHistoryItem(removeGapCols);
1710
1711     statusBar.setText("Removed " + removeGapCols.getSize()
1712             + " empty columns.");
1713
1714     // This is to maintain viewport position on first residue
1715     // of first sequence
1716     SequenceI seq = viewport.alignment.getSequenceAt(0);
1717     int startRes = seq.findPosition(viewport.startRes);
1718     // ShiftList shifts;
1719     // viewport.getAlignment().removeGaps(shifts=new ShiftList());
1720     // edit.alColumnChanges=shifts.getInverse();
1721     // if (viewport.hasHiddenColumns)
1722     // viewport.getColumnSelection().compensateForEdits(shifts);
1723     viewport.setStartRes(seq.findIndex(startRes) - 1);
1724     viewport.firePropertyChange("alignment", null, viewport.getAlignment()
1725             .getSequences());
1726
1727   }
1728
1729   public void removeAllGapsMenuItem_actionPerformed()
1730   {
1731     int start = 0, end = viewport.alignment.getWidth() - 1;
1732
1733     SequenceI[] seqs;
1734     if (viewport.getSelectionGroup() != null)
1735     {
1736       seqs = viewport.getSelectionGroup().getSequencesAsArray(
1737               viewport.hiddenRepSequences);
1738       start = viewport.getSelectionGroup().getStartRes();
1739       end = viewport.getSelectionGroup().getEndRes();
1740     }
1741     else
1742     {
1743       seqs = viewport.alignment.getSequencesArray();
1744     }
1745
1746     // This is to maintain viewport position on first residue
1747     // of first sequence
1748     SequenceI seq = viewport.alignment.getSequenceAt(0);
1749     int startRes = seq.findPosition(viewport.startRes);
1750
1751     addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
1752             viewport.alignment));
1753
1754     viewport.setStartRes(seq.findIndex(startRes) - 1);
1755
1756     viewport.firePropertyChange("alignment", null, viewport.getAlignment()
1757             .getSequences());
1758
1759   }
1760
1761   public void findMenuItem_actionPerformed()
1762   {
1763     new Finder(alignPanel);
1764   }
1765
1766   /**
1767    * create a new view derived from the current view
1768    * 
1769    * @param viewtitle
1770    * @return frame for the new view
1771    */
1772   public AlignFrame newView(String viewtitle)
1773   {
1774     AlignmentI newal;
1775     if (viewport.hasHiddenRows)
1776     {
1777       newal = new Alignment(viewport.getAlignment().getHiddenSequences()
1778               .getFullAlignment().getSequencesArray());
1779     }
1780     else
1781     {
1782       newal = new Alignment(viewport.alignment.getSequencesArray());
1783     }
1784
1785     if (viewport.alignment.getAlignmentAnnotation() != null)
1786     {
1787       for (int i = 0; i < viewport.alignment.getAlignmentAnnotation().length; i++)
1788       {
1789         if (!viewport.alignment.getAlignmentAnnotation()[i].autoCalculated)
1790         {
1791           newal
1792                   .addAnnotation(viewport.alignment
1793                           .getAlignmentAnnotation()[i]);
1794         }
1795       }
1796     }
1797
1798     AlignFrame newaf = new AlignFrame(newal, viewport.applet, "", false);
1799
1800     newaf.viewport.sequenceSetID = alignPanel.av.getSequenceSetId();
1801     PaintRefresher.Register(alignPanel, alignPanel.av.getSequenceSetId());
1802     PaintRefresher.Register(newaf.alignPanel, newaf.alignPanel.av
1803             .getSequenceSetId());
1804
1805     PaintRefresher.Register(newaf.alignPanel.idPanel.idCanvas,
1806             newaf.alignPanel.av.getSequenceSetId());
1807     PaintRefresher.Register(newaf.alignPanel.seqPanel.seqCanvas,
1808             newaf.alignPanel.av.getSequenceSetId());
1809
1810     Vector comps = (Vector) PaintRefresher.components.get(viewport
1811             .getSequenceSetId());
1812     int viewSize = -1;
1813     for (int i = 0; i < comps.size(); i++)
1814     {
1815       if (comps.elementAt(i) instanceof AlignmentPanel)
1816       {
1817         viewSize++;
1818       }
1819     }
1820
1821     String title = new String(this.getTitle());
1822     if (viewtitle != null)
1823     {
1824       title = viewtitle + " ( " + title + ")";
1825     }
1826     else
1827     {
1828       if (title.indexOf("(View") > -1)
1829       {
1830         title = title.substring(0, title.indexOf("(View"));
1831       }
1832       title += "(View " + viewSize + ")";
1833     }
1834
1835     newaf.setTitle(title.toString());
1836
1837     newaf.viewport.historyList = viewport.historyList;
1838     newaf.viewport.redoList = viewport.redoList;
1839     return newaf;
1840   }
1841
1842   /**
1843    * 
1844    * @return list of feature groups on the view
1845    */
1846   public String[] getFeatureGroups()
1847   {
1848     FeatureRenderer fr = null;
1849     if (alignPanel != null
1850             && (fr = alignPanel.getFeatureRenderer()) != null)
1851     {
1852       return fr.getGroups();
1853     }
1854     return null;
1855   }
1856
1857   /**
1858    * get sequence feature groups that are hidden or shown
1859    * 
1860    * @param visible
1861    *                true is visible
1862    * @return list
1863    */
1864   public String[] getFeatureGroupsOfState(boolean visible)
1865   {
1866     FeatureRenderer fr = null;
1867     if (alignPanel != null
1868             && (fr = alignPanel.getFeatureRenderer()) != null)
1869     {
1870       return fr.getGroups(visible);
1871     }
1872     return null;
1873   }
1874
1875   /**
1876    * Change the display state for the given feature groups
1877    * 
1878    * @param groups
1879    *                list of group strings
1880    * @param state
1881    *                visible or invisible
1882    */
1883   public void setFeatureGroupState(String[] groups, boolean state)
1884   {
1885     FeatureRenderer fr = null;
1886     this.sequenceFeatures.setState(true);
1887     viewport.showSequenceFeatures(true);
1888     if (alignPanel != null
1889             && (fr = alignPanel.getFeatureRenderer()) != null)
1890     {
1891       fr.setGroupState(groups, state);
1892       alignPanel.seqPanel.seqCanvas.repaint();
1893       if (alignPanel.overviewPanel != null)
1894       {
1895         alignPanel.overviewPanel.updateOverviewImage();
1896       }
1897     }
1898   }
1899
1900   public void seqLimits_itemStateChanged()
1901   {
1902     viewport.setShowJVSuffix(seqLimits.getState());
1903     alignPanel.fontChanged();
1904     alignPanel.paintAlignment(true);
1905   }
1906
1907   protected void colourTextMenuItem_actionPerformed()
1908   {
1909     viewport.setColourText(colourTextMenuItem.getState());
1910     alignPanel.paintAlignment(true);
1911   }
1912
1913   protected void wrapMenuItem_actionPerformed()
1914   {
1915     viewport.setWrapAlignment(wrapMenuItem.getState());
1916     alignPanel.setWrapAlignment(wrapMenuItem.getState());
1917     scaleAbove.setEnabled(wrapMenuItem.getState());
1918     scaleLeft.setEnabled(wrapMenuItem.getState());
1919     scaleRight.setEnabled(wrapMenuItem.getState());
1920     alignPanel.paintAlignment(true);
1921   }
1922
1923   public void overviewMenuItem_actionPerformed()
1924   {
1925     if (alignPanel.overviewPanel != null)
1926     {
1927       return;
1928     }
1929
1930     Frame frame = new Frame();
1931     OverviewPanel overview = new OverviewPanel(alignPanel);
1932     frame.add(overview);
1933     // +50 must allow for applet frame window
1934     jalview.bin.JalviewLite.addFrame(frame, "Overview " + this.getTitle(),
1935             overview.getPreferredSize().width,
1936             overview.getPreferredSize().height + 50);
1937
1938     frame.pack();
1939     frame.addWindowListener(new WindowAdapter()
1940     {
1941       public void windowClosing(WindowEvent e)
1942       {
1943         alignPanel.setOverviewPanel(null);
1944       };
1945     });
1946
1947     alignPanel.setOverviewPanel(overview);
1948
1949   }
1950
1951   void changeColour(ColourSchemeI cs)
1952   {
1953     int threshold = 0;
1954
1955     if (cs != null)
1956     {
1957       if (viewport.getAbovePIDThreshold())
1958       {
1959         threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,
1960                 "Background");
1961
1962         cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
1963
1964         viewport.setGlobalColourScheme(cs);
1965       }
1966       else
1967       {
1968         cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
1969       }
1970
1971       if (viewport.getConservationSelected())
1972       {
1973
1974         Alignment al = (Alignment) viewport.alignment;
1975         Conservation c = new Conservation("All",
1976                 ResidueProperties.propHash, 3, al.getSequences(), 0, al
1977                         .getWidth() - 1);
1978
1979         c.calculate();
1980         c.verdict(false, viewport.ConsPercGaps);
1981
1982         cs.setConservation(c);
1983
1984         cs.setConservationInc(SliderPanel.setConservationSlider(alignPanel,
1985                 cs, "Background"));
1986
1987       }
1988       else
1989       {
1990         cs.setConservation(null);
1991       }
1992
1993       cs.setConsensus(viewport.hconsensus);
1994
1995     }
1996     viewport.setGlobalColourScheme(cs);
1997
1998     if (viewport.getColourAppliesToAllGroups())
1999     {
2000       Vector groups = viewport.alignment.getGroups();
2001       for (int i = 0; i < groups.size(); i++)
2002       {
2003         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);
2004
2005         if (cs == null)
2006         {
2007           sg.cs = null;
2008           continue;
2009         }
2010         if (cs instanceof ClustalxColourScheme)
2011         {
2012           sg.cs = new ClustalxColourScheme(sg
2013                   .getSequences(viewport.hiddenRepSequences), sg.getWidth());
2014         }
2015         else
2016         {
2017           try
2018           {
2019             sg.cs = (ColourSchemeI) cs.getClass().newInstance();
2020           } catch (Exception ex)
2021           {
2022             ex.printStackTrace();
2023             sg.cs = cs;
2024           }
2025         }
2026
2027         if (viewport.getAbovePIDThreshold()
2028                 || cs instanceof PIDColourScheme
2029                 || cs instanceof Blosum62ColourScheme)
2030         {
2031           sg.cs.setThreshold(threshold, viewport.getIgnoreGapsConsensus());
2032           sg.cs.setConsensus(AAFrequency.calculate(sg
2033                   .getSequences(viewport.hiddenRepSequences), 0, sg
2034                   .getWidth()));
2035         }
2036         else
2037         {
2038           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2039         }
2040
2041         if (viewport.getConservationSelected())
2042         {
2043           Conservation c = new Conservation("Group",
2044                   ResidueProperties.propHash, 3, sg
2045                           .getSequences(viewport.hiddenRepSequences), 0,
2046                   viewport.alignment.getWidth() - 1);
2047           c.calculate();
2048           c.verdict(false, viewport.ConsPercGaps);
2049           sg.cs.setConservation(c);
2050         }
2051         else
2052         {
2053           sg.cs.setConservation(null);
2054           sg.cs.setThreshold(0, viewport.getIgnoreGapsConsensus());
2055         }
2056
2057       }
2058     }
2059
2060     if (alignPanel.getOverviewPanel() != null)
2061     {
2062       alignPanel.getOverviewPanel().updateOverviewImage();
2063     }
2064
2065     jalview.structure.StructureSelectionManager
2066             .getStructureSelectionManager().sequenceColoursChanged(
2067                     alignPanel);
2068
2069     alignPanel.paintAlignment(true);
2070   }
2071
2072   protected void modifyPID_actionPerformed()
2073   {
2074     if (viewport.getAbovePIDThreshold()
2075             && viewport.globalColourScheme != null)
2076     {
2077       SliderPanel.setPIDSliderSource(alignPanel, viewport
2078               .getGlobalColourScheme(), "Background");
2079       SliderPanel.showPIDSlider();
2080     }
2081   }
2082
2083   protected void modifyConservation_actionPerformed()
2084   {
2085     if (viewport.getConservationSelected()
2086             && viewport.globalColourScheme != null)
2087     {
2088       SliderPanel.setConservationSlider(alignPanel,
2089               viewport.globalColourScheme, "Background");
2090       SliderPanel.showConservationSlider();
2091     }
2092   }
2093
2094   protected void conservationMenuItem_actionPerformed()
2095   {
2096     viewport.setConservationSelected(conservationMenuItem.getState());
2097
2098     viewport.setAbovePIDThreshold(false);
2099     abovePIDThreshold.setState(false);
2100
2101     changeColour(viewport.getGlobalColourScheme());
2102
2103     modifyConservation_actionPerformed();
2104   }
2105
2106   public void abovePIDThreshold_actionPerformed()
2107   {
2108     viewport.setAbovePIDThreshold(abovePIDThreshold.getState());
2109
2110     conservationMenuItem.setState(false);
2111     viewport.setConservationSelected(false);
2112
2113     changeColour(viewport.getGlobalColourScheme());
2114
2115     modifyPID_actionPerformed();
2116   }
2117
2118   public void sortPairwiseMenuItem_actionPerformed()
2119   {
2120     SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
2121     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport
2122             .getAlignment().getSequenceAt(0), null);
2123     addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
2124             viewport.alignment));
2125     alignPanel.paintAlignment(true);
2126   }
2127
2128   public void sortIDMenuItem_actionPerformed()
2129   {
2130     // addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,
2131     // HistoryItem.SORT));
2132     AlignmentSorter.sortByID(viewport.getAlignment());
2133     alignPanel.paintAlignment(true);
2134   }
2135
2136   public void sortGroupMenuItem_actionPerformed()
2137   {
2138     // addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,
2139     // HistoryItem.SORT));
2140     AlignmentSorter.sortByGroup(viewport.getAlignment());
2141     alignPanel.paintAlignment(true);
2142
2143   }
2144
2145   public void removeRedundancyMenuItem_actionPerformed()
2146   {
2147     new RedundancyPanel(alignPanel);
2148   }
2149
2150   public void pairwiseAlignmentMenuItem_actionPerformed()
2151   {
2152     if (viewport.getSelectionGroup() != null
2153             && viewport.getSelectionGroup().getSize() > 1)
2154     {
2155       Frame frame = new Frame();
2156       frame.add(new PairwiseAlignPanel(alignPanel));
2157       jalview.bin.JalviewLite.addFrame(frame, "Pairwise Alignment", 600,
2158               500);
2159     }
2160   }
2161
2162   public void PCAMenuItem_actionPerformed()
2163   {
2164     // are the sequences aligned?
2165     if (!viewport.alignment.isAligned())
2166     {
2167       SequenceI current;
2168       int Width = viewport.getAlignment().getWidth();
2169
2170       for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2171       {
2172         current = viewport.getAlignment().getSequenceAt(i);
2173
2174         if (current.getLength() < Width)
2175         {
2176           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2177         }
2178       }
2179       alignPanel.paintAlignment(true);
2180     }
2181
2182     if ((viewport.getSelectionGroup() != null
2183             && viewport.getSelectionGroup().getSize() < 4 && viewport
2184             .getSelectionGroup().getSize() > 0)
2185             || viewport.getAlignment().getHeight() < 4)
2186     {
2187       return;
2188     }
2189
2190     try
2191     {
2192       new PCAPanel(viewport);
2193     } catch (java.lang.OutOfMemoryError ex)
2194     {
2195     }
2196
2197   }
2198
2199   public void averageDistanceTreeMenuItem_actionPerformed()
2200   {
2201     NewTreePanel("AV", "PID", "Average distance tree using PID");
2202   }
2203
2204   public void neighbourTreeMenuItem_actionPerformed()
2205   {
2206     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");
2207   }
2208
2209   protected void njTreeBlosumMenuItem_actionPerformed()
2210   {
2211     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");
2212   }
2213
2214   protected void avTreeBlosumMenuItem_actionPerformed()
2215   {
2216     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");
2217   }
2218
2219   void NewTreePanel(String type, String pwType, String title)
2220   {
2221     // are the sequences aligned?
2222     if (!viewport.alignment.isAligned())
2223     {
2224       SequenceI current;
2225       int Width = viewport.getAlignment().getWidth();
2226
2227       for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
2228       {
2229         current = viewport.getAlignment().getSequenceAt(i);
2230
2231         if (current.getLength() < Width)
2232         {
2233           current.insertCharAt(Width - 1, viewport.getGapCharacter());
2234         }
2235       }
2236       alignPanel.paintAlignment(true);
2237
2238     }
2239
2240     if ((viewport.getSelectionGroup() != null && viewport
2241             .getSelectionGroup().getSize() > 1)
2242             || (viewport.getSelectionGroup() == null && viewport.alignment
2243                     .getHeight() > 1))
2244     {
2245       final TreePanel tp = new TreePanel(viewport, type, pwType);
2246
2247       addTreeMenuItem(tp, title);
2248
2249       jalview.bin.JalviewLite.addFrame(tp, title, 600, 500);
2250     }
2251   }
2252
2253   void loadTree_actionPerformed()
2254   {
2255     CutAndPasteTransfer cap = new CutAndPasteTransfer(true, this);
2256     cap.setText("Paste your Newick tree file here.");
2257     cap.setTreeImport();
2258     Frame frame = new Frame();
2259     frame.add(cap);
2260     jalview.bin.JalviewLite.addFrame(frame, "Paste Newick file ", 400, 300);
2261   }
2262
2263   public void loadTree(jalview.io.NewickFile tree, String treeFile)
2264   {
2265     TreePanel tp = new TreePanel(viewport, treeFile, "From File - ", tree);
2266     jalview.bin.JalviewLite.addFrame(tp, treeFile, 600, 500);
2267     addTreeMenuItem(tp, treeFile);
2268   }
2269
2270   void addTreeMenuItem(final TreePanel treePanel, String title)
2271   {
2272     final MenuItem item = new MenuItem(title);
2273     sortByTreeMenu.add(item);
2274     item.addActionListener(new java.awt.event.ActionListener()
2275     {
2276       public void actionPerformed(ActionEvent evt)
2277       {
2278         // addHistoryItem(new HistoryItem("Sort", viewport.alignment,
2279         // HistoryItem.SORT));
2280         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel
2281                 .getTree());
2282         alignPanel.paintAlignment(true);
2283       }
2284     });
2285
2286     treePanel.addWindowListener(new WindowAdapter()
2287     {
2288       public void windowClosing(WindowEvent e)
2289       {
2290         sortByTreeMenu.remove(item);
2291       };
2292     });
2293   }
2294
2295   protected void documentation_actionPerformed()
2296   {
2297     showURL("http://www.jalview.org/help.html", "HELP");
2298   }
2299
2300   protected void about_actionPerformed()
2301   {
2302
2303     class AboutPanel extends Canvas
2304     {
2305       String version;
2306
2307       public AboutPanel(String version)
2308       {
2309         this.version = version;
2310       }
2311
2312       public void paint(Graphics g)
2313       {
2314         g.setColor(Color.white);
2315         g.fillRect(0, 0, getSize().width, getSize().height);
2316         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2317         FontMetrics fm = g.getFontMetrics();
2318         int fh = fm.getHeight();
2319         int y = 5, x = 7;
2320         g.setColor(Color.black);
2321         // TODO: update this text for each release or centrally store it for
2322         // lite and application
2323         g.setFont(new Font("Helvetica", Font.BOLD, 14));
2324         g.drawString("JalviewLite - Release " + version, x, y += fh);
2325         g.setFont(new Font("Helvetica", Font.PLAIN, 12));
2326         g
2327                 .drawString(
2328                         "Authors:  Andrew Waterhouse, Jim Procter, Michele Clamp, James Cuff, Steve Searle,",
2329                         x, y += fh * 1.5);
2330         g.drawString("David Martin & Geoff Barton.", x + 50, y += fh);
2331         g
2332                 .drawString(
2333                         "Development managed by The Barton Group, University of Dundee, Scotland, UK.",
2334                         x, y += fh);
2335         g
2336                 .drawString(
2337                         "For help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list",
2338                         x, y += fh);
2339         g.drawString("If  you use Jalview, please cite:", x, y += fh + 8);
2340         g
2341                 .drawString(
2342                         "\"Clamp, M., Cuff, J., Searle, S. M. and Barton, G. J. (2004), The Jalview Java Alignment Editor\"",
2343                         x, y += fh);
2344         g.drawString("Bioinformatics,  2004 20;426-7.", x, y += fh);
2345       }
2346     }
2347
2348     String version = "test";
2349     java.net.URL url = getClass().getResource("/.build_properties");
2350     if (url != null)
2351     {
2352       try
2353       {
2354         BufferedReader reader = new BufferedReader(new InputStreamReader(
2355                 url.openStream()));
2356         String line;
2357         while ((line = reader.readLine()) != null)
2358         {
2359           if (line.indexOf("VERSION") > -1)
2360           {
2361             version = line.substring(line.indexOf("=") + 1);
2362           }
2363         }
2364       } catch (Exception ex)
2365       {
2366         ex.printStackTrace();
2367       }
2368     }
2369
2370     Frame frame = new Frame();
2371     frame.add(new AboutPanel(version));
2372     jalview.bin.JalviewLite.addFrame(frame, "Jalview", 580, 220);
2373
2374   }
2375
2376   public void showURL(String url, String target)
2377   {
2378     if (viewport.applet == null)
2379     {
2380       System.out.println("Not running as applet - no browser available.");
2381     }
2382     else
2383     {
2384       try
2385       {
2386         if (url.indexOf(":")==-1)
2387         {
2388           // TODO: verify (Bas Vroling bug) prepend codebase or server URL to form valid URL
2389           if (url.indexOf("/")==0)
2390           {
2391             String codebase = viewport.applet.getCodeBase().toString();
2392             url = codebase.substring(0,codebase.length()-viewport.applet.getCodeBase().getFile().length())+url;
2393           } else {
2394             url = viewport.applet.getCodeBase()+url;
2395           }
2396           System.out.println("Show url (prepended codebase): " + url);
2397         } else {
2398           System.out.println("Show url: " + url);
2399         }
2400         viewport.applet.getAppletContext().showDocument(
2401                 new java.net.URL(url), target);
2402       } catch (Exception ex)
2403       {
2404         ex.printStackTrace();
2405       }
2406     }
2407   }
2408
2409   // ////////////////////////////////////////////////////////////////////////////////
2410   // JBuilder Graphics here
2411
2412   MenuBar alignFrameMenuBar = new MenuBar();
2413
2414   Menu fileMenu = new Menu("File");
2415
2416   MenuItem loadApplication = new MenuItem("View in Full Application");
2417
2418   MenuItem loadTree = new MenuItem("Load Associated Tree ...");
2419
2420   MenuItem loadAnnotations = new MenuItem("Load Features/Annotations ...");
2421
2422   MenuItem outputFeatures = new MenuItem("Export Features ...");
2423
2424   MenuItem outputAnnotations = new MenuItem("Export Annotations ...");
2425
2426   MenuItem closeMenuItem = new MenuItem("Close");
2427
2428   Menu editMenu = new Menu("Edit");
2429
2430   Menu viewMenu = new Menu("View");
2431
2432   Menu colourMenu = new Menu("Colour");
2433
2434   Menu calculateMenu = new Menu("Calculate");
2435
2436   MenuItem selectAllSequenceMenuItem = new MenuItem("Select all");
2437
2438   MenuItem deselectAllSequenceMenuItem = new MenuItem("Deselect All");
2439
2440   MenuItem invertSequenceMenuItem = new MenuItem("Invert Selection");
2441
2442   MenuItem remove2LeftMenuItem = new MenuItem();
2443
2444   MenuItem remove2RightMenuItem = new MenuItem();
2445
2446   MenuItem removeGappedColumnMenuItem = new MenuItem();
2447
2448   MenuItem removeAllGapsMenuItem = new MenuItem();
2449
2450   CheckboxMenuItem viewBoxesMenuItem = new CheckboxMenuItem();
2451
2452   CheckboxMenuItem viewTextMenuItem = new CheckboxMenuItem();
2453
2454   MenuItem sortPairwiseMenuItem = new MenuItem();
2455
2456   MenuItem sortIDMenuItem = new MenuItem();
2457
2458   MenuItem sortGroupMenuItem = new MenuItem();
2459
2460   MenuItem removeRedundancyMenuItem = new MenuItem();
2461
2462   MenuItem pairwiseAlignmentMenuItem = new MenuItem();
2463
2464   MenuItem PCAMenuItem = new MenuItem();
2465
2466   MenuItem averageDistanceTreeMenuItem = new MenuItem();
2467
2468   MenuItem neighbourTreeMenuItem = new MenuItem();
2469
2470   BorderLayout borderLayout1 = new BorderLayout();
2471
2472   public Label statusBar = new Label();
2473
2474   Menu outputTextboxMenu = new Menu();
2475
2476   MenuItem clustalColour = new MenuItem();
2477
2478   MenuItem zappoColour = new MenuItem();
2479
2480   MenuItem taylorColour = new MenuItem();
2481
2482   MenuItem hydrophobicityColour = new MenuItem();
2483
2484   MenuItem helixColour = new MenuItem();
2485
2486   MenuItem strandColour = new MenuItem();
2487
2488   MenuItem turnColour = new MenuItem();
2489
2490   MenuItem buriedColour = new MenuItem();
2491
2492   MenuItem userDefinedColour = new MenuItem();
2493
2494   MenuItem PIDColour = new MenuItem();
2495
2496   MenuItem BLOSUM62Colour = new MenuItem();
2497
2498   MenuItem njTreeBlosumMenuItem = new MenuItem();
2499
2500   MenuItem avDistanceTreeBlosumMenuItem = new MenuItem();
2501
2502   CheckboxMenuItem annotationPanelMenuItem = new CheckboxMenuItem();
2503
2504   CheckboxMenuItem colourTextMenuItem = new CheckboxMenuItem();
2505
2506   MenuItem alProperties = new MenuItem("Alignment Properties...");
2507
2508   MenuItem overviewMenuItem = new MenuItem();
2509
2510   MenuItem undoMenuItem = new MenuItem();
2511
2512   MenuItem redoMenuItem = new MenuItem();
2513
2514   CheckboxMenuItem conservationMenuItem = new CheckboxMenuItem();
2515
2516   MenuItem noColourmenuItem = new MenuItem();
2517
2518   CheckboxMenuItem wrapMenuItem = new CheckboxMenuItem();
2519
2520   CheckboxMenuItem renderGapsMenuItem = new CheckboxMenuItem();
2521
2522   MenuItem findMenuItem = new MenuItem();
2523
2524   CheckboxMenuItem abovePIDThreshold = new CheckboxMenuItem();
2525
2526   MenuItem nucleotideColour = new MenuItem();
2527
2528   MenuItem deleteGroups = new MenuItem();
2529
2530   MenuItem delete = new MenuItem();
2531
2532   MenuItem copy = new MenuItem();
2533
2534   MenuItem cut = new MenuItem();
2535
2536   Menu pasteMenu = new Menu();
2537
2538   MenuItem pasteNew = new MenuItem();
2539
2540   MenuItem pasteThis = new MenuItem();
2541
2542   CheckboxMenuItem applyToAllGroups = new CheckboxMenuItem();
2543
2544   MenuItem font = new MenuItem();
2545
2546   CheckboxMenuItem scaleAbove = new CheckboxMenuItem();
2547
2548   CheckboxMenuItem scaleLeft = new CheckboxMenuItem();
2549
2550   CheckboxMenuItem scaleRight = new CheckboxMenuItem();
2551
2552   MenuItem modifyPID = new MenuItem();
2553
2554   MenuItem modifyConservation = new MenuItem();
2555
2556   CheckboxMenuItem autoCalculate = new CheckboxMenuItem(
2557           "Autocalculate Consensus", true);
2558
2559   Menu sortByTreeMenu = new Menu();
2560
2561   Menu sort = new Menu();
2562
2563   Menu calculate = new Menu();
2564
2565   MenuItem inputText = new MenuItem();
2566
2567   Menu helpMenu = new Menu();
2568
2569   MenuItem documentation = new MenuItem();
2570
2571   MenuItem about = new MenuItem();
2572
2573   CheckboxMenuItem seqLimits = new CheckboxMenuItem();
2574
2575   CheckboxMenuItem centreColumnLabelFlag = new CheckboxMenuItem();
2576
2577   CheckboxMenuItem followMouseOverFlag = new CheckboxMenuItem();
2578
2579   private void jbInit() throws Exception
2580   {
2581
2582     setMenuBar(alignFrameMenuBar);
2583
2584     MenuItem item;
2585
2586     // dynamically fill save as menu with available formats
2587     for (int i = 0; i < jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS.length; i++)
2588     {
2589
2590       item = new MenuItem(
2591               jalview.io.AppletFormatAdapter.WRITEABLE_FORMATS[i]);
2592
2593       item.addActionListener(new java.awt.event.ActionListener()
2594       {
2595         public void actionPerformed(ActionEvent e)
2596         {
2597           outputText_actionPerformed(e);
2598         }
2599       });
2600
2601       outputTextboxMenu.add(item);
2602     }
2603     closeMenuItem.addActionListener(this);
2604     loadApplication.addActionListener(this);
2605
2606     loadTree.addActionListener(this);
2607     loadAnnotations.addActionListener(this);
2608     outputFeatures.addActionListener(this);
2609     outputAnnotations.addActionListener(this);
2610     selectAllSequenceMenuItem.addActionListener(this);
2611     deselectAllSequenceMenuItem.addActionListener(this);
2612     invertSequenceMenuItem.addActionListener(this);
2613     remove2LeftMenuItem.setLabel("Remove Left");
2614     remove2LeftMenuItem.addActionListener(this);
2615     remove2RightMenuItem.setLabel("Remove Right");
2616     remove2RightMenuItem.addActionListener(this);
2617     removeGappedColumnMenuItem.setLabel("Remove Empty Columns");
2618     removeGappedColumnMenuItem.addActionListener(this);
2619     removeAllGapsMenuItem.setLabel("Remove All Gaps");
2620     removeAllGapsMenuItem.addActionListener(this);
2621     viewBoxesMenuItem.setLabel("Boxes");
2622     viewBoxesMenuItem.setState(true);
2623     viewBoxesMenuItem.addItemListener(this);
2624     viewTextMenuItem.setLabel("Text");
2625     viewTextMenuItem.setState(true);
2626     viewTextMenuItem.addItemListener(this);
2627     sortPairwiseMenuItem.setLabel("by Pairwise Identity");
2628     sortPairwiseMenuItem.addActionListener(this);
2629     sortIDMenuItem.setLabel("by ID");
2630     sortIDMenuItem.addActionListener(this);
2631     sortGroupMenuItem.setLabel("by Group");
2632     sortGroupMenuItem.addActionListener(this);
2633     removeRedundancyMenuItem.setLabel("Remove Redundancy...");
2634     removeRedundancyMenuItem.addActionListener(this);
2635     pairwiseAlignmentMenuItem.setLabel("Pairwise Alignments...");
2636     pairwiseAlignmentMenuItem.addActionListener(this);
2637     PCAMenuItem.setLabel("Principal Component Analysis");
2638     PCAMenuItem.addActionListener(this);
2639     averageDistanceTreeMenuItem
2640             .setLabel("Average Distance Using % Identity");
2641     averageDistanceTreeMenuItem.addActionListener(this);
2642     neighbourTreeMenuItem.setLabel("Neighbour Joining Using % Identity");
2643     neighbourTreeMenuItem.addActionListener(this);
2644     statusBar.setBackground(Color.white);
2645     statusBar.setFont(new java.awt.Font("Verdana", 0, 11));
2646     statusBar.setText("Status bar");
2647     outputTextboxMenu.setLabel("Output to Textbox");
2648     clustalColour.setLabel("Clustalx");
2649
2650     clustalColour.addActionListener(this);
2651     zappoColour.setLabel("Zappo");
2652     zappoColour.addActionListener(this);
2653     taylorColour.setLabel("Taylor");
2654     taylorColour.addActionListener(this);
2655     hydrophobicityColour.setLabel("Hydrophobicity");
2656     hydrophobicityColour.addActionListener(this);
2657     helixColour.setLabel("Helix Propensity");
2658     helixColour.addActionListener(this);
2659     strandColour.setLabel("Strand Propensity");
2660     strandColour.addActionListener(this);
2661     turnColour.setLabel("Turn Propensity");
2662     turnColour.addActionListener(this);
2663     buriedColour.setLabel("Buried Index");
2664     buriedColour.addActionListener(this);
2665     userDefinedColour.setLabel("User Defined...");
2666     userDefinedColour.addActionListener(this);
2667     PIDColour.setLabel("Percentage Identity");
2668     PIDColour.addActionListener(this);
2669     BLOSUM62Colour.setLabel("BLOSUM62 Score");
2670     BLOSUM62Colour.addActionListener(this);
2671     avDistanceTreeBlosumMenuItem
2672             .setLabel("Average Distance Using BLOSUM62");
2673     avDistanceTreeBlosumMenuItem.addActionListener(this);
2674     njTreeBlosumMenuItem.setLabel("Neighbour Joining Using BLOSUM62");
2675     njTreeBlosumMenuItem.addActionListener(this);
2676     annotationPanelMenuItem.setLabel("Show Annotations");
2677     annotationPanelMenuItem.addItemListener(this);
2678     colourTextMenuItem.setLabel("Colour Text");
2679     colourTextMenuItem.addItemListener(this);
2680     alProperties.addActionListener(this);
2681     overviewMenuItem.setLabel("Overview Window");
2682     overviewMenuItem.addActionListener(this);
2683     undoMenuItem.setEnabled(false);
2684     undoMenuItem.setLabel("Undo");
2685     undoMenuItem.addActionListener(this);
2686     redoMenuItem.setEnabled(false);
2687     redoMenuItem.setLabel("Redo");
2688     redoMenuItem.addActionListener(this);
2689     conservationMenuItem.setLabel("by Conservation");
2690     conservationMenuItem.addItemListener(this);
2691     noColourmenuItem.setLabel("None");
2692     noColourmenuItem.addActionListener(this);
2693     wrapMenuItem.setLabel("Wrap");
2694     wrapMenuItem.addItemListener(this);
2695     renderGapsMenuItem.setLabel("Show Gaps");
2696     renderGapsMenuItem.setState(true);
2697     renderGapsMenuItem.addItemListener(this);
2698     findMenuItem.setLabel("Find...");
2699     findMenuItem.addActionListener(this);
2700     abovePIDThreshold.setLabel("Above Identity Threshold");
2701     abovePIDThreshold.addItemListener(this);
2702     nucleotideColour.setLabel("Nucleotide");
2703     nucleotideColour.addActionListener(this);
2704     deleteGroups.setLabel("Undefine Groups");
2705     deleteGroups.addActionListener(this);
2706     copy.setLabel("Copy");
2707     copy.addActionListener(this);
2708     cut.setLabel("Cut");
2709     cut.addActionListener(this);
2710     delete.setLabel("Delete");
2711     delete.addActionListener(this);
2712     pasteMenu.setLabel("Paste");
2713     pasteNew.setLabel("To New Alignment");
2714     pasteNew.addActionListener(this);
2715     pasteThis.setLabel("Add To This Alignment");
2716     pasteThis.addActionListener(this);
2717     applyToAllGroups.setLabel("Apply Colour To All Groups");
2718     applyToAllGroups.setState(true);
2719     applyToAllGroups.addItemListener(this);
2720     font.setLabel("Font...");
2721     font.addActionListener(this);
2722     scaleAbove.setLabel("Scale Above");
2723     scaleAbove.setState(true);
2724     scaleAbove.setEnabled(false);
2725     scaleAbove.addItemListener(this);
2726     scaleLeft.setEnabled(false);
2727     scaleLeft.setState(true);
2728     scaleLeft.setLabel("Scale Left");
2729     scaleLeft.addItemListener(this);
2730     scaleRight.setEnabled(false);
2731     scaleRight.setState(true);
2732     scaleRight.setLabel("Scale Right");
2733     scaleRight.addItemListener(this);
2734     modifyPID.setLabel("Modify Identity Threshold...");
2735     modifyPID.addActionListener(this);
2736     modifyConservation.setLabel("Modify Conservation Threshold...");
2737     modifyConservation.addActionListener(this);
2738     sortByTreeMenu.setLabel("By Tree Order");
2739     sort.setLabel("Sort");
2740     calculate.setLabel("Calculate Tree");
2741     autoCalculate.addItemListener(this);
2742     inputText.setLabel("Input from textbox");
2743     inputText.addActionListener(this);
2744     centreColumnLabelFlag.setLabel("Centre column labels");
2745     centreColumnLabelFlag.addItemListener(this);
2746     followMouseOverFlag.setLabel("Automatic Scrolling");
2747     followMouseOverFlag.addItemListener(this);
2748     helpMenu.setLabel("Help");
2749     documentation.setLabel("Documentation");
2750     documentation.addActionListener(this);
2751
2752     about.setLabel("About...");
2753     about.addActionListener(this);
2754     seqLimits.setState(true);
2755     seqLimits.setLabel("Show Sequence Limits");
2756     seqLimits.addItemListener(this);
2757     featureSettings.setLabel("Feature Settings...");
2758     featureSettings.addActionListener(this);
2759     sequenceFeatures.setLabel("Sequence Features");
2760     sequenceFeatures.addItemListener(this);
2761     sequenceFeatures.setState(false);
2762     annotationColour.setLabel("by Annotation...");
2763     annotationColour.addActionListener(this);
2764     invertSequenceMenuItem.setLabel("Invert Sequence Selection");
2765     invertColSel.setLabel("Invert Column Selection");
2766     menu1.setLabel("Show");
2767     showColumns.setLabel("All Columns ");
2768     showSeqs.setLabel("All Sequences");
2769     menu2.setLabel("Hide");
2770     hideColumns.setLabel("Selected Columns");
2771     hideSequences.setLabel("Selected Sequences");
2772     invertColSel.addActionListener(this);
2773     showColumns.addActionListener(this);
2774     showSeqs.addActionListener(this);
2775     hideColumns.addActionListener(this);
2776     hideSequences.addActionListener(this);
2777     formatMenu.setLabel("Format");
2778     selectMenu.setLabel("Select");
2779     newView.setLabel("New View");
2780     newView.addActionListener(this);
2781     alignFrameMenuBar.add(fileMenu);
2782     alignFrameMenuBar.add(editMenu);
2783     alignFrameMenuBar.add(selectMenu);
2784     alignFrameMenuBar.add(viewMenu);
2785     alignFrameMenuBar.add(formatMenu);
2786     alignFrameMenuBar.add(colourMenu);
2787     alignFrameMenuBar.add(calculateMenu);
2788     alignFrameMenuBar.add(helpMenu);
2789
2790     fileMenu.add(inputText);
2791     fileMenu.add(loadTree);
2792     fileMenu.add(loadAnnotations);
2793
2794     fileMenu.addSeparator();
2795     fileMenu.add(outputTextboxMenu);
2796     fileMenu.add(outputFeatures);
2797     fileMenu.add(outputAnnotations);
2798
2799     if (jalviewServletURL != null)
2800     {
2801       fileMenu.add(loadApplication);
2802     }
2803
2804     fileMenu.addSeparator();
2805     fileMenu.add(closeMenuItem);
2806
2807     editMenu.add(undoMenuItem);
2808     editMenu.add(redoMenuItem);
2809     editMenu.add(cut);
2810     editMenu.add(copy);
2811     editMenu.add(pasteMenu);
2812     editMenu.add(delete);
2813     editMenu.addSeparator();
2814     editMenu.add(remove2LeftMenuItem);
2815     editMenu.add(remove2RightMenuItem);
2816     editMenu.add(removeGappedColumnMenuItem);
2817     editMenu.add(removeAllGapsMenuItem);
2818     editMenu.add(removeRedundancyMenuItem);
2819     viewMenu.add(newView);
2820     viewMenu.addSeparator();
2821     viewMenu.add(menu1);
2822     viewMenu.add(menu2);
2823     viewMenu.addSeparator();
2824     viewMenu.add(followMouseOverFlag);
2825     viewMenu.add(annotationPanelMenuItem);
2826     viewMenu.addSeparator();
2827     viewMenu.add(sequenceFeatures);
2828     viewMenu.add(featureSettings);
2829     viewMenu.addSeparator();
2830     viewMenu.add(alProperties);
2831     viewMenu.addSeparator();
2832     viewMenu.add(overviewMenuItem);
2833     colourMenu.add(applyToAllGroups);
2834     colourMenu.addSeparator();
2835     colourMenu.add(noColourmenuItem);
2836     colourMenu.add(clustalColour);
2837     colourMenu.add(BLOSUM62Colour);
2838     colourMenu.add(PIDColour);
2839     colourMenu.add(zappoColour);
2840     colourMenu.add(taylorColour);
2841     colourMenu.add(hydrophobicityColour);
2842     colourMenu.add(helixColour);
2843     colourMenu.add(strandColour);
2844     colourMenu.add(turnColour);
2845     colourMenu.add(buriedColour);
2846     colourMenu.add(nucleotideColour);
2847     colourMenu.add(userDefinedColour);
2848     colourMenu.addSeparator();
2849     colourMenu.add(conservationMenuItem);
2850     colourMenu.add(modifyConservation);
2851     colourMenu.add(abovePIDThreshold);
2852     colourMenu.add(modifyPID);
2853     colourMenu.add(annotationColour);
2854     calculateMenu.add(sort);
2855     calculateMenu.add(calculate);
2856     calculateMenu.addSeparator();
2857     calculateMenu.add(pairwiseAlignmentMenuItem);
2858     calculateMenu.add(PCAMenuItem);
2859     calculateMenu.add(autoCalculate);
2860     this.add(statusBar, BorderLayout.SOUTH);
2861     pasteMenu.add(pasteNew);
2862     pasteMenu.add(pasteThis);
2863     sort.add(sortIDMenuItem);
2864     sort.add(sortByTreeMenu);
2865     sort.add(sortGroupMenuItem);
2866     sort.add(sortPairwiseMenuItem);
2867     calculate.add(averageDistanceTreeMenuItem);
2868     calculate.add(neighbourTreeMenuItem);
2869     calculate.add(avDistanceTreeBlosumMenuItem);
2870     calculate.add(njTreeBlosumMenuItem);
2871     helpMenu.add(documentation);
2872     helpMenu.add(about);
2873     menu1.add(showColumns);
2874     menu1.add(showSeqs);
2875     menu2.add(hideColumns);
2876     menu2.add(hideSequences);
2877     formatMenu.add(font);
2878     formatMenu.add(seqLimits);
2879     formatMenu.add(wrapMenuItem);
2880     formatMenu.add(scaleAbove);
2881     formatMenu.add(scaleLeft);
2882     formatMenu.add(scaleRight);
2883     formatMenu.add(viewBoxesMenuItem);
2884     formatMenu.add(viewTextMenuItem);
2885     formatMenu.add(colourTextMenuItem);
2886     formatMenu.add(renderGapsMenuItem);
2887     formatMenu.add(centreColumnLabelFlag);
2888     selectMenu.add(findMenuItem);
2889     selectMenu.addSeparator();
2890     selectMenu.add(selectAllSequenceMenuItem);
2891     selectMenu.add(deselectAllSequenceMenuItem);
2892     selectMenu.add(invertSequenceMenuItem);
2893     selectMenu.add(invertColSel);
2894     selectMenu.add(deleteGroups);
2895   }
2896
2897   MenuItem featureSettings = new MenuItem();
2898
2899   CheckboxMenuItem sequenceFeatures = new CheckboxMenuItem();
2900
2901   MenuItem annotationColour = new MenuItem();
2902
2903   MenuItem invertColSel = new MenuItem();
2904
2905   Menu menu1 = new Menu();
2906
2907   MenuItem showColumns = new MenuItem();
2908
2909   MenuItem showSeqs = new MenuItem();
2910
2911   Menu menu2 = new Menu();
2912
2913   MenuItem hideColumns = new MenuItem();
2914
2915   MenuItem hideSequences = new MenuItem();
2916
2917   Menu formatMenu = new Menu();
2918
2919   Menu selectMenu = new Menu();
2920
2921   MenuItem newView = new MenuItem();
2922
2923   /**
2924    * Attach the alignFrame panels after embedding menus, if necessary. This used
2925    * to be called setEmbedded, but is now creates the dropdown menus in a
2926    * platform independent manner to avoid OSX/Mac menu appendage daftness.
2927    * 
2928    * @param reallyEmbedded
2929    *                true to attach the view to the applet area on the page
2930    *                rather than in a new window
2931    */
2932   public void createAlignFrameWindow(boolean reallyEmbedded, String title)
2933   {
2934     if (reallyEmbedded)
2935     {
2936       // ////
2937       // Explicly build the embedded menu panel for the on-page applet
2938       //
2939       // view cannot be closed if its actually on the page
2940       fileMenu.remove(closeMenuItem);
2941       fileMenu.remove(3); // Remove Seperator
2942       embeddedMenu = makeEmbeddedPopupMenu(alignFrameMenuBar, "Arial",
2943               Font.PLAIN, 10, false); // use our own fonts.
2944       // and actually add the components to the applet area
2945       viewport.applet.setLayout(new BorderLayout());
2946       viewport.applet.add(embeddedMenu, BorderLayout.NORTH);
2947       viewport.applet.add(statusBar, BorderLayout.SOUTH);
2948       alignPanel.setSize(viewport.applet.getSize().width, viewport.applet
2949               .getSize().height
2950               - embeddedMenu.HEIGHT - statusBar.HEIGHT);
2951       viewport.applet.add(alignPanel, BorderLayout.CENTER);
2952       viewport.applet.validate();
2953     }
2954     else
2955     {
2956       // //////
2957       // test and embed menu bar if necessary.
2958       //
2959       if (embedMenuIfNeeded(alignPanel))
2960       {
2961         // adjust for status bar height too
2962         alignPanel.setSize(getSize().width, getSize().height
2963                 - statusBar.HEIGHT);
2964       }
2965       add(statusBar, BorderLayout.SOUTH);
2966       add(alignPanel, BorderLayout.CENTER);
2967       // and register with the applet so it can pass external API calls to us
2968       jalview.bin.JalviewLite.addFrame(this, title, DEFAULT_WIDTH,
2969               DEFAULT_HEIGHT);
2970     }
2971   }
2972 }