73ef46bb3445886457db3820a99a281cc327e057
[jalview.git] / src / jalview / gui / TreePanel.java
1 package jalview.gui;\r
2 \r
3 import jalview.datamodel.*;\r
4 import jalview.analysis.*;\r
5 import jalview.jbgui.GTreePanel;\r
6 import jalview.io.*;\r
7 import java.awt.event.*;\r
8 import java.util.*;\r
9 import java.io.*;\r
10 import jalview.util.*;\r
11 import javax.swing.*;\r
12 import java.awt.print.*;\r
13 import java.awt.*;\r
14 \r
15 \r
16 \r
17 public class TreePanel extends GTreePanel\r
18 {\r
19   SequenceI[] seq;\r
20   String type;\r
21   String pwtype;\r
22   AlignViewport av;\r
23   int start;\r
24   int end;\r
25   TreeCanvas treeCanvas;\r
26   NJTree tree;\r
27 \r
28   FileProperties       fp;\r
29   PostscriptProperties pp;\r
30 \r
31   PrintWriter bw;\r
32   PrintStream ps;\r
33   boolean makeString = false;\r
34   StringBuffer out;\r
35 \r
36 \r
37 \r
38   public TreePanel(AlignViewport av, Vector seqVector, String type, String pwtype, int s, int e)\r
39   {\r
40     super();\r
41 \r
42     this.type = type;\r
43     this.pwtype = pwtype;\r
44 \r
45     start = s;\r
46     end = e;\r
47 \r
48     String longestName = "";\r
49     seq = new Sequence [seqVector.size()];\r
50     for (int i=0;i < seqVector.size();i++)\r
51     {\r
52       seq[i] = (Sequence) seqVector.elementAt(i);\r
53       if(seq[i].getName().length()>longestName.length())\r
54         longestName = seq[i].getName();\r
55     }\r
56 \r
57     tree = new NJTree(seq, type, pwtype, start, end);\r
58     av.setCurrentTree(tree);\r
59 \r
60     propertiesInit();\r
61 \r
62     treeCanvas = new TreeCanvas(av, tree, scrollPane, longestName);\r
63 \r
64     tree.reCount(tree.getTopNode());\r
65     tree.findHeight(tree.getTopNode());\r
66     scrollPane.setViewportView(treeCanvas);\r
67 \r
68   }\r
69   public TreePanel(AlignViewport av, Vector seqVector, NewickFile newtree,\r
70                    String type, String pwtype)\r
71     {\r
72       super();\r
73       // These are probably only  arbitrary strings reflecting source of tree\r
74       this.type = type;\r
75       this.pwtype = pwtype;\r
76 \r
77       start = 0;\r
78       end = seqVector.size();\r
79 \r
80       String longestName = "";\r
81       seq = new Sequence [seqVector.size()];\r
82       for (int i=0;i < seqVector.size();i++)\r
83       {\r
84         seq[i] = (Sequence) seqVector.elementAt(i);\r
85         if(seq[i].getName().length()>longestName.length())\r
86           longestName = seq[i].getName();\r
87       }\r
88       // This constructor matches sequence names to treenodes and sets up the tree layouts.\r
89       tree = new NJTree(seq, newtree);\r
90       av.setCurrentTree(tree);\r
91 \r
92       propertiesInit();\r
93 \r
94       tree.reCount(tree.getTopNode());\r
95       tree.findHeight(tree.getTopNode());\r
96 \r
97       treeCanvas = new TreeCanvas(av, tree, scrollPane, longestName);\r
98       scrollPane.setViewportView(treeCanvas);\r
99 \r
100     }\r
101 \r
102 \r
103 public void drawPostscript(PostscriptProperties pp) {\r
104   try {\r
105     int width = 0;\r
106     int height = 0;\r
107 \r
108     printout("%!\n");\r
109 \r
110     printout("/" + pp.font + " findfont\n");\r
111     printout(pp.fsize + " scalefont setfont\n");\r
112 \r
113     int offx = pp.xoffset;\r
114     int offy = pp.yoffset;\r
115 \r
116     if (pp.orientation == PostscriptProperties.PORTRAIT) {\r
117       width = PostscriptProperties.SHORTSIDE;\r
118       height = PostscriptProperties.LONGSIDE;\r
119     } else {\r
120       height = PostscriptProperties.SHORTSIDE;\r
121       width = PostscriptProperties.LONGSIDE;\r
122       printout(height + " 0 translate\n90 rotate\n");\r
123     }\r
124     float wscale = (float)(width*.8-offx*2)/tree.getMaxHeight();\r
125     SequenceNode top = tree.getTopNode();\r
126 \r
127     if (top.count == 0) {\r
128         top.count = ((SequenceNode)top.left()).count + ((SequenceNode)top.right()).count ;\r
129     }\r
130 \r
131     float chunk = (float)(height-offy*2)/(((SequenceNode)top).count+1);\r
132 \r
133     drawPostscriptNode(top,chunk,wscale,width,offx,offy);\r
134 \r
135     printout("showpage\n");\r
136   } catch (java.io.IOException e) {\r
137     System.out.println("Exception " + e);\r
138   }\r
139 }\r
140 \r
141 public void drawPostscriptNode(SequenceNode node, float chunk, float scale, int width, int offx, int offy) throws java.io.IOException {\r
142   if (node == null) {\r
143     return;\r
144   }\r
145 \r
146   if (node.left() == null && node.right() == null) {\r
147     // Drawing leaf node\r
148 \r
149     float height = node.height;\r
150     float dist = node.dist;\r
151 \r
152     int xstart = (int)((height-dist)*scale) + offx;\r
153     int xend =   (int)(height*scale) + offx;\r
154 \r
155     int ypos = (int)(node.ycount * chunk) + offy;\r
156 \r
157     // g.setColor(Color.black);\r
158     printout("\n" + new Format("%5.3f").form((double)node.color.getRed()/255) + " " +\r
159              new Format("%5.3f").form((double)node.color.getGreen()/255) + " " +\r
160              new Format("%5.3f").form((double)node.color.getBlue()/255) + " setrgbcolor\n");\r
161 \r
162     // Draw horizontal line\r
163     //  g.drawLine(xstart,ypos,xend,ypos);\r
164     printout(xstart + " " + ypos + " moveto " + xend + " " + ypos + " lineto stroke \n");\r
165 \r
166     if (treeCanvas.showDistances && node.dist > 0) {\r
167       //        g.drawString(new Format("%5.2f").form(node.dist),xstart,ypos - 5);\r
168       printout("(" + new Format("%5.2f").form(node.dist) + ") " + xstart + " " + (ypos+5) + " moveto show\n");\r
169     }\r
170     //g.drawString((String)node.element(),xend+20,ypos);\r
171     printout("(" + (((SequenceI)node.element()).getName()) + ") " + (xend+20) + " " + (ypos) + " moveto show\n");\r
172   } else {\r
173     drawPostscriptNode((SequenceNode)node.left(),chunk,scale,width,offx,offy);\r
174     drawPostscriptNode((SequenceNode)node.right(),chunk,scale,width,offx,offy);\r
175 \r
176 \r
177     float height = node.height;\r
178     float dist = node.dist;\r
179 \r
180     int xstart = (int)((height-dist)*scale) + offx;\r
181     int xend =   (int)(height*scale) + offx;\r
182     int ypos = (int)(node.ycount * chunk) + offy;\r
183 \r
184     printout("\n" + new Format("%5.3f").form((double)node.color.getRed()/255) + " " +\r
185              new Format("%5.3f").form((double)node.color.getGreen()/255) + " " +\r
186              new Format("%5.3f").form((double)node.color.getBlue()/255) + " setrgbcolor\n");\r
187     //      g.setColor(Color.black);\r
188     //      bw.append("\nblack setrgbcolor\n");\r
189     // Draw horizontal line\r
190     //      g.drawLine(xstart,ypos,xend,ypos);\r
191     printout(xstart + " " + ypos + " moveto " + xend + " " + ypos + " lineto stroke\n");\r
192     int ystart = (int)(((SequenceNode)node.left()).ycount * chunk) + offy;\r
193     int yend = (int)(((SequenceNode)node.right()).ycount * chunk) + offy;\r
194 \r
195     //      g.drawLine((int)(height*scale) + offx, ystart,\r
196     //           (int)(height*scale) + offx, yend);\r
197     printout\r
198     (((int)(height*scale) + offx) + " " + ystart + " moveto " +  ((int)(height*scale) + offx) + " " +\r
199      yend + " lineto stroke\n");\r
200     if (treeCanvas.showDistances && node.dist > 0) {\r
201       //        g.drawString(new Format("%5.2f").form(node.dist),xstart,ypos - 5);\r
202       printout("(" +new Format("%5.2f").form(node.dist) + ") " + (xstart) + " " + (ypos+5) + " moveto show\n");\r
203     }\r
204   }\r
205 }\r
206 \r
207 public void printout(String s) throws IOException {\r
208   if (bw != null) {\r
209     bw.write(s);\r
210   }\r
211   if (ps != null) {\r
212     ps.print(s);\r
213   }\r
214   if (makeString == true) {\r
215     out.append(s);\r
216   }\r
217 }\r
218 \r
219 \r
220 public PostscriptProperties getPostscriptProperties() {\r
221   return pp;\r
222 }\r
223 \r
224 public FileProperties getFileProperties() {\r
225   return fp;\r
226 }\r
227 \r
228 public void setPostscriptProperties(PostscriptProperties pp) {\r
229   this.pp = pp;\r
230 }\r
231 \r
232 public void setFileProperties(FileProperties fp) {\r
233   this.fp = fp;\r
234 }\r
235 \r
236 public String getText(String format) {\r
237   return null;\r
238 }\r
239 \r
240 public void getPostscript(PrintWriter bw) {\r
241   this.bw = bw;\r
242   drawPostscript(pp);\r
243 \r
244 }\r
245 \r
246 public void getPostscript(PrintStream bw) {\r
247   this.ps = bw;\r
248   drawPostscript(pp);\r
249   bw.flush();\r
250 }\r
251 \r
252 public StringBuffer getPostscript() {\r
253   makeString = true;\r
254   out = new StringBuffer();\r
255   drawPostscript(pp);\r
256   return out;\r
257 }\r
258 \r
259 public void propertiesInit() {\r
260   this.pp = new PostscriptProperties();\r
261   this.fp = new FileProperties();\r
262 }\r
263 \r
264 \r
265   public void saveButton_actionPerformed(ActionEvent e)\r
266   {\r
267 \r
268     try{\r
269       JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty("LAST_DIRECTORY"));\r
270       chooser.setDialogTitle("Save Tree as postscript file");\r
271       chooser.setToolTipText("Save");\r
272       int value = chooser.showSaveDialog(this);\r
273       if (value == JalviewFileChooser.APPROVE_OPTION)\r
274       {\r
275         String choice = chooser.getSelectedFile().getPath();\r
276         jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);\r
277 \r
278         bw = new PrintWriter(new FileWriter(choice));\r
279         getPostscript(bw);\r
280         bw.close();\r
281 \r
282       }\r
283 \r
284     }catch(Exception ex){ex.printStackTrace();}\r
285 \r
286   }\r
287 \r
288 \r
289   protected void saveMenu_actionPerformed(ActionEvent e)\r
290   {\r
291     JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
292         getProperty("LAST_DIRECTORY"));\r
293     chooser.setFileView(new JalviewFileView());\r
294     chooser.setDialogTitle("Save tree as newick file");\r
295     chooser.setToolTipText("Save");\r
296     int value = chooser.showSaveDialog(null);\r
297     if (value == JalviewFileChooser.APPROVE_OPTION) {\r
298       String choice =  chooser.getSelectedFile().getPath();\r
299       jalview.bin.Cache.setProperty("LAST_DIRECTORY",  choice);\r
300       try{\r
301         jalview.io.NewickFile fout = new jalview.io.NewickFile(tree.getTopNode());\r
302         String output = fout.print(false,true); // distances only\r
303         java.io.PrintWriter out = new java.io.PrintWriter( new java.io.FileWriter( choice )  );\r
304         out.println(output);\r
305         out.close();\r
306       }\r
307       catch (Exception ex) {\r
308         ex.printStackTrace();\r
309       }\r
310     }\r
311   }\r
312 \r
313   protected void printMenu_actionPerformed(ActionEvent e)\r
314   {\r
315 \r
316     //Putting in a thread avoids Swing painting problems\r
317     treeCanvas.startPrinting();\r
318   }\r
319 \r
320   protected void fitToWindow_actionPerformed(ActionEvent e)\r
321   {\r
322     treeCanvas.fitToWindow = fitToWindow.isSelected();\r
323     repaint();\r
324   }\r
325 \r
326 \r
327   protected void fontSize_actionPerformed(ActionEvent e)\r
328   {\r
329     if( treeCanvas==null )\r
330      return;\r
331 \r
332    String size = fontSize.getText().substring( fontSize.getText().indexOf("-")+1);\r
333 \r
334    Object selection = JOptionPane.showInternalInputDialog(Desktop.desktop,\r
335                                "Select font size",\r
336                                "Font size",\r
337                                JOptionPane.QUESTION_MESSAGE,\r
338                                null, new String[]{"1","2","4","6","8","10","12","14","16","18","20"}\r
339                                ,"Font Size - "+size);\r
340    if(selection!=null)\r
341    {\r
342      fontSize.setText("Font Size - " + selection);\r
343 \r
344      int i = Integer.parseInt(selection.toString());\r
345      treeCanvas.setFontSize(i);\r
346    }\r
347     scrollPane.setViewportView(treeCanvas);\r
348 \r
349   }\r
350 \r
351   protected void distanceMenu_actionPerformed(ActionEvent e)\r
352   {\r
353     treeCanvas.setShowDistances(distanceMenu.isSelected());\r
354   }\r
355 \r
356   protected void bootstrapMenu_actionPerformed(ActionEvent e)\r
357   {\r
358     treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());\r
359   }\r
360 \r
361 \r
362 }\r