1c70c240b08b0d2f4a3810594e226dd400429b4d
[jalview.git] / src / jalview / gui / TreePanel.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 package jalview.gui;\r
20 \r
21 import jalview.analysis.*;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 import jalview.io.*;\r
26 \r
27 import jalview.jbgui.*;\r
28 \r
29 \r
30 import java.awt.*;\r
31 import java.awt.event.*;\r
32 \r
33 import java.io.*;\r
34 \r
35 import java.util.*;\r
36 \r
37 import java.beans.PropertyChangeEvent;\r
38 \r
39 \r
40 /**\r
41  * DOCUMENT ME!\r
42  *\r
43  * @author $author$\r
44  * @version $Revision$\r
45  */\r
46 public class TreePanel extends GTreePanel\r
47 {\r
48     SequenceI[] seq;\r
49     String type;\r
50     String pwtype;\r
51     int start;\r
52     int end;\r
53     TreeCanvas treeCanvas;\r
54     NJTree tree;\r
55 \r
56     /**\r
57      * Creates a new TreePanel object.\r
58      *\r
59      * @param av DOCUMENT ME!\r
60      * @param seqVector DOCUMENT ME!\r
61      * @param type DOCUMENT ME!\r
62      * @param pwtype DOCUMENT ME!\r
63      * @param s DOCUMENT ME!\r
64      * @param e DOCUMENT ME!\r
65      */\r
66     public TreePanel(AlignViewport av, Vector seqVector, String type,\r
67                      String pwtype, int s, int e)\r
68     {\r
69       super();\r
70       initTreePanel(av, seqVector, type, pwtype, s, e, null);\r
71 \r
72       // We know this tree has distances. JBPNote TODO: prolly should add this as a userdefined default\r
73       showDistances(true);\r
74     }\r
75 \r
76     /**\r
77      * Creates a new TreePanel object.\r
78      *\r
79      * @param av DOCUMENT ME!\r
80      * @param seqVector DOCUMENT ME!\r
81      * @param newtree DOCUMENT ME!\r
82      * @param type DOCUMENT ME!\r
83      * @param pwtype DOCUMENT ME!\r
84      */\r
85     public TreePanel(AlignViewport av, Vector seqVector, NewickFile newtree,\r
86                      String type, String pwtype)\r
87     {\r
88       super();\r
89       initTreePanel(av, seqVector, type, pwtype, 0, seqVector.size(), newtree);\r
90     }\r
91 \r
92     public AlignmentI getAlignment()\r
93     {\r
94       return treeCanvas.av.getAlignment();\r
95     }\r
96 \r
97 \r
98     void initTreePanel(AlignViewport av, Vector seqVector, String type,\r
99                        String pwtype, int s, int e, NewickFile newTree)\r
100     {\r
101 \r
102       this.type = type;\r
103       this.pwtype = pwtype;\r
104 \r
105       start = s;\r
106       end = e;\r
107 \r
108       seq = new Sequence[seqVector.size()];\r
109       seqVector.toArray(seq);\r
110 \r
111 \r
112       treeCanvas = new TreeCanvas(av, scrollPane);\r
113       scrollPane.setViewportView(treeCanvas);\r
114 \r
115       av.addPropertyChangeListener(new java.beans.PropertyChangeListener()\r
116       {\r
117         public void propertyChange(PropertyChangeEvent evt)\r
118         {\r
119           if (evt.getPropertyName().equals("alignment"))\r
120           {\r
121             if(tree==null)\r
122               System.out.println("tree is null");\r
123             if(evt.getNewValue()==null)\r
124               System.out.println("new value is null");\r
125 \r
126             tree.UpdatePlaceHolders( (Vector) evt.getNewValue());\r
127 \r
128             repaint();\r
129           }\r
130         }\r
131       });\r
132 \r
133 \r
134       TreeLoader tl = new TreeLoader(newTree);\r
135       tl.start();\r
136 \r
137     }\r
138 \r
139     class TreeLoader extends Thread\r
140     {\r
141       NewickFile newtree;\r
142 \r
143       public TreeLoader(NewickFile newtree)\r
144       {\r
145         this.newtree = newtree;\r
146         if (newtree != null)\r
147         {\r
148           // Must be outside run(), as Jalview2XML tries to\r
149           // update distance/bootstrap visibility at the same time\r
150           showBootstrap(newtree.HasBootstrap());\r
151           showDistances(newtree.HasDistances());\r
152           showPlaceholders(true);\r
153         }\r
154       }\r
155 \r
156       public void run()\r
157       {\r
158         if(newtree!=null)\r
159           tree = new NJTree(seq, newtree);\r
160         else\r
161           tree = new NJTree(seq, type, pwtype, start, end);\r
162 \r
163         tree.reCount(tree.getTopNode());\r
164         tree.findHeight(tree.getTopNode());\r
165         treeCanvas.setTree(tree);\r
166 \r
167         treeCanvas.repaint();\r
168 \r
169 \r
170         fullid.setState(treeCanvas.av.showDBPrefix);\r
171         if(!treeCanvas.av.showDBPrefix)\r
172         {\r
173           fullid_actionPerformed(null);\r
174         }\r
175       }\r
176 \r
177     }\r
178 \r
179     public void showDistances(boolean b)\r
180     {\r
181       treeCanvas.setShowDistances(b);\r
182       distanceMenu.setSelected(b);\r
183     }\r
184 \r
185     public void showBootstrap(boolean b)\r
186     {\r
187       treeCanvas.setShowBootstrap(b);\r
188       bootstrapMenu.setSelected(b);\r
189     }\r
190 \r
191     public void showPlaceholders(boolean b)\r
192     {\r
193       placeholdersMenu.setState(b);\r
194       treeCanvas.setMarkPlaceholders(b);\r
195     }\r
196 \r
197 \r
198 \r
199 \r
200     /**\r
201      * DOCUMENT ME!\r
202      *\r
203      * @return DOCUMENT ME!\r
204      */\r
205     public NJTree getTree()\r
206     {\r
207         return tree;\r
208     }\r
209 \r
210 \r
211     /**\r
212      * DOCUMENT ME!\r
213      *\r
214      * @param e DOCUMENT ME!\r
215      */\r
216     public void textbox_actionPerformed(ActionEvent e)\r
217     {\r
218         CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
219 \r
220         StringBuffer buffer = new StringBuffer();\r
221 \r
222         if (type.equals("AV"))\r
223         {\r
224             buffer.append("Average distance tree using ");\r
225         }\r
226         else\r
227         {\r
228             buffer.append("Neighbour joining tree using ");\r
229         }\r
230 \r
231         if (pwtype.equals("BL"))\r
232         {\r
233             buffer.append("BLOSUM62");\r
234         }\r
235         else\r
236         {\r
237             buffer.append("PID");\r
238         }\r
239 \r
240         Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);\r
241 \r
242         jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
243         cap.setText(fout.print(false, true));\r
244     }\r
245 \r
246     /**\r
247      * DOCUMENT ME!\r
248      *\r
249      * @param e DOCUMENT ME!\r
250      */\r
251     public void saveAsNewick_actionPerformed(ActionEvent e)\r
252     {\r
253         JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
254                     "LAST_DIRECTORY"));\r
255         chooser.setFileView(new JalviewFileView());\r
256         chooser.setDialogTitle("Save tree as newick file");\r
257         chooser.setToolTipText("Save");\r
258 \r
259         int value = chooser.showSaveDialog(null);\r
260 \r
261         if (value == JalviewFileChooser.APPROVE_OPTION)\r
262         {\r
263             String choice = chooser.getSelectedFile().getPath();\r
264             jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
265                 chooser.getSelectedFile().getParent());\r
266 \r
267             try\r
268             {\r
269                 jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
270                 String output = fout.print(false, true); // distances only\r
271                 java.io.PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(\r
272                             choice));\r
273                 out.println(output);\r
274                 out.close();\r
275             }\r
276             catch (Exception ex)\r
277             {\r
278                 ex.printStackTrace();\r
279             }\r
280         }\r
281     }\r
282 \r
283     /**\r
284      * DOCUMENT ME!\r
285      *\r
286      * @param e DOCUMENT ME!\r
287      */\r
288     public void printMenu_actionPerformed(ActionEvent e)\r
289     {\r
290         //Putting in a thread avoids Swing painting problems\r
291         treeCanvas.startPrinting();\r
292     }\r
293 \r
294     /**\r
295      * DOCUMENT ME!\r
296      *\r
297      * @param e DOCUMENT ME!\r
298      */\r
299     public void fitToWindow_actionPerformed(ActionEvent e)\r
300     {\r
301         treeCanvas.fitToWindow = fitToWindow.isSelected();\r
302         repaint();\r
303     }\r
304 \r
305     /**\r
306      * DOCUMENT ME!\r
307      *\r
308      * @param e DOCUMENT ME!\r
309      */\r
310     public void font_actionPerformed(ActionEvent e)\r
311     {\r
312         if (treeCanvas == null)\r
313         {\r
314             return;\r
315         }\r
316 \r
317         new FontChooser(this);\r
318     }\r
319 \r
320     public Font getTreeFont()\r
321     {\r
322         return treeCanvas.font;\r
323     }\r
324 \r
325     public void setTreeFont(Font font)\r
326     {\r
327       if(treeCanvas!=null)\r
328       treeCanvas.setFont(font);\r
329     }\r
330 \r
331     /**\r
332      * DOCUMENT ME!\r
333      *\r
334      * @param e DOCUMENT ME!\r
335      */\r
336     public void distanceMenu_actionPerformed(ActionEvent e)\r
337     {\r
338         treeCanvas.setShowDistances(distanceMenu.isSelected());\r
339     }\r
340 \r
341     /**\r
342      * DOCUMENT ME!\r
343      *\r
344      * @param e DOCUMENT ME!\r
345      */\r
346     public void bootstrapMenu_actionPerformed(ActionEvent e)\r
347     {\r
348         treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());\r
349     }\r
350 \r
351     /**\r
352      * DOCUMENT ME!\r
353      *\r
354      * @param e DOCUMENT ME!\r
355      */\r
356     public void placeholdersMenu_actionPerformed(ActionEvent e)\r
357     {\r
358         treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());\r
359     }\r
360 \r
361 \r
362     public void fullid_actionPerformed(ActionEvent e)\r
363     {\r
364       tree.findHeight(tree.getTopNode());\r
365 \r
366       // Now have to calculate longest name based on the leaves\r
367       Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());\r
368 \r
369       treeCanvas.longestName="";\r
370       for (int i = 0; i < leaves.size(); i++)\r
371       {\r
372         SequenceNode lf = (SequenceNode) leaves.elementAt(i);\r
373         Sequence seq = (Sequence) lf.element();\r
374         lf.setName(seq.getDisplayId(fullid.getState(), false));\r
375         if(lf.getName().length() > treeCanvas.longestName.length())\r
376           treeCanvas.longestName = lf.getName();\r
377       }\r
378 \r
379       treeCanvas.repaint();\r
380     }\r
381 \r
382 \r
383     /**\r
384      * DOCUMENT ME!\r
385      *\r
386      * @param e DOCUMENT ME!\r
387      */\r
388     public void epsTree_actionPerformed(ActionEvent e)\r
389     {\r
390       makeTreeImage(jalview.util.ImageMaker.EPS);\r
391     }\r
392 \r
393     /**\r
394      * DOCUMENT ME!\r
395      *\r
396      * @param e DOCUMENT ME!\r
397      */\r
398     public void pngTree_actionPerformed(ActionEvent e)\r
399     {\r
400        makeTreeImage(jalview.util.ImageMaker.PNG);\r
401     }\r
402 \r
403     void makeTreeImage(int type)\r
404     {\r
405       int width = treeCanvas.getWidth();\r
406       int height = treeCanvas.getHeight();\r
407 \r
408       jalview.util.ImageMaker im;\r
409 \r
410       if(type == jalview.util.ImageMaker.PNG)\r
411         im = new jalview.util.ImageMaker(this,\r
412                                          jalview.util.ImageMaker.PNG,\r
413                                          "Make PNG image from tree",\r
414                                          width, height,\r
415                                          null, null);\r
416         else\r
417           im = new jalview.util.ImageMaker(this,\r
418                                  jalview.util.ImageMaker.EPS,\r
419                                  "Make EPS file from tree",\r
420                                  width, height,\r
421                                  null, this.getTitle());\r
422 \r
423       if(im.getGraphics()!=null)\r
424       {\r
425         treeCanvas.draw(im.getGraphics(), width, height);\r
426         im.writeImage();\r
427       }\r
428     }\r
429 \r
430 }\r