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