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