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