3ba9cdd5b0b51cc13b56964877acfb37ef88658a
[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 java.io.*;\r
22 import java.util.*;\r
23 import javax.imageio.*;\r
24 \r
25 import java.awt.*;\r
26 import java.awt.event.*;\r
27 import java.awt.image.*;\r
28 import javax.swing.*;\r
29 \r
30 import org.jibble.epsgraphics.*;\r
31 import jalview.analysis.*;\r
32 import jalview.datamodel.*;\r
33 import jalview.io.*;\r
34 import jalview.jbgui.*;\r
35 \r
36 public class TreePanel\r
37     extends GTreePanel\r
38 {\r
39   SequenceI[] seq;\r
40   String type;\r
41   String pwtype;\r
42   int start;\r
43   int end;\r
44   TreeCanvas treeCanvas;\r
45   NJTree tree;\r
46 \r
47   public TreePanel(AlignViewport av, Vector seqVector, String type,\r
48                    String pwtype, int s, int e)\r
49   {\r
50     super();\r
51 \r
52     this.type = type;\r
53     this.pwtype = pwtype;\r
54 \r
55     start = s;\r
56     end = e;\r
57 \r
58     String longestName = "";\r
59     seq = new Sequence[seqVector.size()];\r
60 \r
61     for (int i = 0; i < seqVector.size(); i++)\r
62     {\r
63       seq[i] = (Sequence) seqVector.elementAt(i);\r
64 \r
65       if (seq[i].getName().length() > longestName.length())\r
66       {\r
67         longestName = seq[i].getName();\r
68       }\r
69     }\r
70 \r
71     tree = new NJTree(seq, type, pwtype, start, end);\r
72 \r
73     treeCanvas = new TreeCanvas(av, tree, scrollPane, longestName);\r
74     treeCanvas.setShowDistances(true); // We know this tree has distances. JBPNote TODO: prolly should add this as a userdefined default\r
75     setViewStateFromTreeCanvas(treeCanvas);\r
76     tree.reCount(tree.getTopNode());\r
77     tree.findHeight(tree.getTopNode());\r
78     scrollPane.setViewportView(treeCanvas);\r
79   }\r
80 \r
81   public TreePanel(AlignViewport av, Vector seqVector, NewickFile newtree,\r
82                    String type, String pwtype)\r
83   {\r
84     super();\r
85 \r
86     // These are probably only  arbitrary strings reflecting source of tree\r
87     this.type = type;\r
88     this.pwtype = pwtype;\r
89 \r
90     start = 0;\r
91     end = seqVector.size();\r
92 \r
93     String longestName = "";\r
94     seq = new Sequence[seqVector.size()];\r
95 \r
96     for (int i = 0; i < seqVector.size(); i++)\r
97     {\r
98       seq[i] = (Sequence) seqVector.elementAt(i);\r
99     }\r
100 \r
101     // This constructor matches sequence names to treenodes and sets up the tree layouts.\r
102     tree = new NJTree(seq, newtree);\r
103 \r
104     // Now have to calculate longest name based on the leaves\r
105     Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());\r
106     boolean has_placeholders = false;\r
107 \r
108     for (int i = 0; i < leaves.size(); i++)\r
109     {\r
110       SequenceNode lf = (SequenceNode) leaves.elementAt(i);\r
111 \r
112       if (lf.isPlaceholder())\r
113       {\r
114         has_placeholders = true;\r
115       }\r
116 \r
117       if (longestName.length() < ( (Sequence) lf.element()).getName()\r
118           .length())\r
119       {\r
120         longestName = TreeCanvas.PLACEHOLDER +\r
121             ( (Sequence) lf.element()).getName();\r
122       }\r
123     }\r
124 \r
125     tree.reCount(tree.getTopNode());\r
126     tree.findHeight(tree.getTopNode());\r
127 \r
128     treeCanvas = new TreeCanvas(av, tree, scrollPane, longestName);\r
129     treeCanvas.setShowBootstrap(newtree.HasBootstrap());\r
130     treeCanvas.setShowDistances(newtree.HasDistances());\r
131     scrollPane.setViewportView(treeCanvas);\r
132     treeCanvas.setMarkPlaceholders(has_placeholders);\r
133     setViewStateFromTreeCanvas(treeCanvas);\r
134 \r
135     // JBPNote TODO: preference for always marking placeholders in new associated tree\r
136   }\r
137 \r
138   public NJTree getTree()\r
139   {\r
140     return tree;\r
141   }\r
142 \r
143   private void setViewStateFromTreeCanvas(TreeCanvas tree)\r
144   {\r
145     // update view menu state from treeCanvas render state\r
146     distanceMenu.setSelected(tree.showDistances);\r
147     bootstrapMenu.setSelected(tree.showBootstrap);\r
148     placeholdersMenu.setSelected(tree.markPlaceholders);\r
149   }\r
150 \r
151   private void setTreeCanvasFromViewState(TreeCanvas tree)\r
152   {\r
153     // update view menu state from treeCanvas render state\r
154     tree.showDistances = distanceMenu.isSelected();\r
155     tree.showBootstrap = bootstrapMenu.isSelected();\r
156     tree.markPlaceholders = placeholdersMenu.isSelected();\r
157   }\r
158 \r
159   public void textbox_actionPerformed(ActionEvent e)\r
160   {\r
161     CutAndPasteTransfer cap = new CutAndPasteTransfer();\r
162 \r
163     StringBuffer buffer = new StringBuffer();\r
164 \r
165     if (type.equals("AV"))\r
166     {\r
167       buffer.append("Average distance tree using ");\r
168     }\r
169     else\r
170     {\r
171       buffer.append("Neighbour joining tree using ");\r
172     }\r
173 \r
174     if (pwtype.equals("BL"))\r
175     {\r
176       buffer.append("BLOSUM62");\r
177     }\r
178     else\r
179     {\r
180       buffer.append("PID");\r
181     }\r
182 \r
183     Desktop.addInternalFrame(cap, buffer.toString(), 500, 100);\r
184 \r
185     jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
186     cap.setText(fout.print(false, true));\r
187   }\r
188 \r
189   public void saveAsNewick_actionPerformed(ActionEvent e)\r
190   {\r
191     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
192         getProperty(\r
193             "LAST_DIRECTORY"));\r
194     chooser.setFileView(new JalviewFileView());\r
195     chooser.setDialogTitle("Save tree as newick file");\r
196     chooser.setToolTipText("Save");\r
197 \r
198     int value = chooser.showSaveDialog(null);\r
199 \r
200     if (value == JalviewFileChooser.APPROVE_OPTION)\r
201     {\r
202       String choice = chooser.getSelectedFile().getPath();\r
203       jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
204                                     chooser.getSelectedFile().getParent());\r
205 \r
206       try\r
207       {\r
208         jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
209         String output = fout.print(false, true); // distances only\r
210         java.io.PrintWriter out = new java.io.PrintWriter(new java.io.\r
211             FileWriter(\r
212                 choice));\r
213         out.println(output);\r
214         out.close();\r
215       }\r
216       catch (Exception ex)\r
217       {\r
218         ex.printStackTrace();\r
219       }\r
220     }\r
221   }\r
222 \r
223   public void printMenu_actionPerformed(ActionEvent e)\r
224   {\r
225     //Putting in a thread avoids Swing painting problems\r
226     treeCanvas.startPrinting();\r
227   }\r
228 \r
229   public void fitToWindow_actionPerformed(ActionEvent e)\r
230   {\r
231     treeCanvas.fitToWindow = fitToWindow.isSelected();\r
232     repaint();\r
233   }\r
234 \r
235   public void fontSize_actionPerformed(ActionEvent e)\r
236   {\r
237     if (treeCanvas == null)\r
238     {\r
239       return;\r
240     }\r
241 \r
242     String size = fontSize.getText().substring(fontSize.getText().indexOf("-") +\r
243                                                1);\r
244 \r
245     Object selection = JOptionPane.showInternalInputDialog(Desktop.desktop,\r
246         "Select font size", "Font size", JOptionPane.QUESTION_MESSAGE,\r
247         null,\r
248         new String[]\r
249         {\r
250         "1", "2", "4", "6", "8", "10", "12", "14", "16", "18", "20"\r
251     }, "Font Size - " + size);\r
252 \r
253     if (selection != null)\r
254     {\r
255       fontSize.setText("Font Size - " + selection);\r
256 \r
257       int i = Integer.parseInt(selection.toString());\r
258       treeCanvas.setFontSize(i);\r
259     }\r
260 \r
261     scrollPane.setViewportView(treeCanvas);\r
262   }\r
263 \r
264   public void distanceMenu_actionPerformed(ActionEvent e)\r
265   {\r
266     treeCanvas.setShowDistances(distanceMenu.isSelected());\r
267   }\r
268 \r
269   public void bootstrapMenu_actionPerformed(ActionEvent e)\r
270   {\r
271     treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());\r
272   }\r
273 \r
274   public void placeholdersMenu_actionPerformed(ActionEvent e)\r
275   {\r
276     treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());\r
277   }\r
278 \r
279   public void epsTree_actionPerformed(ActionEvent e)\r
280   {\r
281     int width = treeCanvas.getWidth();\r
282     int height = treeCanvas.getHeight();\r
283 \r
284     try\r
285     {\r
286       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(\r
287           jalview.bin.Cache.getProperty(\r
288               "LAST_DIRECTORY"), new String[]\r
289           {"eps"},\r
290           new String[]\r
291           {"Encapsulated Postscript"},\r
292           "Encapsulated Postscript");\r
293       chooser.setFileView(new jalview.io.JalviewFileView());\r
294       chooser.setDialogTitle("Create EPS file from tree");\r
295       chooser.setToolTipText("Save");\r
296 \r
297       int value = chooser.showSaveDialog(this);\r
298 \r
299       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
300       {\r
301         return;\r
302       }\r
303 \r
304       jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
305                                     chooser.getSelectedFile().getParent());\r
306 \r
307       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
308       EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,\r
309                                            height);\r
310 \r
311       treeCanvas.draw(pg, width, height);\r
312 \r
313       pg.flush();\r
314       pg.close();\r
315     }\r
316     catch (Exception ex)\r
317     {\r
318       ex.printStackTrace();\r
319     }\r
320   }\r
321 \r
322   public void pngTree_actionPerformed(ActionEvent e)\r
323   {\r
324     int width = treeCanvas.getWidth();\r
325     int height = treeCanvas.getHeight();\r
326 \r
327     try\r
328     {\r
329       jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(\r
330           jalview.bin.Cache.getProperty(\r
331               "LAST_DIRECTORY"), new String[]\r
332           {"png"},\r
333           new String[]\r
334           {"Portable network graphics"},\r
335           "Portable network graphics");\r
336 \r
337       chooser.setFileView(new jalview.io.JalviewFileView());\r
338       chooser.setDialogTitle("Create PNG image from tree");\r
339       chooser.setToolTipText("Save");\r
340 \r
341       int value = chooser.showSaveDialog(this);\r
342 \r
343       if (value != jalview.io.JalviewFileChooser.APPROVE_OPTION)\r
344       {\r
345         return;\r
346       }\r
347 \r
348       jalview.bin.Cache.setProperty("LAST_DIRECTORY",\r
349                                     chooser.getSelectedFile().getParent());\r
350 \r
351       FileOutputStream out = new FileOutputStream(chooser.getSelectedFile());\r
352 \r
353       BufferedImage bi = new BufferedImage(width, height,\r
354                                            BufferedImage.TYPE_INT_RGB);\r
355       Graphics png = bi.getGraphics();\r
356 \r
357       treeCanvas.draw(png, width, height);\r
358 \r
359       ImageIO.write(bi, "png", out);\r
360       out.close();\r
361     }\r
362     catch (Exception ex)\r
363     {\r
364       ex.printStackTrace();\r
365     }\r
366   }\r
367 }\r