PaintRefresher must be sent alignment
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import java.beans.*;\r
22 import java.util.*;\r
23 \r
24 import java.awt.*;\r
25 import java.awt.datatransfer.*;\r
26 import java.awt.event.*;\r
27 import java.awt.print.*;\r
28 import javax.swing.*;\r
29 import javax.swing.event.*;\r
30 \r
31 import jalview.analysis.*;\r
32 import jalview.datamodel.*;\r
33 import jalview.io.*;\r
34 import jalview.jbgui.*;\r
35 import jalview.schemes.*;\r
36 import jalview.ws.*;\r
37 \r
38 public class AlignFrame\r
39     extends GAlignFrame\r
40 {\r
41   public static final int NEW_WINDOW_WIDTH = 700;\r
42   public static final int NEW_WINDOW_HEIGHT = 500;\r
43   final AlignmentPanel alignPanel;\r
44   final AlignViewport viewport;\r
45   public String currentFileFormat = "Jalview";\r
46   Stack historyList = new Stack();\r
47   Stack redoList = new Stack();\r
48   private int treeCount = 0;\r
49 \r
50   public AlignFrame(AlignmentI al)\r
51   {\r
52     viewport = new AlignViewport(al);\r
53 \r
54     alignPanel = new AlignmentPanel(this, viewport);\r
55     alignPanel.annotationPanel.adjustPanelHeight();\r
56     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.\r
57         annotationPanel.getPreferredSize());\r
58     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.\r
59         getPreferredSize());\r
60     alignPanel.setAnnotationVisible(viewport.getShowAnnotation());\r
61 \r
62     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
63 \r
64     addInternalFrameListener(new InternalFrameAdapter()\r
65     {\r
66       public void internalFrameActivated(InternalFrameEvent evt)\r
67       {\r
68         javax.swing.SwingUtilities.invokeLater(new Runnable()\r
69         {\r
70           public void run()\r
71           {\r
72             alignPanel.requestFocus();\r
73           }\r
74         });\r
75       }\r
76     });\r
77   }\r
78 \r
79   public void saveAlignmentMenu_actionPerformed(ActionEvent e)\r
80   {\r
81     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
82         getProperty(\r
83             "LAST_DIRECTORY"),\r
84         new String[]\r
85         {\r
86         "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc",\r
87         "jar"\r
88     },\r
89         new String[]\r
90         {\r
91         "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "Jalview"\r
92     }, currentFileFormat);\r
93 \r
94     chooser.setAcceptAllFileFilterUsed(false);\r
95     chooser.setFileView(new JalviewFileView());\r
96     chooser.setDialogTitle("Save Alignment to file");\r
97     chooser.setToolTipText("Save");\r
98 \r
99     int value = chooser.showSaveDialog(this);\r
100 \r
101     if (value == JalviewFileChooser.APPROVE_OPTION)\r
102     {\r
103       currentFileFormat = chooser.getSelectedFormat();\r
104       jalview.bin.Cache.setProperty("DEFAULT_FILE_FORMAT",\r
105                                     currentFileFormat);\r
106 \r
107       if (currentFileFormat.equals("Jalview"))\r
108       {\r
109         String shortName = title;\r
110 \r
111         if (shortName.indexOf(java.io.File.separatorChar) > -1)\r
112         {\r
113           shortName = shortName.substring(shortName.lastIndexOf(\r
114               java.io.File.separatorChar) + 1);\r
115         }\r
116 \r
117         String choice = chooser.getSelectedFile().getPath();\r
118         Jalview2XML.SaveAlignment(this, choice, shortName);\r
119 \r
120         // USE Jalview2XML to save this file\r
121         return;\r
122       }\r
123 \r
124       String choice = chooser.getSelectedFile().getPath();\r
125       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
126 \r
127       String output = FormatAdapter.formatSequences(currentFileFormat,\r
128           viewport.getAlignment().getSequences());\r
129 \r
130       try\r
131       {\r
132         java.io.PrintWriter out = new java.io.PrintWriter(new java.io.\r
133             FileWriter(\r
134                 choice));\r
135         out.println(output);\r
136         out.close();\r
137       }\r
138       catch (Exception ex)\r
139       {\r
140       }\r
141     }\r
142   }\r
143 \r
144   protected void outputText_actionPerformed(ActionEvent e)\r
145   {\r
146     CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
147     Desktop.addInternalFrame(cap,\r
148                              "Alignment output - " + e.getActionCommand(), 600,\r
149                              500);\r
150     cap.setText(FormatAdapter.formatSequences(e.getActionCommand(),\r
151                                               viewport.getAlignment().\r
152                                               getSequences()));\r
153   }\r
154 \r
155   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
156   {\r
157     new HTMLOutput(viewport);\r
158   }\r
159 \r
160   protected void createPNG_actionPerformed(ActionEvent e)\r
161   {\r
162     alignPanel.makePNG();\r
163   }\r
164 \r
165   protected void epsFile_actionPerformed(ActionEvent e)\r
166   {\r
167     alignPanel.makeEPS();\r
168   }\r
169 \r
170   public void printMenuItem_actionPerformed(ActionEvent e)\r
171   {\r
172     //Putting in a thread avoids Swing painting problems\r
173     PrintThread thread = new PrintThread();\r
174     thread.start();\r
175   }\r
176 \r
177   public void closeMenuItem_actionPerformed(ActionEvent e)\r
178   {\r
179     try\r
180     {\r
181       this.setClosed(true);\r
182     }\r
183     catch (Exception ex)\r
184     {\r
185     }\r
186   }\r
187 \r
188   void updateEditMenuBar()\r
189   {\r
190     if (historyList.size() > 0)\r
191     {\r
192       undoMenuItem.setEnabled(true);\r
193 \r
194       HistoryItem hi = (HistoryItem) historyList.peek();\r
195       undoMenuItem.setText("Undo " + hi.getDescription());\r
196     }\r
197     else\r
198     {\r
199       undoMenuItem.setEnabled(false);\r
200       undoMenuItem.setText("Undo");\r
201     }\r
202 \r
203     if (redoList.size() > 0)\r
204     {\r
205       redoMenuItem.setEnabled(true);\r
206 \r
207       HistoryItem hi = (HistoryItem) redoList.peek();\r
208       redoMenuItem.setText("Redo " + hi.getDescription());\r
209     }\r
210     else\r
211     {\r
212       redoMenuItem.setEnabled(false);\r
213       redoMenuItem.setText("Redo");\r
214     }\r
215   }\r
216 \r
217   public void addHistoryItem(HistoryItem hi)\r
218   {\r
219     historyList.push(hi);\r
220     updateEditMenuBar();\r
221   }\r
222 \r
223   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
224   {\r
225     HistoryItem hi = (HistoryItem) historyList.pop();\r
226     redoList.push(new HistoryItem(hi.getDescription(), viewport.alignment,\r
227                                   HistoryItem.HIDE));\r
228     restoreHistoryItem(hi);\r
229   }\r
230 \r
231   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
232   {\r
233     HistoryItem hi = (HistoryItem) redoList.pop();\r
234     restoreHistoryItem(hi);\r
235     updateEditMenuBar();\r
236     viewport.updateConsensus();\r
237     alignPanel.repaint();\r
238     alignPanel.repaint();\r
239   }\r
240 \r
241   // used by undo and redo\r
242   void restoreHistoryItem(HistoryItem hi)\r
243   {\r
244     if (hi.getType() == HistoryItem.SORT)\r
245     {\r
246       for (int i = 0; i < hi.getSequences().size(); i++)\r
247       {\r
248         viewport.alignment.getSequences().setElementAt(hi.getSequences()\r
249             .elementAt(i),\r
250             i);\r
251       }\r
252     }\r
253     else\r
254     {\r
255       for (int i = 0; i < hi.getSequences().size(); i++)\r
256       {\r
257         SequenceI restore = (SequenceI) hi.getSequences().elementAt(i);\r
258 \r
259         if (restore.getLength() == 0)\r
260         {\r
261           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
262           viewport.alignment.getSequences().insertElementAt(restore,\r
263               hi.getAlignIndex(i));\r
264         }\r
265         else\r
266         {\r
267           restore.setSequence(hi.getHidden().elementAt(i).toString());\r
268         }\r
269       }\r
270 \r
271       if (hi.getType() == HistoryItem.PASTE)\r
272       {\r
273         for (int i = viewport.alignment.getHeight() - 1;\r
274              i > (hi.getSequences().size() - 1); i--)\r
275         {\r
276           viewport.alignment.deleteSequence(i);\r
277         }\r
278       }\r
279     }\r
280 \r
281     updateEditMenuBar();\r
282 \r
283     viewport.updateConsensus();\r
284     viewport.updateConservation();\r
285     alignPanel.repaint();\r
286     viewport.firePropertyChange("alignment", null,\r
287                                 viewport.getAlignment().getSequences());\r
288   }\r
289 \r
290   public void moveSelectedSequences(boolean up)\r
291   {\r
292     SequenceGroup sg = viewport.getSelectionGroup();\r
293 \r
294     if (sg == null)\r
295     {\r
296       return;\r
297     }\r
298 \r
299     if (up)\r
300     {\r
301       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
302       {\r
303         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
304 \r
305         if (!sg.sequences.contains(seq))\r
306         {\r
307           continue;\r
308         }\r
309 \r
310         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
311 \r
312         if (sg.sequences.contains(temp))\r
313         {\r
314           continue;\r
315         }\r
316 \r
317         viewport.alignment.getSequences().setElementAt(temp, i);\r
318         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
319       }\r
320     }\r
321     else\r
322     {\r
323       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
324       {\r
325         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
326 \r
327         if (!sg.sequences.contains(seq))\r
328         {\r
329           continue;\r
330         }\r
331 \r
332         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
333 \r
334         if (sg.sequences.contains(temp))\r
335         {\r
336           continue;\r
337         }\r
338 \r
339         viewport.alignment.getSequences().setElementAt(temp, i);\r
340         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
341       }\r
342     }\r
343 \r
344     alignPanel.repaint();\r
345   }\r
346 \r
347   protected void copy_actionPerformed(ActionEvent e)\r
348   {\r
349     if (viewport.getSelectionGroup() == null)\r
350     {\r
351       return;\r
352     }\r
353 \r
354     SequenceGroup sg = viewport.getSelectionGroup();\r
355 \r
356     Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
357     StringBuffer buffer = new StringBuffer();\r
358 \r
359     Hashtable orderedSeqs = new Hashtable();\r
360 \r
361     for (int i = 0; i < sg.getSize(); i++)\r
362     {\r
363       SequenceI seq = sg.getSequenceAt(i);\r
364       int index = viewport.alignment.findIndex(seq);\r
365       orderedSeqs.put(index + "", seq);\r
366     }\r
367 \r
368     int index = 0;\r
369 \r
370     for (int i = 0; i < sg.getSize(); i++)\r
371     {\r
372       SequenceI seq = null;\r
373 \r
374       while (seq == null)\r
375       {\r
376         if (orderedSeqs.containsKey(index + ""))\r
377         {\r
378           seq = (SequenceI) orderedSeqs.get(index + "");\r
379           index++;\r
380 \r
381           break;\r
382         }\r
383         else\r
384         {\r
385           index++;\r
386         }\r
387       }\r
388 \r
389       buffer.append(seq.getName() + "\t" +\r
390                     seq.findPosition(sg.getStartRes()) + "\t" +\r
391                     seq.findPosition(sg.getEndRes()) + "\t" +\r
392                     sg.getSequenceAt(i).getSequence(sg.getStartRes(),\r
393           sg.getEndRes() + 1) + "\n");\r
394     }\r
395 \r
396     c.setContents(new StringSelection(buffer.toString()), null);\r
397   }\r
398 \r
399   protected void pasteNew_actionPerformed(ActionEvent e)\r
400   {\r
401     paste(true);\r
402   }\r
403 \r
404   protected void pasteThis_actionPerformed(ActionEvent e)\r
405   {\r
406     addHistoryItem(new HistoryItem("Paste Sequences", viewport.alignment,\r
407                                    HistoryItem.PASTE));\r
408     paste(false);\r
409   }\r
410 \r
411   void paste(boolean newAlignment)\r
412   {\r
413     try\r
414     {\r
415       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
416       Transferable contents = c.getContents(this);\r
417 \r
418       if (contents == null)\r
419       {\r
420         return;\r
421       }\r
422 \r
423       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
424       StringTokenizer st = new StringTokenizer(str);\r
425       ArrayList seqs = new ArrayList();\r
426 \r
427       while (st.hasMoreElements())\r
428       {\r
429         String name = st.nextToken();\r
430         int start = Integer.parseInt(st.nextToken());\r
431         int end = Integer.parseInt(st.nextToken());\r
432         Sequence sequence = new Sequence(name, st.nextToken(), start,\r
433                                          end);\r
434 \r
435         if (!newAlignment)\r
436         {\r
437           viewport.alignment.addSequence(sequence);\r
438         }\r
439         else\r
440         {\r
441           seqs.add(sequence);\r
442         }\r
443       }\r
444 \r
445       if (newAlignment)\r
446       {\r
447         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
448         seqs.toArray(newSeqs);\r
449 \r
450         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
451         String newtitle = new String("Copied sequences");\r
452 \r
453         if (title.startsWith("Copied sequences"))\r
454         {\r
455           newtitle = title;\r
456         }\r
457         else\r
458         {\r
459           newtitle = newtitle.concat("- from " + title);\r
460         }\r
461 \r
462         Desktop.addInternalFrame(af, newtitle, NEW_WINDOW_WIDTH,\r
463                                  NEW_WINDOW_HEIGHT);\r
464       }\r
465       else\r
466       {\r
467         viewport.firePropertyChange("alignment", null,\r
468                                     viewport.getAlignment().getSequences());\r
469         viewport.setEndSeq(viewport.alignment.getHeight());\r
470         viewport.alignment.getWidth();\r
471         viewport.updateConservation();\r
472         viewport.updateConsensus();\r
473         alignPanel.repaint();\r
474       }\r
475     }\r
476     catch (Exception ex)\r
477     {\r
478     }\r
479 \r
480     // could be anything being pasted in here\r
481   }\r
482 \r
483   protected void cut_actionPerformed(ActionEvent e)\r
484   {\r
485     copy_actionPerformed(null);\r
486     delete_actionPerformed(null);\r
487   }\r
488 \r
489   protected void delete_actionPerformed(ActionEvent e)\r
490   {\r
491     boolean seqsdeleted = false;\r
492 \r
493     if (viewport.getSelectionGroup() == null)\r
494     {\r
495       return;\r
496     }\r
497 \r
498     addHistoryItem(new HistoryItem("Delete Sequences", viewport.alignment,\r
499                                    HistoryItem.HIDE));\r
500 \r
501     SequenceGroup sg = viewport.getSelectionGroup();\r
502 \r
503     for (int i = 0; i < sg.sequences.size(); i++)\r
504     {\r
505       SequenceI seq = sg.getSequenceAt(i);\r
506       int index = viewport.getAlignment().findIndex(seq);\r
507       seq.deleteChars(sg.getStartRes(), sg.getEndRes() + 1);\r
508 \r
509       if (seq.getSequence().length() < 1)\r
510       {\r
511         seqsdeleted = true;\r
512         viewport.getAlignment().deleteSequence(seq);\r
513       }\r
514       else\r
515       {\r
516         viewport.getAlignment().getSequences().setElementAt(seq, index);\r
517       }\r
518     }\r
519 \r
520     viewport.setSelectionGroup(null);\r
521     viewport.alignment.deleteGroup(sg);\r
522 \r
523     if (seqsdeleted)\r
524     {\r
525       viewport.firePropertyChange("alignment", null,\r
526                                   viewport.getAlignment().getSequences());\r
527     }\r
528 \r
529     viewport.resetSeqLimits(alignPanel.seqPanel.seqCanvas.getHeight());\r
530 \r
531     if (viewport.getAlignment().getHeight() < 1)\r
532     {\r
533       try\r
534       {\r
535         this.setClosed(true);\r
536       }\r
537       catch (Exception ex)\r
538       {\r
539       }\r
540     }\r
541 \r
542     viewport.updateConservation();\r
543     viewport.updateConsensus();\r
544     alignPanel.repaint();\r
545   }\r
546 \r
547   protected void deleteGroups_actionPerformed(ActionEvent e)\r
548   {\r
549     viewport.alignment.deleteAllGroups();\r
550     viewport.setSelectionGroup(null);\r
551     alignPanel.repaint();\r
552   }\r
553 \r
554   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
555   {\r
556     SequenceGroup sg = new SequenceGroup();\r
557 \r
558     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
559          i++)\r
560     {\r
561       sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);\r
562     }\r
563 \r
564     sg.setEndRes(viewport.alignment.getWidth());\r
565     viewport.setSelectionGroup(sg);\r
566     PaintRefresher.Refresh(null, viewport.alignment);\r
567   }\r
568 \r
569   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
570   {\r
571     viewport.setSelectionGroup(null);\r
572     viewport.getColumnSelection().clear();\r
573     viewport.setSelectionGroup(null);\r
574     PaintRefresher.Refresh(null, viewport.alignment);\r
575   }\r
576 \r
577   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
578   {\r
579     SequenceGroup sg = viewport.getSelectionGroup();\r
580     if(sg==null)\r
581     {\r
582       selectAllSequenceMenuItem_actionPerformed(null);\r
583       return;\r
584     }\r
585 \r
586     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
587          i++)\r
588     {\r
589       sg.addOrRemove(viewport.getAlignment().getSequenceAt(i), false);\r
590     }\r
591 \r
592     PaintRefresher.Refresh(null, viewport.alignment);\r
593   }\r
594 \r
595   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
596   {\r
597     ColumnSelection colSel = viewport.getColumnSelection();\r
598 \r
599     if (colSel.size() > 0)\r
600     {\r
601       addHistoryItem(new HistoryItem("Remove Left", viewport.alignment,\r
602                                      HistoryItem.HIDE));\r
603 \r
604       int min = colSel.getMin();\r
605       viewport.getAlignment().trimLeft(min);\r
606       colSel.compensateForEdit(0, min);\r
607 \r
608       if (viewport.getSelectionGroup() != null)\r
609       {\r
610         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
611       }\r
612 \r
613       Vector groups = viewport.alignment.getGroups();\r
614 \r
615       for (int i = 0; i < groups.size(); i++)\r
616       {\r
617         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
618 \r
619         if (!sg.adjustForRemoveLeft(min))\r
620         {\r
621           viewport.alignment.deleteGroup(sg);\r
622         }\r
623       }\r
624 \r
625       alignPanel.repaint();\r
626     }\r
627   }\r
628 \r
629   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
630   {\r
631     ColumnSelection colSel = viewport.getColumnSelection();\r
632 \r
633     if (colSel.size() > 0)\r
634     {\r
635       addHistoryItem(new HistoryItem("Remove Right", viewport.alignment,\r
636                                      HistoryItem.HIDE));\r
637 \r
638       int max = colSel.getMax();\r
639       viewport.getAlignment().trimRight(max);\r
640 \r
641       if (viewport.getSelectionGroup() != null)\r
642       {\r
643         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
644       }\r
645 \r
646       Vector groups = viewport.alignment.getGroups();\r
647 \r
648       for (int i = 0; i < groups.size(); i++)\r
649       {\r
650         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
651 \r
652         if (!sg.adjustForRemoveRight(max))\r
653         {\r
654           viewport.alignment.deleteGroup(sg);\r
655         }\r
656       }\r
657 \r
658       alignPanel.repaint();\r
659     }\r
660   }\r
661 \r
662   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
663   {\r
664     addHistoryItem(new HistoryItem("Remove Gapped Columns",\r
665                                    viewport.alignment, HistoryItem.HIDE));\r
666 \r
667     viewport.getAlignment().removeGaps();\r
668     viewport.updateConservation();\r
669     viewport.updateConsensus();\r
670     alignPanel.repaint();\r
671   }\r
672 \r
673   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
674   {\r
675     addHistoryItem(new HistoryItem("Remove Gaps", viewport.alignment,\r
676                                    HistoryItem.HIDE));\r
677 \r
678     SequenceI current;\r
679     int jSize;\r
680 \r
681     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
682          i++)\r
683     {\r
684       current = viewport.getAlignment().getSequenceAt(i);\r
685       jSize = current.getLength();\r
686 \r
687       for (int j = 0; j < jSize; j++)\r
688       {\r
689         if (jalview.util.Comparison.isGap(current.getCharAt(j)))\r
690         {\r
691           current.deleteCharAt(j);\r
692           j--;\r
693           jSize--;\r
694         }\r
695       }\r
696     }\r
697 \r
698     viewport.updateConservation();\r
699     viewport.updateConsensus();\r
700     alignPanel.repaint();\r
701   }\r
702 \r
703   public void padGapsMenuitem_actionPerformed(ActionEvent e)\r
704   {\r
705     addHistoryItem(new HistoryItem("Pad Gaps", viewport.alignment,\r
706                                    HistoryItem.HIDE));\r
707 \r
708     SequenceI current;\r
709     int Width = viewport.getAlignment().getWidth() - 1;\r
710 \r
711     for (int i = 0; i < viewport.getAlignment().getSequences().size();\r
712          i++)\r
713     {\r
714       current = viewport.getAlignment().getSequenceAt(i);\r
715 \r
716       if (current.getLength() < Width)\r
717       {\r
718         current.insertCharAt(Width, viewport.getGapCharacter());\r
719       }\r
720     }\r
721 \r
722     viewport.updateConservation();\r
723     viewport.updateConsensus();\r
724     alignPanel.repaint();\r
725   }\r
726 \r
727   public void findMenuItem_actionPerformed(ActionEvent e)\r
728   {\r
729     JInternalFrame frame = new JInternalFrame();\r
730     Finder finder = new Finder(viewport, alignPanel, frame);\r
731     frame.setContentPane(finder);\r
732     Desktop.addInternalFrame(frame, "Find", 340, 110);\r
733     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
734   }\r
735 \r
736   public void font_actionPerformed(ActionEvent e)\r
737   {\r
738     FontChooser fc = new FontChooser(alignPanel);\r
739   }\r
740 \r
741   protected void fullSeqId_actionPerformed(ActionEvent e)\r
742   {\r
743     viewport.setShowFullId(fullSeqId.isSelected());\r
744 \r
745     alignPanel.idPanel.idCanvas.setPreferredSize(alignPanel.calculateIdWidth());\r
746     alignPanel.repaint();\r
747   }\r
748 \r
749   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
750   {\r
751     viewport.setColourText(colourTextMenuItem.isSelected());\r
752     alignPanel.repaint();\r
753   }\r
754 \r
755   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
756   {\r
757     viewport.setWrapAlignment(wrapMenuItem.isSelected());\r
758     alignPanel.setWrapAlignment(wrapMenuItem.isSelected());\r
759     scaleAbove.setVisible(wrapMenuItem.isSelected());\r
760     scaleLeft.setVisible(wrapMenuItem.isSelected());\r
761     scaleRight.setVisible(wrapMenuItem.isSelected());\r
762     alignPanel.repaint();\r
763   }\r
764 \r
765   protected void scaleAbove_actionPerformed(ActionEvent e)\r
766   {\r
767     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
768     alignPanel.repaint();\r
769   }\r
770 \r
771   protected void scaleLeft_actionPerformed(ActionEvent e)\r
772   {\r
773     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
774     alignPanel.repaint();\r
775   }\r
776 \r
777   protected void scaleRight_actionPerformed(ActionEvent e)\r
778   {\r
779     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
780     alignPanel.repaint();\r
781   }\r
782 \r
783   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
784   {\r
785     viewport.setShowBoxes(viewBoxesMenuItem.isSelected());\r
786     alignPanel.repaint();\r
787   }\r
788 \r
789   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
790   {\r
791     viewport.setShowText(viewTextMenuItem.isSelected());\r
792     alignPanel.repaint();\r
793   }\r
794 \r
795   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
796   {\r
797     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
798     alignPanel.repaint();\r
799   }\r
800 \r
801   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
802   {\r
803     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
804 \r
805     if (viewport.showSequenceFeatures &&\r
806         ! ( (Alignment) viewport.alignment).featuresAdded)\r
807     {\r
808       SequenceFeatureFetcher sft = new SequenceFeatureFetcher(viewport.\r
809           alignment,\r
810           alignPanel);\r
811       ( (Alignment) viewport.alignment).featuresAdded = true;\r
812     }\r
813 \r
814     alignPanel.repaint();\r
815   }\r
816 \r
817   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
818   {\r
819     if (annotationPanelMenuItem.isSelected() &&\r
820         viewport.getWrapAlignment())\r
821     {\r
822       annotationPanelMenuItem.setSelected(false);\r
823 \r
824       return;\r
825     }\r
826 \r
827     viewport.setShowAnnotation(annotationPanelMenuItem.isSelected());\r
828     alignPanel.setAnnotationVisible(annotationPanelMenuItem.isSelected());\r
829   }\r
830 \r
831   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
832   {\r
833     if (alignPanel.overviewPanel != null)\r
834     {\r
835       return;\r
836     }\r
837 \r
838     JInternalFrame frame = new JInternalFrame();\r
839     OverviewPanel overview = new OverviewPanel(alignPanel);\r
840     frame.setContentPane(overview);\r
841     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
842                              frame.getWidth(), frame.getHeight());\r
843     frame.pack();\r
844     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
845     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
846     {\r
847       public void internalFrameClosed(\r
848           javax.swing.event.InternalFrameEvent evt)\r
849       {\r
850         alignPanel.setOverviewPanel(null);\r
851       }\r
852       ;\r
853     });\r
854 \r
855     alignPanel.setOverviewPanel(overview);\r
856   }\r
857 \r
858   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
859   {\r
860     changeColour(null);\r
861   }\r
862 \r
863   public void clustalColour_actionPerformed(ActionEvent e)\r
864   {\r
865     changeColour(new ClustalxColourScheme(\r
866         viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
867   }\r
868 \r
869   public void zappoColour_actionPerformed(ActionEvent e)\r
870   {\r
871     changeColour(new ZappoColourScheme());\r
872   }\r
873 \r
874   public void taylorColour_actionPerformed(ActionEvent e)\r
875   {\r
876     changeColour(new TaylorColourScheme());\r
877   }\r
878 \r
879   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
880   {\r
881     changeColour(new HydrophobicColourScheme());\r
882   }\r
883 \r
884   public void helixColour_actionPerformed(ActionEvent e)\r
885   {\r
886     changeColour(new HelixColourScheme());\r
887   }\r
888 \r
889   public void strandColour_actionPerformed(ActionEvent e)\r
890   {\r
891     changeColour(new StrandColourScheme());\r
892   }\r
893 \r
894   public void turnColour_actionPerformed(ActionEvent e)\r
895   {\r
896     changeColour(new TurnColourScheme());\r
897   }\r
898 \r
899   public void buriedColour_actionPerformed(ActionEvent e)\r
900   {\r
901     changeColour(new BuriedColourScheme());\r
902   }\r
903 \r
904   public void nucleotideColour_actionPerformed(ActionEvent e)\r
905   {\r
906     changeColour(new NucleotideColourScheme());\r
907   }\r
908 \r
909   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
910   {\r
911     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
912   }\r
913 \r
914   void changeColour(ColourSchemeI cs)\r
915   {\r
916     int threshold = 0;\r
917 \r
918     if (viewport.getAbovePIDThreshold())\r
919     {\r
920       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs,\r
921                                                  "Background");\r
922 \r
923       if (cs instanceof ResidueColourScheme)\r
924       {\r
925         ( (ResidueColourScheme) cs).setThreshold(threshold);\r
926       }\r
927       else if (cs instanceof ScoreColourScheme)\r
928       {\r
929         ( (ScoreColourScheme) cs).setThreshold(threshold);\r
930       }\r
931 \r
932       viewport.setGlobalColourScheme(cs);\r
933     }\r
934     else if (cs instanceof ResidueColourScheme)\r
935     {\r
936       ( (ResidueColourScheme) cs).setThreshold(0);\r
937     }\r
938     else if (cs instanceof ScoreColourScheme)\r
939     {\r
940       ( (ScoreColourScheme) cs).setThreshold(0);\r
941     }\r
942 \r
943     if (viewport.getConservationSelected())\r
944     {\r
945       ConservationColourScheme ccs = null;\r
946 \r
947       Alignment al = (Alignment) viewport.alignment;\r
948       Conservation c = new Conservation("All",\r
949                                         ResidueProperties.propHash, 3,\r
950                                         al.getSequences(), 0,\r
951                                         al.getWidth() - 1);\r
952 \r
953       c.calculate();\r
954       c.verdict(false, viewport.ConsPercGaps);\r
955 \r
956       ccs = new ConservationColourScheme(c, cs);\r
957 \r
958       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
959       ccs.setConsensus(viewport.vconsensus);\r
960       viewport.setGlobalColourScheme(ccs);\r
961 \r
962       ccs.inc = SliderPanel.setConservationSlider(alignPanel, ccs,\r
963                                                   "Background");\r
964     }\r
965     else\r
966     {\r
967       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
968       if (cs != null)\r
969       {\r
970         cs.setConsensus(viewport.vconsensus);\r
971       }\r
972 \r
973       viewport.setGlobalColourScheme(cs);\r
974     }\r
975 \r
976     if (viewport.getColourAppliesToAllGroups())\r
977     {\r
978       Vector groups = viewport.alignment.getGroups();\r
979 \r
980       for (int i = 0; i < groups.size(); i++)\r
981       {\r
982         SequenceGroup sg = (SequenceGroup) groups.elementAt(i);\r
983 \r
984         if (cs == null)\r
985         {\r
986           sg.cs = null;\r
987         }\r
988         else if (cs instanceof ClustalxColourScheme)\r
989         {\r
990           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
991         }\r
992         else if (cs instanceof UserColourScheme)\r
993         {\r
994           sg.cs = new UserColourScheme( ( (UserColourScheme) cs).getColours());\r
995         }\r
996         else\r
997         {\r
998           try\r
999           {\r
1000             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
1001           }\r
1002           catch (Exception ex)\r
1003           {\r
1004           }\r
1005         }\r
1006 \r
1007         if (viewport.getAbovePIDThreshold())\r
1008         {\r
1009           if (sg.cs instanceof ResidueColourScheme)\r
1010           {\r
1011             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);\r
1012           }\r
1013           else if (sg.cs instanceof ScoreColourScheme)\r
1014           {\r
1015             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);\r
1016           }\r
1017 \r
1018           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1019               sg.getWidth()));\r
1020         }\r
1021 \r
1022         if (viewport.getConservationSelected())\r
1023         {\r
1024           Conservation c = new Conservation("Group",\r
1025                                             ResidueProperties.propHash, 3,\r
1026                                             sg.sequences, 0,\r
1027                                             viewport.alignment.getWidth() - 1);\r
1028           c.calculate();\r
1029           c.verdict(false, viewport.ConsPercGaps);\r
1030 \r
1031           ConservationColourScheme ccs = new ConservationColourScheme(c,\r
1032               sg.cs);\r
1033 \r
1034           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1035           ccs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1036                                                  sg.getWidth()));\r
1037           sg.cs = ccs;\r
1038         }\r
1039         else if (cs != null)\r
1040         {\r
1041           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
1042           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0,\r
1043               sg.getWidth()));\r
1044         }\r
1045       }\r
1046     }\r
1047 \r
1048     if (alignPanel.getOverviewPanel() != null)\r
1049     {\r
1050       alignPanel.getOverviewPanel().updateOverviewImage();\r
1051     }\r
1052 \r
1053     alignPanel.repaint();\r
1054   }\r
1055 \r
1056   protected void modifyPID_actionPerformed(ActionEvent e)\r
1057   {\r
1058     if (viewport.getAbovePIDThreshold())\r
1059     {\r
1060       SliderPanel.setPIDSliderSource(alignPanel,\r
1061                                      viewport.getGlobalColourScheme(),\r
1062                                      "Background");\r
1063       SliderPanel.showPIDSlider();\r
1064     }\r
1065   }\r
1066 \r
1067   protected void modifyConservation_actionPerformed(ActionEvent e)\r
1068   {\r
1069     if (viewport.getConservationSelected())\r
1070     {\r
1071       SliderPanel.setConservationSlider(alignPanel,\r
1072                                         viewport.globalColourScheme,\r
1073                                         "Background");\r
1074       SliderPanel.showConservationSlider();\r
1075     }\r
1076   }\r
1077 \r
1078   protected void conservationMenuItem_actionPerformed(ActionEvent e)\r
1079   {\r
1080     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
1081 \r
1082     viewport.setAbovePIDThreshold(false);\r
1083     abovePIDThreshold.setSelected(false);\r
1084 \r
1085     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1086 \r
1087     if (cs instanceof ConservationColourScheme)\r
1088     {\r
1089       changeColour( ( (ConservationColourScheme) cs).cs);\r
1090     }\r
1091     else\r
1092     {\r
1093       changeColour(cs);\r
1094     }\r
1095 \r
1096     modifyConservation_actionPerformed(null);\r
1097   }\r
1098 \r
1099   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
1100   {\r
1101     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
1102 \r
1103     conservationMenuItem.setSelected(false);\r
1104     viewport.setConservationSelected(false);\r
1105 \r
1106     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
1107 \r
1108     if (cs instanceof ConservationColourScheme)\r
1109     {\r
1110       changeColour( ( (ConservationColourScheme) cs).cs);\r
1111     }\r
1112     else\r
1113     {\r
1114       changeColour(cs);\r
1115     }\r
1116 \r
1117     modifyPID_actionPerformed(null);\r
1118   }\r
1119 \r
1120   public void userDefinedColour_actionPerformed(ActionEvent e)\r
1121   {\r
1122     new UserDefinedColours(alignPanel, null);\r
1123   }\r
1124 \r
1125   public void PIDColour_actionPerformed(ActionEvent e)\r
1126   {\r
1127     changeColour(new PIDColourScheme());\r
1128   }\r
1129 \r
1130   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
1131   {\r
1132     changeColour(new Blosum62ColourScheme());\r
1133   }\r
1134 \r
1135   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
1136   {\r
1137     addHistoryItem(new HistoryItem("Pairwise Sort", viewport.alignment,\r
1138                                    HistoryItem.SORT));\r
1139     AlignmentSorter.sortByPID(viewport.getAlignment(),\r
1140                               viewport.getAlignment().getSequenceAt(0));\r
1141     alignPanel.repaint();\r
1142   }\r
1143 \r
1144   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
1145   {\r
1146     addHistoryItem(new HistoryItem("ID Sort", viewport.alignment,\r
1147                                    HistoryItem.SORT));\r
1148     AlignmentSorter.sortByID(viewport.getAlignment());\r
1149     alignPanel.repaint();\r
1150   }\r
1151 \r
1152   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
1153   {\r
1154     addHistoryItem(new HistoryItem("Group Sort", viewport.alignment,\r
1155                                    HistoryItem.SORT));\r
1156 \r
1157     //  AlignmentSorter.sortByGroup(viewport.getAlignment());\r
1158     AlignmentSorter.sortGroups(viewport.getAlignment());\r
1159     alignPanel.repaint();\r
1160   }\r
1161 \r
1162   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
1163   {\r
1164     RedundancyPanel sp = new RedundancyPanel(alignPanel, this);\r
1165     JInternalFrame frame = new JInternalFrame();\r
1166     frame.setContentPane(sp);\r
1167     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400,\r
1168                              100, false);\r
1169   }\r
1170 \r
1171   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
1172   {\r
1173     if ( (viewport.getSelectionGroup() == null) ||\r
1174         (viewport.getSelectionGroup().getSize() < 2))\r
1175     {\r
1176       JOptionPane.showInternalMessageDialog(this,\r
1177                                             "You must select at least 2 sequences.",\r
1178                                             "Invalid Selection",\r
1179                                             JOptionPane.WARNING_MESSAGE);\r
1180     }\r
1181     else\r
1182     {\r
1183       JInternalFrame frame = new JInternalFrame();\r
1184       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
1185       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
1186     }\r
1187   }\r
1188 \r
1189   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
1190   {\r
1191     if ( ( (viewport.getSelectionGroup() != null) &&\r
1192           (viewport.getSelectionGroup().getSize() < 4) &&\r
1193           (viewport.getSelectionGroup().getSize() > 0)) ||\r
1194         (viewport.getAlignment().getHeight() < 4))\r
1195     {\r
1196       JOptionPane.showInternalMessageDialog(this,\r
1197                                             "Principal component analysis must take\n" +\r
1198                                             "at least 4 input sequences.",\r
1199                                             "Sequence selection insufficient",\r
1200                                             JOptionPane.WARNING_MESSAGE);\r
1201 \r
1202       return;\r
1203     }\r
1204 \r
1205     try\r
1206     {\r
1207       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1208       JInternalFrame frame = new JInternalFrame();\r
1209       frame.setContentPane(pcaPanel);\r
1210       Desktop.addInternalFrame(frame, "Principal component analysis",\r
1211                                400, 400);\r
1212     }\r
1213     catch (java.lang.OutOfMemoryError ex)\r
1214     {\r
1215       JOptionPane.showInternalMessageDialog(this,\r
1216                                             "Too many sequences selected\nfor Principal Component Analysis!!",\r
1217                                             "Out of memory",\r
1218                                             JOptionPane.WARNING_MESSAGE);\r
1219     }\r
1220   }\r
1221 \r
1222   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1223   {\r
1224     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1225   }\r
1226 \r
1227   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1228   {\r
1229     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1230   }\r
1231 \r
1232   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1233   {\r
1234     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1235   }\r
1236 \r
1237   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1238   {\r
1239     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62");\r
1240   }\r
1241 \r
1242   void NewTreePanel(String type, String pwType, String title)\r
1243   {\r
1244     final TreePanel tp;\r
1245 \r
1246     if ( (viewport.getSelectionGroup() != null) &&\r
1247         (viewport.getSelectionGroup().getSize() > 3))\r
1248     {\r
1249       int s = 0;\r
1250       SequenceGroup sg = viewport.getSelectionGroup();\r
1251 \r
1252       /* Decide if the selection is a column region */\r
1253       while (s < sg.sequences.size())\r
1254       {\r
1255         if ( ( (SequenceI) sg.sequences.elementAt(s++)).getLength() <\r
1256             sg.getEndRes())\r
1257         {\r
1258           JOptionPane.showMessageDialog(Desktop.desktop,\r
1259                                         "The selected region to create a tree may\nonly contain residues or gaps.\n" +\r
1260                                         "Try using the Pad function in the edit menu,\n" +\r
1261                                         "or one of the multiple sequence alignment web services.",\r
1262                                         "Sequences in selection are not aligned",\r
1263                                         JOptionPane.WARNING_MESSAGE);\r
1264 \r
1265           return;\r
1266         }\r
1267       }\r
1268 \r
1269       title = title + " on region";\r
1270       tp = new TreePanel(viewport,\r
1271                          viewport.getSelectionGroup().sequences, type, pwType,\r
1272                          sg.getStartRes(), sg.getEndRes());\r
1273     }\r
1274     else\r
1275     {\r
1276       //are the sequences aligned?\r
1277       if (!viewport.alignment.isAligned())\r
1278       {\r
1279         JOptionPane.showMessageDialog(Desktop.desktop,\r
1280                                       "The sequences must be aligned before creating a tree.\n" +\r
1281                                       "Try using the Pad function in the edit menu,\n" +\r
1282                                       "or one of the multiple sequence alignment web services.",\r
1283                                       "Sequences not aligned",\r
1284                                       JOptionPane.WARNING_MESSAGE);\r
1285 \r
1286         return;\r
1287       }\r
1288 \r
1289       tp = new TreePanel(viewport,\r
1290                          viewport.getAlignment().getSequences(), type, pwType,\r
1291                          0,\r
1292                          viewport.alignment.getWidth());\r
1293     }\r
1294 \r
1295     addTreeMenuItem(tp, title);\r
1296     viewport.setCurrentTree(tp.getTree());\r
1297 \r
1298     Desktop.addInternalFrame(tp, title + " from " + this.title, 600, 500);\r
1299   }\r
1300 \r
1301   public void addSortByOrderMenuItem(String title, final AlignmentOrder order)\r
1302   {\r
1303     final JMenuItem item = new JMenuItem("by " + title);\r
1304     sort.add(item);\r
1305     item.addActionListener(new java.awt.event.ActionListener()\r
1306     {\r
1307       public void actionPerformed(ActionEvent e)\r
1308       {\r
1309         addHistoryItem(new HistoryItem("Sort", viewport.alignment,\r
1310                                        HistoryItem.SORT));\r
1311 \r
1312         // TODO: JBPNote - have to map order entries to curent SequenceI pointers\r
1313         AlignmentSorter.sortBy(viewport.getAlignment(), order);\r
1314         alignPanel.repaint();\r
1315       }\r
1316     });\r
1317   }\r
1318 \r
1319   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1320   {\r
1321     final JMenuItem item = new JMenuItem(title);\r
1322 \r
1323     treeCount++;\r
1324 \r
1325     if (treeCount == 1)\r
1326     {\r
1327       sort.add(sortByTreeMenu);\r
1328     }\r
1329 \r
1330     sortByTreeMenu.add(item);\r
1331     item.addActionListener(new java.awt.event.ActionListener()\r
1332     {\r
1333       public void actionPerformed(ActionEvent e)\r
1334       {\r
1335         addHistoryItem(new HistoryItem("Tree Sort",\r
1336                                        viewport.alignment, HistoryItem.SORT));\r
1337         AlignmentSorter.sortByTree(viewport.getAlignment(),\r
1338                                    treePanel.getTree());\r
1339         alignPanel.repaint();\r
1340       }\r
1341     });\r
1342 \r
1343     treePanel.addInternalFrameListener(new javax.swing.event.\r
1344                                        InternalFrameAdapter()\r
1345     {\r
1346       public void internalFrameClosed(\r
1347           javax.swing.event.InternalFrameEvent evt)\r
1348       {\r
1349         treeCount--;\r
1350         sortByTreeMenu.remove(item);\r
1351 \r
1352         if (treeCount == 0)\r
1353         {\r
1354           sort.remove(sortByTreeMenu);\r
1355         }\r
1356       }\r
1357       ;\r
1358     });\r
1359     viewport.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
1360     {\r
1361       public void propertyChange(PropertyChangeEvent evt)\r
1362       {\r
1363         if (evt.getPropertyName().equals("alignment"))\r
1364         {\r
1365           treePanel.getTree().UpdatePlaceHolders( (Vector) evt.getNewValue());\r
1366           treePanel.repaint();\r
1367         }\r
1368       }\r
1369     });\r
1370   }\r
1371 \r
1372   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)\r
1373   {\r
1374     // TODO:resolve which menu item was actually selected\r
1375     // Now, check we have enough sequences\r
1376     SequenceI[] msa = null;\r
1377 \r
1378     if ( (viewport.getSelectionGroup() != null) &&\r
1379         (viewport.getSelectionGroup().getSize() > 1))\r
1380     {\r
1381       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1382       SequenceGroup seqs = viewport.getSelectionGroup();\r
1383       int sz;\r
1384       msa = new SequenceI[sz = seqs.getSize()];\r
1385 \r
1386       for (int i = 0; i < sz; i++)\r
1387       {\r
1388         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1389       }\r
1390     }\r
1391     else\r
1392     {\r
1393       Vector seqs = viewport.getAlignment().getSequences();\r
1394 \r
1395       if (seqs.size() > 1)\r
1396       {\r
1397         msa = new SequenceI[seqs.size()];\r
1398 \r
1399         for (int i = 0; i < seqs.size(); i++)\r
1400         {\r
1401           msa[i] = (SequenceI) seqs.elementAt(i);\r
1402         }\r
1403       }\r
1404     }\r
1405 \r
1406     if (msa != null)\r
1407     {\r
1408       jalview.ws.MsaWSClient ct = new jalview.ws.MsaWSClient("ClustalWS",\r
1409           title, msa, false, true);\r
1410     }\r
1411   }\r
1412 \r
1413   public void ClustalRealign_actionPerformed(ActionEvent e)\r
1414   {\r
1415     // TODO:resolve which menu item was actually selected\r
1416     // Now, check we have enough sequences\r
1417     SequenceI[] msa = null;\r
1418 \r
1419     if ( (viewport.getSelectionGroup() != null) &&\r
1420         (viewport.getSelectionGroup().getSize() > 1))\r
1421     {\r
1422       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1423       SequenceGroup seqs = viewport.getSelectionGroup();\r
1424       int sz;\r
1425       msa = new SequenceI[sz = seqs.getSize()];\r
1426 \r
1427       for (int i = 0; i < sz; i++)\r
1428       {\r
1429         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1430       }\r
1431     }\r
1432     else\r
1433     {\r
1434       Vector seqs = viewport.getAlignment().getSequences();\r
1435 \r
1436       if (seqs.size() > 1)\r
1437       {\r
1438         msa = new SequenceI[seqs.size()];\r
1439 \r
1440         for (int i = 0; i < seqs.size(); i++)\r
1441         {\r
1442           msa[i] = (SequenceI) seqs.elementAt(i);\r
1443         }\r
1444       }\r
1445     }\r
1446 \r
1447     if (msa != null)\r
1448     {\r
1449       jalview.ws.MsaWSClient ct = new jalview.ws.MsaWSClient("ClustalWS",\r
1450           title, msa, true, true);\r
1451     }\r
1452   }\r
1453 \r
1454   protected void jpred_actionPerformed(ActionEvent e)\r
1455   {\r
1456     SequenceI seq = null;\r
1457     SequenceI[] msa = null;\r
1458 \r
1459     if ( (viewport.getSelectionGroup() != null) &&\r
1460         (viewport.getSelectionGroup().getSize() > 0))\r
1461     {\r
1462       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1463       SequenceGroup seqs = viewport.getSelectionGroup();\r
1464 \r
1465       if ( (seqs.getSize() == 1) || !viewport.alignment.isAligned())\r
1466       {\r
1467         seq = (SequenceI) seqs.getSequenceAt(0);\r
1468       }\r
1469       else\r
1470       {\r
1471         int sz;\r
1472         msa = new SequenceI[sz = seqs.getSize()];\r
1473 \r
1474         for (int i = 0; i < sz; i++)\r
1475         {\r
1476           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1477         }\r
1478       }\r
1479     }\r
1480     else\r
1481     {\r
1482       Vector seqs = viewport.getAlignment().getSequences();\r
1483 \r
1484       if ( (seqs.size() == 1) || !viewport.alignment.isAligned())\r
1485       {\r
1486         seq = (SequenceI) seqs.elementAt(0);\r
1487       }\r
1488       else\r
1489       {\r
1490         msa = new SequenceI[seqs.size()];\r
1491 \r
1492         for (int i = 0; i < seqs.size(); i++)\r
1493         {\r
1494           msa[i] = (SequenceI) seqs.elementAt(i);\r
1495         }\r
1496       }\r
1497     }\r
1498 \r
1499     if (msa != null)\r
1500     {\r
1501       JPredClient ct = new JPredClient(title, msa);\r
1502     }\r
1503     else if (seq != null)\r
1504     {\r
1505       JPredClient ct = new JPredClient(title, seq);\r
1506     }\r
1507     else\r
1508     {\r
1509       System.err.print(\r
1510           "JALVIEW ERROR! - Unexpected JPred selection state!\n");\r
1511     }\r
1512   }\r
1513 \r
1514   protected void msaAlignMenuItem_actionPerformed(ActionEvent e)\r
1515   {\r
1516     // TODO:resolve which menu item was actually selected\r
1517     // Now, check we have enough sequences\r
1518     SequenceI[] msa = null;\r
1519 \r
1520     if ( (viewport.getSelectionGroup() != null) &&\r
1521         (viewport.getSelectionGroup().getSize() > 1))\r
1522     {\r
1523       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1524       SequenceGroup seqs = viewport.getSelectionGroup();\r
1525       int sz;\r
1526       msa = new SequenceI[sz = seqs.getSize()];\r
1527 \r
1528       for (int i = 0; i < sz; i++)\r
1529       {\r
1530         msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1531       }\r
1532     }\r
1533     else\r
1534     {\r
1535       Vector seqs = viewport.getAlignment().getSequences();\r
1536 \r
1537       if (seqs.size() > 1)\r
1538       {\r
1539         msa = new SequenceI[seqs.size()];\r
1540 \r
1541         for (int i = 0; i < seqs.size(); i++)\r
1542         {\r
1543           msa[i] = (SequenceI) seqs.elementAt(i);\r
1544         }\r
1545       }\r
1546     }\r
1547 \r
1548     if (msa != null)\r
1549     {\r
1550       MsaWSClient ct = new jalview.ws.MsaWSClient("MuscleWS", title, msa,\r
1551                                                   false, true);\r
1552     }\r
1553   }\r
1554 \r
1555   protected void LoadtreeMenuItem_actionPerformed(ActionEvent e)\r
1556   {\r
1557     // Pick the tree file\r
1558     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
1559         getProperty(\r
1560             "LAST_DIRECTORY"));\r
1561     chooser.setFileView(new JalviewFileView());\r
1562     chooser.setDialogTitle("Select a newick-like tree file");\r
1563     chooser.setToolTipText("Load a tree file");\r
1564 \r
1565     int value = chooser.showOpenDialog(null);\r
1566 \r
1567     if (value == JalviewFileChooser.APPROVE_OPTION)\r
1568     {\r
1569       String choice = chooser.getSelectedFile().getPath();\r
1570       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
1571 \r
1572       try\r
1573       {\r
1574         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice,\r
1575             "File");\r
1576         viewport.setCurrentTree( ShowNewickTree(fin, choice).getTree() );\r
1577       }\r
1578       catch (Exception ex)\r
1579       {\r
1580         JOptionPane.showMessageDialog(Desktop.desktop,\r
1581                                       "Problem reading tree file",\r
1582                                       ex.getMessage(),\r
1583                                       JOptionPane.WARNING_MESSAGE);\r
1584         ex.printStackTrace();\r
1585       }\r
1586     }\r
1587   }\r
1588 \r
1589   public TreePanel ShowNewickTree(NewickFile nf, String title)\r
1590   {\r
1591     TreePanel tp = null;\r
1592     try\r
1593     {\r
1594       nf.parse();\r
1595       if (nf.getTree() != null)\r
1596       {\r
1597         tp = new TreePanel(viewport,\r
1598                                      viewport.getAlignment().getSequences(), nf,\r
1599                                      "FromFile",\r
1600                                      title);\r
1601         Desktop.addInternalFrame(tp, title, 600, 500);\r
1602         addTreeMenuItem(tp, title);\r
1603       }\r
1604     }\r
1605     catch (Exception ex)\r
1606     {\r
1607       ex.printStackTrace();\r
1608     }\r
1609     return tp;\r
1610   }\r
1611 \r
1612   class PrintThread\r
1613       extends Thread\r
1614   {\r
1615     public void run()\r
1616     {\r
1617       PrinterJob printJob = PrinterJob.getPrinterJob();\r
1618       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
1619       printJob.setPrintable(alignPanel, pf);\r
1620 \r
1621       if (printJob.printDialog())\r
1622       {\r
1623         try\r
1624         {\r
1625           printJob.print();\r
1626         }\r
1627         catch (Exception PrintException)\r
1628         {\r
1629           PrintException.printStackTrace();\r
1630         }\r
1631       }\r
1632     }\r
1633   }\r
1634 }\r