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