d6c0069480292a4cb9080240a93ff2619dba9c88
[jalview.git] / src / jalview / appletgui / TreePanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.appletgui;
20
21 import java.awt.*;
22 import java.awt.event.*;
23 import java.util.Hashtable;
24
25 import jalview.analysis.*;
26 import jalview.datamodel.*;
27 import jalview.io.*;
28
29 public class TreePanel extends EmbmenuFrame implements ActionListener,
30         ItemListener
31 {
32   SequenceI[] seq;
33
34   String type;
35
36   String pwtype;
37
38   int start;
39
40   int end;
41
42   TreeCanvas treeCanvas;
43
44   NJTree tree;
45
46   AlignViewport av;
47
48   public NJTree getTree()
49   {
50     return tree;
51   }
52
53   /**
54    * Creates a new TreePanel object.
55    * 
56    * @param av
57    *                DOCUMENT ME!
58    * @param seqVector
59    *                DOCUMENT ME!
60    * @param type
61    *                DOCUMENT ME!
62    * @param pwtype
63    *                DOCUMENT ME!
64    * @param s
65    *                DOCUMENT ME!
66    * @param e
67    *                DOCUMENT ME!
68    */
69   public TreePanel(AlignViewport av, String type, String pwtype)
70   {
71     try
72     {
73       jbInit();
74       this.setMenuBar(jMenuBar1);
75     } catch (Exception ex)
76     {
77       ex.printStackTrace();
78     }
79
80     initTreePanel(av, type, pwtype, null);
81   }
82
83   /**
84    * Creates a new TreePanel object.
85    * 
86    * @param av
87    *                DOCUMENT ME!
88    * @param seqVector
89    *                DOCUMENT ME!
90    * @param newtree
91    *                DOCUMENT ME!
92    * @param type
93    *                DOCUMENT ME!
94    * @param pwtype
95    *                DOCUMENT ME!
96    */
97   public TreePanel(AlignViewport av, String type, String pwtype,
98           NewickFile newtree)
99   {
100     try
101     {
102       jbInit();
103       this.setMenuBar(jMenuBar1);
104     } catch (Exception e)
105     {
106       e.printStackTrace();
107     }
108
109     initTreePanel(av, type, pwtype, newtree);
110   }
111
112   void initTreePanel(AlignViewport av, String type, String pwtype,
113           NewickFile newTree)
114   {
115
116     this.av = av;
117     this.type = type;
118     this.pwtype = pwtype;
119
120     treeCanvas = new TreeCanvas(av, scrollPane);
121     TreeLoader tl = new TreeLoader(newTree);
122     tl.start();
123     embedMenuIfNeeded(treeCanvas);
124     scrollPane.add(treeCanvas, BorderLayout.CENTER);
125   }
126
127   void showOriginalData()
128   {
129     // decide if av alignment is sufficiently different to original data to
130     // warrant a new window to be created
131     // create new alignmnt window with hidden regions (unhiding hidden regions
132     // yields unaligned seqs)
133     // or create a selection box around columns in alignment view
134     // test Alignment(SeqCigar[])
135     if (tree.seqData != null)
136     {
137       char gc = '-';
138       try
139       {
140         // we try to get the associated view's gap character
141         // but this may fail if the view was closed...
142         gc = av.getGapCharacter();
143       } catch (Exception ex)
144       {
145       }
146       ;
147       Object[] alAndColsel = tree.seqData
148               .getAlignmentAndColumnSelection(gc);
149
150       if (alAndColsel != null && alAndColsel[0] != null)
151       {
152         Alignment al = new Alignment((SequenceI[]) alAndColsel[0]);
153         AlignFrame af = new AlignFrame(al, av.applet,
154                 "Original Data for Tree", false);
155
156         af.viewport.setHiddenColumns((ColumnSelection) alAndColsel[1]);
157       }
158     }
159     else
160     {
161       System.out.println("Original Tree Data not available");
162     }
163   }
164
165   class TreeLoader extends Thread
166   {
167     NewickFile newtree;
168
169     jalview.datamodel.AlignmentView odata = null;
170
171     public TreeLoader(NewickFile newtree)
172     {
173       this.newtree = newtree;
174     }
175
176     public void run()
177     {
178       if (newtree != null)
179       {
180         if (odata == null)
181         {
182           tree = new NJTree(av.alignment.getSequencesArray(), newtree);
183         }
184         else
185         {
186           tree = new NJTree(av.alignment.getSequencesArray(), odata,
187                   newtree);
188         }
189
190       }
191       else
192       {
193         int start, end;
194         SequenceI[] seqs;
195         AlignmentView seqStrings = av.getAlignmentView(av
196                 .getSelectionGroup() != null);
197         if (av.getSelectionGroup() == null)
198         {
199           start = 0;
200           end = av.alignment.getWidth();
201           seqs = av.alignment.getSequencesArray();
202         }
203         else
204         {
205           start = av.getSelectionGroup().getStartRes();
206           end = av.getSelectionGroup().getEndRes() + 1;
207           seqs = av.getSelectionGroup().getSequencesInOrder(av.alignment);
208         }
209
210         tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
211       }
212
213       tree.reCount(tree.getTopNode());
214       tree.findHeight(tree.getTopNode());
215       treeCanvas.setTree(tree);
216       if (newtree != null)
217       {
218         distanceMenu.setState(newtree.HasDistances());
219         bootstrapMenu.setState(newtree.HasBootstrap());
220         treeCanvas.setShowBootstrap(newtree.HasBootstrap());
221         treeCanvas.setShowDistances(newtree.HasDistances());
222       }
223
224       treeCanvas.repaint();
225
226       av.setCurrentTree(tree);
227
228     }
229   }
230
231   public void actionPerformed(ActionEvent evt)
232   {
233     if (evt.getSource() == newickOutput)
234     {
235       newickOutput_actionPerformed();
236     }
237     else if (evt.getSource() == fontSize)
238     {
239       fontSize_actionPerformed();
240     }
241     else if (evt.getSource() == inputData)
242     {
243       showOriginalData();
244     }
245   }
246
247   public void itemStateChanged(ItemEvent evt)
248   {
249     if (evt.getSource() == fitToWindow)
250     {
251       treeCanvas.fitToWindow = fitToWindow.getState();
252     }
253
254     else if (evt.getSource() == distanceMenu)
255     {
256       treeCanvas.setShowDistances(distanceMenu.getState());
257     }
258
259     else if (evt.getSource() == bootstrapMenu)
260     {
261       treeCanvas.setShowBootstrap(bootstrapMenu.getState());
262     }
263
264     else if (evt.getSource() == placeholdersMenu)
265     {
266       treeCanvas.setMarkPlaceholders(placeholdersMenu.getState());
267     }
268
269     treeCanvas.repaint();
270   }
271
272   public void newickOutput_actionPerformed()
273   {
274     jalview.io.NewickFile fout = new jalview.io.NewickFile(tree
275             .getTopNode());
276     String output = fout.print(false, true);
277     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
278     cap.setText(output);
279     java.awt.Frame frame = new java.awt.Frame();
280     frame.add(cap);
281     jalview.bin.JalviewLite.addFrame(frame, type + " " + pwtype, 500, 100);
282   }
283
284   public java.awt.Font getTreeFont()
285   {
286     return treeCanvas.font;
287   }
288
289   public void setTreeFont(java.awt.Font font)
290   {
291     treeCanvas.font = font;
292     treeCanvas.repaint();
293   }
294
295   protected void fontSize_actionPerformed()
296   {
297     if (treeCanvas == null)
298     {
299       return;
300     }
301
302     new FontChooser(this);
303   }
304
305   BorderLayout borderLayout1 = new BorderLayout();
306
307   protected ScrollPane scrollPane = new ScrollPane();
308
309   MenuBar jMenuBar1 = new MenuBar();
310
311   Menu jMenu2 = new Menu();
312
313   protected MenuItem fontSize = new MenuItem();
314
315   protected CheckboxMenuItem bootstrapMenu = new CheckboxMenuItem();
316
317   protected CheckboxMenuItem distanceMenu = new CheckboxMenuItem();
318
319   protected CheckboxMenuItem placeholdersMenu = new CheckboxMenuItem();
320
321   protected CheckboxMenuItem fitToWindow = new CheckboxMenuItem();
322
323   Menu fileMenu = new Menu();
324
325   MenuItem newickOutput = new MenuItem();
326
327   MenuItem inputData = new MenuItem();
328
329   private void jbInit() throws Exception
330   {
331     setLayout(borderLayout1);
332     this.setBackground(Color.white);
333     this.setFont(new java.awt.Font("Verdana", 0, 12));
334     jMenu2.setLabel("View");
335     fontSize.setLabel("Font...");
336     fontSize.addActionListener(this);
337     bootstrapMenu.setLabel("Show Bootstrap Values");
338     bootstrapMenu.addItemListener(this);
339     distanceMenu.setLabel("Show Distances");
340     distanceMenu.addItemListener(this);
341     placeholdersMenu.setLabel("Mark Unassociated Leaves");
342     placeholdersMenu.addItemListener(this);
343     fitToWindow.setState(true);
344     fitToWindow.setLabel("Fit To Window");
345     fitToWindow.addItemListener(this);
346     fileMenu.setLabel("File");
347     newickOutput.setLabel("Newick Format");
348     newickOutput.addActionListener(this);
349     inputData.setLabel("Input Data...");
350
351     add(scrollPane, BorderLayout.CENTER);
352     jMenuBar1.add(fileMenu);
353     jMenuBar1.add(jMenu2);
354     jMenu2.add(fitToWindow);
355     jMenu2.add(fontSize);
356     jMenu2.add(distanceMenu);
357     jMenu2.add(bootstrapMenu);
358     jMenu2.add(placeholdersMenu);
359     fileMenu.add(newickOutput);
360     fileMenu.add(inputData);
361     inputData.addActionListener(this);
362   }
363
364 }