Overviewpanel allows for large alignments
[jalview.git] / src / jalview / gui / AlignFrame.java
1 /********************\r
2  * 2004 Jalview Reengineered\r
3  * Barton Group\r
4  * Dundee University\r
5  *\r
6  * AM Waterhouse\r
7  *******************/\r
8 \r
9 \r
10 \r
11 \r
12 package jalview.gui;\r
13 \r
14 import jalview.jbgui.GAlignFrame;\r
15 import jalview.schemes.*;\r
16 import jalview.datamodel.*;\r
17 import jalview.analysis.*;\r
18 import jalview.io.*;\r
19 import jalview.ws.*;\r
20 import java.awt.*;\r
21 import java.awt.event.*;\r
22 import java.awt.print.*;\r
23 import javax.swing.*;\r
24 import javax.swing.event.*;\r
25 import java.util.*;\r
26 import java.awt.datatransfer.*;\r
27 \r
28 \r
29 public class AlignFrame extends GAlignFrame\r
30 {\r
31   final AlignmentPanel alignPanel;\r
32   final AlignViewport viewport;\r
33   public static final int NEW_WINDOW_WIDTH = 700;\r
34   public static final int NEW_WINDOW_HEIGHT = 500;\r
35 \r
36   public AlignFrame(AlignmentI al)\r
37   {\r
38     try{\r
39       String ip = java.net.InetAddress.getLocalHost().getHostAddress();\r
40       if( !ip.startsWith("10."))\r
41         alignMenu.setVisible(false);\r
42     }\r
43     catch(java.net.UnknownHostException e){}\r
44     viewport = new AlignViewport(al,true,true,false);\r
45 \r
46     String fontName = jalview.bin.Cache.getProperty("FONT_NAME");\r
47     String fontStyle= jalview.bin.Cache.getProperty("FONT_STYLE");\r
48     String fontSize = jalview.bin.Cache.getProperty("FONT_SIZE");\r
49     if(fontName!=null && fontStyle!=null && fontSize!=null)\r
50       viewport.setFont( new Font(fontName,Integer.parseInt(fontStyle),Integer.parseInt(fontSize)) );\r
51 \r
52     // add conservation graph to alignment\r
53     viewport.updateConservation();\r
54     viewport.updateConsensus();\r
55 \r
56 \r
57     alignPanel = new AlignmentPanel(this, viewport);\r
58 \r
59     alignPanel.annotationPanel.adjustPanelHeight();\r
60     alignPanel.annotationSpaceFillerHolder.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
61     alignPanel.annotationScroller.setPreferredSize(alignPanel.annotationPanel.getPreferredSize());\r
62 \r
63     getContentPane().add(alignPanel, java.awt.BorderLayout.CENTER);\r
64 \r
65 \r
66     addInternalFrameListener(new InternalFrameAdapter()\r
67    {\r
68      public void internalFrameActivated(InternalFrameEvent evt)\r
69      {\r
70           javax.swing.SwingUtilities.invokeLater(new Runnable()\r
71           {\r
72             public void run()\r
73             {      alignPanel.requestFocus();    }\r
74           });\r
75 \r
76      }\r
77    });\r
78 \r
79   }\r
80 \r
81   protected void saveAs_actionPerformed(ActionEvent e)\r
82   {\r
83     String suffix [] = null;\r
84     if(e.getActionCommand().equals("FASTA"))\r
85       suffix = new String[]{"fa", "fasta"};\r
86     else if(e.getActionCommand().equals("MSF"))\r
87       suffix = new String[]{"msf"};\r
88     else if(e.getActionCommand().equals("CLUSTAL"))\r
89       suffix = new String[]{"aln"};\r
90     else if(e.getActionCommand().equals("BLC"))\r
91       suffix = new String[]{"blc"};\r
92     else if(e.getActionCommand().equals("PIR"))\r
93       suffix = new String[]{"pir"};\r
94     else if(e.getActionCommand().equals("PFAM"))\r
95       suffix = new String[]{"pfam"};\r
96 \r
97 \r
98     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty("LAST_DIRECTORY")\r
99         , suffix, e.getActionCommand()+" file");\r
100     chooser.setFileView(new JalviewFileView());\r
101     chooser.setDialogTitle("Save Alignment to file - "+e.getActionCommand() +" format.");\r
102     chooser.setToolTipText("Save");\r
103     int value = chooser.showSaveDialog(this);\r
104     if(value == JalviewFileChooser.APPROVE_OPTION)\r
105     {\r
106       String choice =  chooser.getSelectedFile().getPath();\r
107       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
108       String output = FormatAdapter.get(e.getActionCommand(), viewport.getAlignment().getSequences());\r
109       try{\r
110         java.io.PrintWriter out = new java.io.PrintWriter( new java.io.FileWriter( choice )  );\r
111         out.println(output);\r
112         out.close();\r
113       }\r
114       catch(Exception ex){}\r
115     }\r
116 \r
117   }\r
118 \r
119   protected void outputText_actionPerformed(ActionEvent e)\r
120   {\r
121      CutAndPasteTransfer cap = new CutAndPasteTransfer(false);\r
122      JInternalFrame frame = new JInternalFrame();\r
123      cap.formatForOutput();\r
124      frame.setContentPane(cap);\r
125      Desktop.addInternalFrame(frame, "Alignment output - "+e.getActionCommand(), 600, 500);\r
126      cap.setText( FormatAdapter.get(e.getActionCommand(), viewport.getAlignment().getSequences()));\r
127   }\r
128 \r
129   protected void htmlMenuItem_actionPerformed(ActionEvent e)\r
130   {\r
131     HTMLOutput htmlOutput = new HTMLOutput(viewport);\r
132     htmlOutput = null;\r
133   }\r
134 \r
135   protected void createPNG_actionPerformed(ActionEvent e)\r
136   {\r
137     alignPanel.makePNG();\r
138   }\r
139 \r
140   protected void epsFile_actionPerformed(ActionEvent e)\r
141   {\r
142     alignPanel.makeEPS();\r
143   }\r
144 \r
145 \r
146   public void printMenuItem_actionPerformed(ActionEvent e)\r
147   {\r
148     //Putting in a thread avoids Swing painting problems\r
149     PrintThread thread = new PrintThread();\r
150     thread.start();\r
151   }\r
152 \r
153   class PrintThread extends Thread\r
154   {\r
155     public void run()\r
156     {\r
157       PrinterJob printJob = PrinterJob.getPrinterJob();\r
158       PageFormat pf = printJob.pageDialog(printJob.defaultPage());\r
159       printJob.setPrintable(alignPanel, pf);\r
160       if (printJob.printDialog())\r
161       {\r
162         try\r
163         {\r
164           printJob.print();\r
165         }\r
166         catch (Exception PrintException)\r
167         {\r
168           PrintException.printStackTrace();\r
169         }\r
170       }\r
171     }\r
172 \r
173   }\r
174 \r
175 \r
176 \r
177 \r
178   public void closeMenuItem_actionPerformed(ActionEvent e)\r
179   {\r
180     try{\r
181       this.setClosed(true);\r
182     }catch(Exception ex){}\r
183   }\r
184 \r
185   Stack historyList = new Stack();\r
186   Stack redoList = new Stack();\r
187   JMenuBar jMenuBar1 = new JMenuBar();\r
188 \r
189   void updateEditMenuBar()\r
190   {\r
191     if(historyList.size()>0)\r
192      {\r
193        undoMenuItem.setEnabled(true);\r
194        Object [] history = (Object[])historyList.get(0);\r
195        undoMenuItem.setText("Undo "+history[0]);\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        Object [] history = (Object[])redoList.get(0);\r
207        redoMenuItem.setText("Redo "+history[0]);\r
208      }\r
209     else\r
210     {\r
211       redoMenuItem.setEnabled(false);\r
212       redoMenuItem.setText("Redo");\r
213     }\r
214   }\r
215 \r
216   public void addHistoryItem(String type)\r
217   {\r
218     // must make sure we add new sequence objects her, not refs to the existing sequences\r
219     redoList.clear();\r
220     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
221     for(int i=0; i<viewport.getAlignment().getHeight(); i++)\r
222     {\r
223       seq[i] = new Sequence( viewport.getAlignment().getSequenceAt(i).getName(),\r
224                              viewport.getAlignment().getSequenceAt(i).getSequence());\r
225     }\r
226 \r
227     historyList.add(0, new Object[]{type,  seq} );\r
228     updateEditMenuBar();\r
229   }\r
230 \r
231   protected void undoMenuItem_actionPerformed(ActionEvent e)\r
232   {\r
233     Object [] history = (Object[])historyList.remove(0);\r
234     // add the redo state before continuing!!\r
235     SequenceI[] seq = new SequenceI[viewport.getAlignment().getHeight()];\r
236     for (int i = 0; i < viewport.getAlignment().getHeight(); i++)\r
237     {\r
238       seq[i] = new Sequence(viewport.getAlignment().getSequenceAt(i).getName(),\r
239                             viewport.getAlignment().getSequenceAt(i).\r
240                             getSequence());\r
241     }\r
242     /////////\r
243 \r
244     redoList.add(0, new Object[] {history[0], seq});\r
245 \r
246       seq = (SequenceI[]) history[1];\r
247       viewport.setAlignment( new Alignment(seq) );\r
248       updateEditMenuBar();\r
249       viewport.updateConsensus();\r
250       alignPanel.repaint();\r
251   }\r
252 \r
253   public void moveSelectedSequences(boolean up)\r
254   {\r
255     SequenceGroup sg = viewport.getSelectionGroup();\r
256     if (sg == null)\r
257       return;\r
258 \r
259     if (up)\r
260     {\r
261       for (int i = 1; i < viewport.alignment.getHeight(); i++)\r
262       {\r
263         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
264         if (!sg.sequences.contains(seq))\r
265           continue;\r
266 \r
267         SequenceI temp = viewport.alignment.getSequenceAt(i - 1);\r
268         if (sg.sequences.contains(temp))\r
269           continue;\r
270 \r
271         viewport.alignment.getSequences().setElementAt(temp, i);\r
272         viewport.alignment.getSequences().setElementAt(seq, i - 1);\r
273       }\r
274     }\r
275     else\r
276     {\r
277       for (int i = viewport.alignment.getHeight() - 2; i > -1; i--)\r
278       {\r
279         SequenceI seq = viewport.alignment.getSequenceAt(i);\r
280         if (!sg.sequences.contains(seq))\r
281           continue;\r
282 \r
283         SequenceI temp = viewport.alignment.getSequenceAt(i + 1);\r
284         if (sg.sequences.contains(temp))\r
285           continue;\r
286 \r
287         viewport.alignment.getSequences().setElementAt(temp, i);\r
288         viewport.alignment.getSequences().setElementAt(seq, i + 1);\r
289       }\r
290     }\r
291 \r
292     alignPanel.repaint();\r
293   }\r
294 \r
295 \r
296 \r
297   protected void copy_actionPerformed(ActionEvent e)\r
298   {\r
299    if(viewport.getSelectionGroup()==null)\r
300      return;\r
301 \r
302    SequenceGroup sg = viewport.getSelectionGroup();\r
303 \r
304      Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
305      StringBuffer buffer= new StringBuffer();\r
306 \r
307        for(int i=0; i<sg.getSize(); i++)\r
308        {\r
309          SequenceI seq = sg.getSequenceAt(i);\r
310          buffer.append( seq.getName()+"\t"+seq.findPosition( sg.getStartRes() ) +"\t"\r
311                         +seq.findPosition( sg.getEndRes() )+ "\t"\r
312                         +sg.getSequenceAt(i).getSequence(sg.getStartRes(), sg.getEndRes()+1)+"\n");\r
313        }\r
314      c.setContents( new StringSelection( buffer.toString()) , null ) ;\r
315 \r
316   }\r
317 \r
318 \r
319   protected void pasteNew_actionPerformed(ActionEvent e)\r
320   {\r
321     paste(true);\r
322   }\r
323 \r
324   protected void pasteThis_actionPerformed(ActionEvent e)\r
325   {\r
326     addHistoryItem("Paste");\r
327     paste(false);\r
328   }\r
329 \r
330   void paste(boolean newAlignment)\r
331   {\r
332     try{\r
333       Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();\r
334       Transferable contents = c.getContents(this);\r
335       if (contents == null)\r
336         return;\r
337 \r
338       String str = (String) contents.getTransferData(DataFlavor.stringFlavor);\r
339       StringTokenizer st = new StringTokenizer(str);\r
340       ArrayList seqs = new ArrayList();\r
341       while (st.hasMoreElements())\r
342       {\r
343         String name = st.nextToken();\r
344         int start = Integer.parseInt(st.nextToken());\r
345         int end = Integer.parseInt(st.nextToken());\r
346         Sequence sequence = new Sequence(name,st.nextToken(), start, end);\r
347 \r
348         if(!newAlignment)\r
349           viewport.alignment.addSequence(sequence);\r
350         else\r
351           seqs.add(sequence);\r
352       }\r
353 \r
354       if(newAlignment)\r
355       {\r
356         SequenceI[] newSeqs = new SequenceI[seqs.size()];\r
357         seqs.toArray(newSeqs);\r
358         AlignFrame af = new AlignFrame(new Alignment(newSeqs));\r
359         Desktop.addInternalFrame(af, "Copied sequences", NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
360       }\r
361       else\r
362       {\r
363         viewport.setEndSeq(viewport.alignment.getHeight());\r
364         viewport.alignment.getWidth();\r
365         viewport.updateConservation();\r
366         viewport.updateConsensus();\r
367         alignPanel.repaint();\r
368       }\r
369 \r
370     }catch(Exception ex){}// could be anything being pasted in here\r
371 \r
372   }\r
373 \r
374 \r
375   protected void cut_actionPerformed(ActionEvent e)\r
376   {\r
377     copy_actionPerformed(null);\r
378     delete_actionPerformed(null);\r
379   }\r
380 \r
381   protected void delete_actionPerformed(ActionEvent e)\r
382   {\r
383     addHistoryItem("Delete");\r
384     if (viewport.getSelectionGroup() == null)\r
385       return;\r
386 \r
387      SequenceGroup sg = viewport.getSelectionGroup();\r
388      for (int i=0;i < sg.sequences.size(); i++)\r
389      {\r
390        SequenceI seq = sg.getSequenceAt(i);\r
391        int index = viewport.getAlignment().findIndex(seq);\r
392        seq.deleteChars(sg.getStartRes(), sg.getEndRes()+1);\r
393 \r
394        if(seq.getSequence().length()<1)\r
395           viewport.getAlignment().deleteSequence(seq);\r
396       else\r
397           viewport.getAlignment().getSequences().setElementAt(seq, index);\r
398      }\r
399 \r
400      viewport.setSelectionGroup(null);\r
401      viewport.alignment.deleteGroup(sg);\r
402      viewport.resetSeqLimits( alignPanel.seqPanel.seqCanvas.getHeight());\r
403      if(viewport.getAlignment().getHeight()<1)\r
404      try\r
405      {\r
406        this.setClosed(true);\r
407      }catch(Exception ex){}\r
408    viewport.updateConservation();\r
409    viewport.updateConsensus();\r
410      alignPanel.repaint();\r
411 \r
412   }\r
413 \r
414 \r
415 \r
416   protected void redoMenuItem_actionPerformed(ActionEvent e)\r
417   {\r
418      Object [] history = (Object[])redoList.remove(0);\r
419      SequenceI[] seq = (SequenceI[]) history[1];\r
420      viewport.setAlignment( new Alignment(seq) );\r
421      updateEditMenuBar();\r
422      viewport.updateConsensus();\r
423      alignPanel.repaint();\r
424      alignPanel.repaint();\r
425   }\r
426 \r
427 \r
428   protected void deleteGroups_actionPerformed(ActionEvent e)\r
429   {\r
430     viewport.alignment.deleteAllGroups();\r
431     viewport.setSelectionGroup(null);\r
432 \r
433     alignPanel.repaint();\r
434   }\r
435 \r
436 \r
437 \r
438   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
439   {\r
440     SequenceGroup sg = new SequenceGroup();\r
441     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
442       sg.addSequence( viewport.getAlignment().getSequenceAt(i));\r
443     sg.setEndRes(viewport.alignment.getWidth());\r
444     viewport.setSelectionGroup(sg);\r
445     PaintRefresher.Refresh(null);\r
446   }\r
447 \r
448   public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)\r
449   {\r
450     viewport.setSelectionGroup(null);\r
451     PaintRefresher.Refresh(null);\r
452   }\r
453 \r
454   public void invertSequenceMenuItem_actionPerformed(ActionEvent e)\r
455   {\r
456     SequenceGroup sg = viewport.getSelectionGroup();\r
457     for (int i=0; i<viewport.getAlignment().getSequences().size(); i++)\r
458       sg.addOrRemove (viewport.getAlignment().getSequenceAt(i));\r
459 \r
460     PaintRefresher.Refresh(null);\r
461   }\r
462 \r
463 \r
464   public void deselectAllColumnsMenuItem_actionPerformed(ActionEvent e)\r
465   {\r
466     viewport.getColumnSelection().clear();\r
467     repaint();\r
468   }\r
469 \r
470   public void remove2LeftMenuItem_actionPerformed(ActionEvent e)\r
471   {\r
472     addHistoryItem("delete columns");\r
473     ColumnSelection colSel = viewport.getColumnSelection();\r
474     if (colSel.size() > 0)\r
475     {\r
476       int min = colSel.getMin();\r
477       viewport.getAlignment().trimLeft(min);\r
478       colSel.compensateForEdit(0,min);\r
479 \r
480       if(viewport.getSelectionGroup()!=null)\r
481         viewport.getSelectionGroup().adjustForRemoveLeft(min);\r
482 \r
483       Vector groups = viewport.alignment.getGroups();\r
484       for(int i=0; i<groups.size(); i++)\r
485       {\r
486         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
487         if(!sg.adjustForRemoveLeft(min))\r
488           viewport.alignment.deleteGroup(sg);\r
489       }\r
490 \r
491       alignPanel.repaint();\r
492     }\r
493   }\r
494 \r
495   public void remove2RightMenuItem_actionPerformed(ActionEvent e)\r
496   {\r
497     addHistoryItem("delete columns");\r
498     ColumnSelection colSel = viewport.getColumnSelection();\r
499     if (colSel.size() > 0)\r
500     {\r
501       int max = colSel.getMax();\r
502       viewport.getAlignment().trimRight(max);\r
503       if(viewport.getSelectionGroup()!=null)\r
504         viewport.getSelectionGroup().adjustForRemoveRight(max);\r
505 \r
506       Vector groups = viewport.alignment.getGroups();\r
507       for(int i=0; i<groups.size(); i++)\r
508       {\r
509         SequenceGroup sg = (SequenceGroup) groups.get(i);\r
510         if(!sg.adjustForRemoveRight(max))\r
511           viewport.alignment.deleteGroup(sg);\r
512       }\r
513 \r
514 \r
515 \r
516       alignPanel.repaint();\r
517     }\r
518 \r
519   }\r
520 \r
521   public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)\r
522   {\r
523     addHistoryItem("delete gapped columns");\r
524     viewport.getAlignment().removeGaps();\r
525     viewport.updateConservation();\r
526     viewport.updateConsensus();\r
527     alignPanel.repaint();\r
528   }\r
529 \r
530   public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)\r
531   {\r
532     addHistoryItem("delete all gaps");\r
533     SequenceI current;\r
534     int jSize;\r
535     for (int i=0; i < viewport.getAlignment().getSequences().size();i++)\r
536     {\r
537       current = viewport.getAlignment().getSequenceAt(i);\r
538       jSize = current.getLength();\r
539       for (int j=0; j < jSize; j++)\r
540         if(jalview.util.Comparison.isGap(current.getCharAt(j)))\r
541         {\r
542           current.deleteCharAt(j);\r
543           j--;\r
544           jSize--;\r
545         }\r
546     }\r
547     viewport.updateConservation();\r
548     viewport.updateConsensus();\r
549     alignPanel.repaint();\r
550   }\r
551 \r
552   public void setGapCharMenuItem_actionPerformed(ActionEvent e)\r
553   {\r
554     char thisChar = '-';\r
555     char nextChar = '.';\r
556     if(viewport.getGapCharacter()=='-')\r
557     {\r
558       thisChar = '.';\r
559       nextChar = '-';\r
560     }\r
561     setGapCharMenuItem.setText("Set gap character to \""+nextChar+"\"");\r
562     viewport.setGapCharacter(thisChar);\r
563     alignPanel.repaint();\r
564   }\r
565 \r
566   public void findMenuItem_actionPerformed(ActionEvent e)\r
567   {\r
568     JInternalFrame frame = new JInternalFrame();\r
569     Finder finder = new Finder(viewport, alignPanel, frame);\r
570     frame.setContentPane(finder);\r
571     Desktop.addInternalFrame(frame, "Find", 340,110, false);\r
572     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
573 \r
574   }\r
575 \r
576 \r
577   public void font_actionPerformed(ActionEvent e)\r
578   {\r
579     JInternalFrame frame = new JInternalFrame();\r
580     FontChooser fc = new FontChooser( alignPanel, frame );\r
581     frame.setContentPane(fc);\r
582     Desktop.addInternalFrame(frame, "Change Font", 480,100, false);\r
583     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
584     if(alignPanel.getOverviewPanel()!=null)\r
585       alignPanel.getOverviewPanel().updateOverviewImage();\r
586   }\r
587 \r
588   protected void fullSeqId_actionPerformed(ActionEvent e)\r
589   {\r
590     viewport.setShowFullId( fullSeqId.isSelected() );\r
591 \r
592     alignPanel.idPanel.idCanvas.setPreferredSize( alignPanel.calculateIdWidth() );\r
593     alignPanel.repaint();\r
594   }\r
595 \r
596   protected void colourTextMenuItem_actionPerformed(ActionEvent e)\r
597   {\r
598       viewport.setColourText( colourTextMenuItem.isSelected() );\r
599       alignPanel.repaint();\r
600   }\r
601 \r
602   protected void wrapMenuItem_actionPerformed(ActionEvent e)\r
603   {\r
604     viewport.setWrapAlignment( wrapMenuItem.isSelected() );\r
605     alignPanel.setWrapAlignment( wrapMenuItem.isSelected() );\r
606     scaleAbove.setVisible( wrapMenuItem.isSelected() );\r
607     scaleLeft.setVisible( wrapMenuItem.isSelected() );\r
608     scaleRight.setVisible( wrapMenuItem.isSelected() );\r
609     alignPanel.repaint();\r
610   }\r
611 \r
612   protected void scaleAbove_actionPerformed(ActionEvent e)\r
613   {\r
614     viewport.setScaleAboveWrapped(scaleAbove.isSelected());\r
615     alignPanel.repaint();\r
616   }\r
617 \r
618   protected void scaleLeft_actionPerformed(ActionEvent e)\r
619   {\r
620     viewport.setScaleLeftWrapped(scaleLeft.isSelected());\r
621     alignPanel.repaint();\r
622   }\r
623 \r
624   protected void scaleRight_actionPerformed(ActionEvent e)\r
625   {\r
626     viewport.setScaleRightWrapped(scaleRight.isSelected());\r
627     alignPanel.repaint();\r
628   }\r
629 \r
630 \r
631 \r
632   public void viewBoxesMenuItem_actionPerformed(ActionEvent e)\r
633   {\r
634     viewport.setShowBoxes( viewBoxesMenuItem.isSelected() );\r
635     alignPanel.repaint();\r
636   }\r
637 \r
638   public void viewTextMenuItem_actionPerformed(ActionEvent e)\r
639   {\r
640     viewport.setShowText( viewTextMenuItem.isSelected() );\r
641     alignPanel.repaint();\r
642   }\r
643 \r
644 \r
645   protected void renderGapsMenuItem_actionPerformed(ActionEvent e)\r
646   {\r
647     viewport.setRenderGaps(renderGapsMenuItem.isSelected());\r
648     alignPanel.repaint();\r
649   }\r
650 \r
651   public void sequenceFeatures_actionPerformed(ActionEvent evt)\r
652   {\r
653     viewport.showSequenceFeatures(sequenceFeatures.isSelected());\r
654     if(viewport.showSequenceFeatures && !((Alignment)viewport.alignment).featuresAdded)\r
655     {\r
656          AlignmentUtil.fetchSequenceFeatures( viewport.alignment , alignPanel);\r
657          ((Alignment)viewport.alignment).featuresAdded = true;\r
658     }\r
659     alignPanel.repaint();\r
660   }\r
661 \r
662   public void annotationPanelMenuItem_actionPerformed(ActionEvent e)\r
663   {\r
664     if(annotationPanelMenuItem.isSelected() && viewport.getWrapAlignment())\r
665     {\r
666       annotationPanelMenuItem.setSelected(false);\r
667       return;\r
668     }\r
669     viewport.setShowAnnotation( annotationPanelMenuItem.isSelected() );\r
670     alignPanel.setAnnotationVisible( annotationPanelMenuItem.isSelected() );\r
671   }\r
672 \r
673   public void overviewMenuItem_actionPerformed(ActionEvent e)\r
674   {\r
675     if (alignPanel.overviewPanel != null)\r
676       return;\r
677 \r
678     JInternalFrame frame = new JInternalFrame();\r
679     OverviewPanel overview = new OverviewPanel(alignPanel);\r
680      frame.setContentPane(overview);\r
681     Desktop.addInternalFrame(frame, "Overview " + this.getTitle(),\r
682                              frame.getWidth(), frame.getHeight());\r
683     frame.pack();\r
684     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
685     frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
686     { public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
687       {\r
688             alignPanel.setOverviewPanel(null);\r
689       };\r
690     });\r
691 \r
692     alignPanel.setOverviewPanel( overview );\r
693 \r
694 \r
695   }\r
696 \r
697   protected void noColourmenuItem_actionPerformed(ActionEvent e)\r
698   {\r
699     changeColour( null );\r
700   }\r
701 \r
702 \r
703   public void clustalColour_actionPerformed(ActionEvent e)\r
704   {\r
705     abovePIDThreshold.setSelected(false);\r
706     changeColour(new ClustalxColourScheme(viewport.alignment.getSequences(), viewport.alignment.getWidth()));\r
707   }\r
708 \r
709   public void zappoColour_actionPerformed(ActionEvent e)\r
710   {\r
711     changeColour(new ZappoColourScheme());\r
712   }\r
713 \r
714   public void taylorColour_actionPerformed(ActionEvent e)\r
715   {\r
716     changeColour(new TaylorColourScheme());\r
717   }\r
718 \r
719 \r
720   public void hydrophobicityColour_actionPerformed(ActionEvent e)\r
721   {\r
722     changeColour( new HydrophobicColourScheme() );\r
723   }\r
724 \r
725   public void helixColour_actionPerformed(ActionEvent e)\r
726   {\r
727     changeColour(new HelixColourScheme() );\r
728   }\r
729 \r
730 \r
731   public void strandColour_actionPerformed(ActionEvent e)\r
732   {\r
733     changeColour(new StrandColourScheme());\r
734   }\r
735 \r
736 \r
737   public void turnColour_actionPerformed(ActionEvent e)\r
738   {\r
739     changeColour(new TurnColourScheme());\r
740   }\r
741 \r
742 \r
743   public void buriedColour_actionPerformed(ActionEvent e)\r
744   {\r
745     changeColour(new BuriedColourScheme() );\r
746   }\r
747 \r
748   public void nucleotideColour_actionPerformed(ActionEvent e)\r
749   {\r
750     changeColour(new NucleotideColourScheme());\r
751   }\r
752 \r
753 \r
754   protected void applyToAllGroups_actionPerformed(ActionEvent e)\r
755   {\r
756     viewport.setColourAppliesToAllGroups(applyToAllGroups.isSelected());\r
757   }\r
758 \r
759 \r
760 \r
761   void changeColour(ColourSchemeI cs)\r
762   {\r
763     int threshold = 0;\r
764 \r
765     if ( viewport.getAbovePIDThreshold() )\r
766     {\r
767       threshold = SliderPanel.setPIDSliderSource(alignPanel, cs, "Background");\r
768 \r
769       if (cs instanceof ResidueColourScheme)\r
770         ( (ResidueColourScheme) cs).setThreshold(threshold);\r
771       else if (cs instanceof ScoreColourScheme)\r
772         ( (ScoreColourScheme) cs).setThreshold(threshold);\r
773 \r
774       viewport.setGlobalColourScheme(cs);\r
775     }\r
776     else if (cs instanceof ResidueColourScheme)\r
777       ( (ResidueColourScheme) cs).setThreshold(0);\r
778     else if (cs instanceof ScoreColourScheme)\r
779       ( (ScoreColourScheme) cs).setThreshold(0);\r
780 \r
781 \r
782 \r
783     if (viewport.getConservationSelected())\r
784     {\r
785       ConservationColourScheme ccs = null;\r
786 \r
787       Alignment al = (Alignment) viewport.alignment;\r
788       Conservation c = new Conservation("All",\r
789                                         ResidueProperties.propHash, 3,\r
790                                         al.getSequences(), 0,\r
791                                         al.getWidth() - 1);\r
792 \r
793       c.calculate();\r
794       c.verdict(false, viewport.ConsPercGaps);\r
795 \r
796       ccs = new ConservationColourScheme(c, cs);\r
797 \r
798       // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
799       ccs.setConsensus( viewport.vconsensus );\r
800       viewport.setGlobalColourScheme(ccs);\r
801 \r
802       SliderPanel.setConservationSlider(alignPanel, ccs, "Background");\r
803 \r
804     }\r
805     else\r
806     {\r
807         // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
808         if (cs != null)\r
809           cs.setConsensus(viewport.vconsensus);\r
810         viewport.setGlobalColourScheme(cs);\r
811     }\r
812 \r
813 \r
814     if(viewport.getColourAppliesToAllGroups())\r
815     {\r
816       Vector groups = viewport.alignment.getGroups();\r
817       for(int i=0; i<groups.size(); i++)\r
818       {\r
819         SequenceGroup sg = (SequenceGroup)groups.elementAt(i);\r
820 \r
821         if (cs instanceof ClustalxColourScheme)\r
822         {\r
823           sg.cs = new ClustalxColourScheme(sg.sequences, sg.getWidth());\r
824         }\r
825         else\r
826           try\r
827           {\r
828             sg.cs = (ColourSchemeI) cs.getClass().newInstance();\r
829           }\r
830           catch (Exception ex)\r
831           {\r
832             ex.printStackTrace();\r
833             sg.cs = cs;\r
834           }\r
835 \r
836         if(viewport.getAbovePIDThreshold())\r
837         {\r
838           if (sg.cs instanceof ResidueColourScheme)\r
839             ( (ResidueColourScheme) sg.cs).setThreshold(threshold);\r
840           else if (sg.cs instanceof ScoreColourScheme)\r
841             ( (ScoreColourScheme) sg.cs).setThreshold(threshold);\r
842 \r
843            sg.cs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()) );\r
844         }\r
845 \r
846         if( viewport.getConservationSelected() )\r
847         {\r
848           Conservation c = new Conservation("Group",\r
849                                             ResidueProperties.propHash, 3,\r
850                                             sg.sequences, 0, viewport.alignment.getWidth()-1);\r
851           c.calculate();\r
852           c.verdict(false, viewport.ConsPercGaps);\r
853           ConservationColourScheme ccs = new ConservationColourScheme(c, sg.cs);\r
854 \r
855           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
856           ccs.setConsensus( AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
857           sg.cs = ccs;\r
858         }\r
859         else\r
860         {\r
861           // MUST NOTIFY THE COLOURSCHEME OF CONSENSUS!\r
862           sg.cs.setConsensus(AAFrequency.calculate(sg.sequences, 0, sg.getWidth()));\r
863         }\r
864 \r
865       }\r
866     }\r
867 \r
868     if(alignPanel.getOverviewPanel()!=null)\r
869       alignPanel.getOverviewPanel().updateOverviewImage();\r
870     alignPanel.repaint();\r
871   }\r
872 \r
873   protected void modifyPID_actionPerformed(ActionEvent e)\r
874   {\r
875       if(viewport.getAbovePIDThreshold())\r
876       {\r
877         SliderPanel.setPIDSliderSource(alignPanel, viewport.getGlobalColourScheme(),\r
878                                    "Background");\r
879         SliderPanel.showPIDSlider();\r
880       }\r
881   }\r
882 \r
883   protected void modifyConservation_actionPerformed(ActionEvent e)\r
884   {\r
885     if(viewport.getConservationSelected())\r
886     {\r
887       SliderPanel.setConservationSlider(alignPanel, viewport.globalColourScheme,\r
888                                         "Background");\r
889       SliderPanel.showConservationSlider();\r
890     }\r
891   }\r
892 \r
893 \r
894   protected  void conservationMenuItem_actionPerformed(ActionEvent e)\r
895   {\r
896     viewport.setConservationSelected(conservationMenuItem.isSelected());\r
897 \r
898     viewport.setAbovePIDThreshold(false);\r
899     abovePIDThreshold.setSelected(false);\r
900 \r
901    ColourSchemeI cs = viewport.getGlobalColourScheme();\r
902    if(cs instanceof ConservationColourScheme )\r
903      changeColour( ((ConservationColourScheme)cs).cs );\r
904     else\r
905       changeColour( cs );\r
906 \r
907     modifyConservation_actionPerformed(null);\r
908   }\r
909 \r
910   public void abovePIDThreshold_actionPerformed(ActionEvent e)\r
911   {\r
912     viewport.setAbovePIDThreshold(abovePIDThreshold.isSelected());\r
913 \r
914     conservationMenuItem.setSelected(false);\r
915     viewport.setConservationSelected(false);\r
916 \r
917     ColourSchemeI cs = viewport.getGlobalColourScheme();\r
918 \r
919     if(cs instanceof ConservationColourScheme )\r
920         changeColour( ((ConservationColourScheme)cs).cs );\r
921     else\r
922         changeColour( cs );\r
923 \r
924     modifyPID_actionPerformed(null);\r
925   }\r
926 \r
927 \r
928 \r
929   public void userDefinedColour_actionPerformed(ActionEvent e)\r
930   {\r
931     JInternalFrame frame = new JInternalFrame();\r
932     UserDefinedColours chooser = new UserDefinedColours( frame, alignPanel, null);\r
933     frame.setContentPane(chooser);\r
934     Desktop.addInternalFrame(frame,"User defined colours", 450,540, false );\r
935   }\r
936 \r
937   public void PIDColour_actionPerformed(ActionEvent e)\r
938   {\r
939     changeColour( new PIDColourScheme() );\r
940   }\r
941 \r
942 \r
943   public void BLOSUM62Colour_actionPerformed(ActionEvent e)\r
944   {\r
945     changeColour(new Blosum62ColourScheme() );\r
946   }\r
947 \r
948 \r
949 \r
950   public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)\r
951   {\r
952     addHistoryItem("sort");\r
953     AlignmentSorter.sortByPID(viewport.getAlignment(), viewport.getAlignment().getSequenceAt(0));\r
954     alignPanel.repaint();\r
955   }\r
956 \r
957   public void sortIDMenuItem_actionPerformed(ActionEvent e)\r
958   {\r
959     addHistoryItem("sort");\r
960     AlignmentSorter.sortByID( viewport.getAlignment() );\r
961     alignPanel.repaint();\r
962   }\r
963 \r
964   public void sortGroupMenuItem_actionPerformed(ActionEvent e)\r
965   {\r
966     addHistoryItem("sort");\r
967     AlignmentSorter.sortByGroup(viewport.getAlignment());\r
968     AlignmentSorter.sortGroups(viewport.getAlignment());\r
969     alignPanel.repaint();\r
970   }\r
971 \r
972   public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)\r
973   {\r
974     RedundancyPanel sp = new RedundancyPanel(alignPanel);\r
975     JInternalFrame frame = new JInternalFrame();\r
976     frame.setContentPane(sp);\r
977     Desktop.addInternalFrame(frame, "Redundancy threshold selection", 400, 100, false);\r
978 \r
979   }\r
980 \r
981   public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)\r
982   {\r
983     if(viewport.getSelectionGroup().getSize()<2)\r
984       JOptionPane.showInternalMessageDialog(this, "You must select at least 2 sequences.", "Invalid Selection", JOptionPane.WARNING_MESSAGE);\r
985     else\r
986     {\r
987       JInternalFrame frame = new JInternalFrame();\r
988       frame.setContentPane(new PairwiseAlignPanel(viewport));\r
989       Desktop.addInternalFrame(frame, "Pairwise Alignment", 600, 500);\r
990     }\r
991   }\r
992 \r
993   public void PCAMenuItem_actionPerformed(ActionEvent e)\r
994   {\r
995 \r
996     if( (viewport.getSelectionGroup()!=null && viewport.getSelectionGroup().getSize()<4 && viewport.getSelectionGroup().getSize()>0)\r
997        || viewport.getAlignment().getHeight()<4)\r
998     {\r
999       JOptionPane.showInternalMessageDialog(this, "Principal component analysis must take\n"\r
1000                                     +"at least 4 input sequences.",\r
1001                                     "Sequence selection insufficient",\r
1002                                     JOptionPane.WARNING_MESSAGE);\r
1003       return;\r
1004     }\r
1005 \r
1006     try{\r
1007       PCAPanel pcaPanel = new PCAPanel(viewport, null);\r
1008       JInternalFrame frame = new JInternalFrame();\r
1009       frame.setContentPane(pcaPanel);\r
1010       Desktop.addInternalFrame(frame, "Principal component analysis", 400, 400);\r
1011    }catch(java.lang.OutOfMemoryError ex)\r
1012    {\r
1013      JOptionPane.showInternalMessageDialog(this, "Too many sequences selected\nfor Principal Component Analysis!!",\r
1014                                    "Out of memory", JOptionPane.WARNING_MESSAGE);\r
1015    }\r
1016 \r
1017 \r
1018   }\r
1019 \r
1020   public void averageDistanceTreeMenuItem_actionPerformed(ActionEvent e)\r
1021   {\r
1022     NewTreePanel("AV", "PID", "Average distance tree using PID");\r
1023   }\r
1024 \r
1025   public void neighbourTreeMenuItem_actionPerformed(ActionEvent e)\r
1026   {\r
1027     NewTreePanel("NJ", "PID", "Neighbour joining tree using PID");\r
1028   }\r
1029 \r
1030 \r
1031   protected void njTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1032   {\r
1033     NewTreePanel("NJ", "BL", "Neighbour joining tree using BLOSUM62");\r
1034   }\r
1035 \r
1036   protected void avTreeBlosumMenuItem_actionPerformed(ActionEvent e)\r
1037   {\r
1038     NewTreePanel("AV", "BL", "Average distance tree using BLOSUM62PID");\r
1039   }\r
1040 \r
1041   void NewTreePanel(String type, String pwType, String title)\r
1042   {\r
1043     //are the sequences aligned?\r
1044     if(!viewport.alignment.isAligned())\r
1045     {\r
1046       JOptionPane.showMessageDialog(Desktop.desktop, "The sequences must be aligned before creating a tree.",\r
1047                                     "Sequences not aligned", JOptionPane.WARNING_MESSAGE);\r
1048       return;\r
1049     }\r
1050 \r
1051     final TreePanel tp;\r
1052     if (viewport.getSelectionGroup() != null &&\r
1053         viewport.getSelectionGroup().getSize() > 3)\r
1054     {\r
1055       tp = new TreePanel(viewport, viewport.getSelectionGroup().sequences, type,\r
1056                          pwType,\r
1057                          0, viewport.alignment.getWidth());\r
1058     }\r
1059     else\r
1060     {\r
1061       tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1062                          type, pwType, 0, viewport.alignment.getWidth());\r
1063     }\r
1064 \r
1065    addTreeMenuItem(tp, title);\r
1066 \r
1067    Desktop.addInternalFrame(tp, title, 600, 500);\r
1068   }\r
1069 \r
1070   void addTreeMenuItem(final TreePanel treePanel, String title)\r
1071   {\r
1072     final JMenuItem item = new JMenuItem(title);\r
1073     sortByTreeMenu.add(item);\r
1074     item.addActionListener(new java.awt.event.ActionListener()\r
1075     {\r
1076       public void actionPerformed(ActionEvent e)\r
1077       {\r
1078         addHistoryItem("sort");\r
1079         AlignmentSorter.sortByTree(viewport.getAlignment(), treePanel.getTree());\r
1080         alignPanel.repaint();\r
1081       }\r
1082     });\r
1083 \r
1084     treePanel.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()\r
1085     {\r
1086       public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt)\r
1087       {\r
1088         sortByTreeMenu.remove(item);\r
1089       };\r
1090     });\r
1091 \r
1092   }\r
1093 \r
1094 \r
1095   public void clustalAlignMenuItem_actionPerformed(ActionEvent e)\r
1096   {\r
1097      WebserviceInfo info = new WebserviceInfo("Clustal web service",\r
1098      "\"Thompson, J.D., Higgins, D.G. and Gibson, T.J. (1994) CLUSTAL W: improving the sensitivity of progressive multiple"+\r
1099      " sequence alignment through sequence weighting, position specific gap penalties and weight matrix choice."\r
1100     +" Nucleic Acids Research, submitted, June 1994.",\r
1101      450, 150);\r
1102 \r
1103     ClustalThread thread = new ClustalThread(info);\r
1104     thread.start();\r
1105   }\r
1106 \r
1107     class ClustalThread extends Thread\r
1108     {\r
1109       WebserviceInfo info;\r
1110       public ClustalThread(WebserviceInfo info)\r
1111       {this.info = info; }\r
1112 \r
1113       public void run()\r
1114       {\r
1115         info.setStatus(WebserviceInfo.STATE_RUNNING);\r
1116         jalview.ws.Jemboss jemboss = new jalview.ws.Jemboss();\r
1117         Vector sv = viewport.getAlignment().getSequences();\r
1118         SequenceI[] seqs = new SequenceI[sv.size()];\r
1119 \r
1120         int i = 0;\r
1121         do\r
1122         {\r
1123           seqs[i] = (SequenceI) sv.elementAt(i);\r
1124         }\r
1125         while (++i < sv.size());\r
1126 \r
1127         SequenceI[] alignment = jemboss.clustalW(seqs); // gaps removed within method\r
1128         if (alignment != null)\r
1129         {\r
1130           AlignFrame af = new AlignFrame(new Alignment(alignment));\r
1131           Desktop.addInternalFrame(af, title.concat(" - ClustalW Alignment"),\r
1132                                    NEW_WINDOW_WIDTH, NEW_WINDOW_HEIGHT);\r
1133           af.clustalColour_actionPerformed(null);\r
1134           af.clustalColour.setSelected(true);\r
1135           info.setStatus(WebserviceInfo.STATE_STOPPED_OK);\r
1136         }\r
1137         else\r
1138         {\r
1139             info.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);\r
1140             info.appendProgressText("Problem obtaining clustal alignment");\r
1141         }\r
1142       }\r
1143     }\r
1144 \r
1145   protected void jpred_actionPerformed(ActionEvent e)\r
1146 {\r
1147 \r
1148     if (viewport.getSelectionGroup() != null && viewport.getSelectionGroup().getSize()>0)\r
1149     {\r
1150       // JBPNote UGLY! To prettify, make SequenceGroup and Alignment conform to some common interface!\r
1151       SequenceGroup seqs = viewport.getSelectionGroup();\r
1152       if (seqs.getSize() == 1 || !viewport.alignment.isAligned())\r
1153       {\r
1154         JPredClient ct = new JPredClient( (SequenceI)seqs.getSequenceAt(0));\r
1155       }\r
1156       else\r
1157       {\r
1158         int sz;\r
1159         SequenceI[] msa = new SequenceI[sz=seqs.getSize()];\r
1160         for (int i = 0; i < sz; i++)\r
1161         {\r
1162           msa[i] = (SequenceI) seqs.getSequenceAt(i);\r
1163         }\r
1164 \r
1165         JPredClient ct = new JPredClient(msa);\r
1166       }\r
1167 \r
1168     }\r
1169     else\r
1170     {\r
1171       Vector seqs = viewport.getAlignment().getSequences();\r
1172 \r
1173       if (seqs.size() == 1 || !viewport.alignment.isAligned())\r
1174       {\r
1175         JPredClient ct = new JPredClient( (SequenceI)\r
1176                                          seqs.elementAt(0));\r
1177       }\r
1178       else\r
1179       {\r
1180         SequenceI[] msa = new SequenceI[seqs.size()];\r
1181         for (int i = 0; i < seqs.size(); i++)\r
1182         {\r
1183           msa[i] = (SequenceI) seqs.elementAt(i);\r
1184         }\r
1185 \r
1186         JPredClient ct = new JPredClient(msa);\r
1187       }\r
1188 \r
1189     }\r
1190   }\r
1191 \r
1192     protected void LoadtreeMenuItem_actionPerformed(ActionEvent e) {\r
1193     // Pick the tree file\r
1194     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
1195         getProperty("LAST_DIRECTORY"));\r
1196     chooser.setFileView(new JalviewFileView());\r
1197     chooser.setDialogTitle("Select a newick-like tree file");\r
1198     chooser.setToolTipText("Load a tree file");\r
1199     int value = chooser.showOpenDialog(null);\r
1200     if (value == JalviewFileChooser.APPROVE_OPTION)\r
1201     {\r
1202       String choice = chooser.getSelectedFile().getPath();\r
1203       jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
1204       TreePanel treepanel = null;\r
1205       try\r
1206       {\r
1207         jalview.io.NewickFile fin = new jalview.io.NewickFile(choice, "File");\r
1208         fin.parse();\r
1209 \r
1210         if (fin.getTree() != null)\r
1211         {\r
1212           TreePanel tp = null;\r
1213           tp = new TreePanel(viewport, viewport.getAlignment().getSequences(),\r
1214                              fin, "FromFile", choice);\r
1215           Desktop.addInternalFrame(tp, title, 600, 500);\r
1216           addTreeMenuItem(tp, title);\r
1217         }\r
1218       }\r
1219       catch (Exception ex)\r
1220       {\r
1221         JOptionPane.showMessageDialog(Desktop.desktop,\r
1222                                       "Problem reading tree file",\r
1223                                       ex.getMessage(),\r
1224                                       JOptionPane.WARNING_MESSAGE);\r
1225         ex.printStackTrace();\r
1226       }\r
1227     }\r
1228   }\r
1229 \r
1230 }\r