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