Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.gui

File TreePanel.java

 

Coverage histogram

../../img/srcFileCovDistChart4.png
44% of files have more coverage

Code metrics

58
207
44
2
836
571
82
0.4
4.7
22
1.86

Classes

Class Line # Actions
TreePanel 77 187 75
0.2707581227.1%
TreePanel.TreeLoader 274 20 7
0.6562565.6%
 

Contributing tests

This file is covered by 8 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.gui;
22   
23    import jalview.analysis.AlignmentSorter;
24    import jalview.analysis.AverageDistanceTree;
25    import jalview.analysis.NJTree;
26    import jalview.analysis.TreeBuilder;
27    import jalview.analysis.TreeModel;
28    import jalview.analysis.scoremodels.ScoreModels;
29    import jalview.api.analysis.ScoreModelI;
30    import jalview.api.analysis.SimilarityParamsI;
31    import jalview.commands.CommandI;
32    import jalview.commands.OrderCommand;
33    import jalview.datamodel.Alignment;
34    import jalview.datamodel.AlignmentI;
35    import jalview.datamodel.AlignmentView;
36    import jalview.datamodel.BinaryNode;
37    import jalview.datamodel.DBRefEntry;
38    import jalview.datamodel.HiddenColumns;
39    import jalview.datamodel.NodeTransformI;
40    import jalview.datamodel.SequenceFeature;
41    import jalview.datamodel.SequenceI;
42    import jalview.datamodel.SequenceNode;
43    import jalview.gui.ImageExporter.ImageWriterI;
44    import jalview.io.JalviewFileChooser;
45    import jalview.io.JalviewFileView;
46    import jalview.io.NewickFile;
47    import jalview.jbgui.GTreePanel;
48    import jalview.util.ImageMaker.TYPE;
49    import jalview.util.MessageManager;
50    import jalview.viewmodel.AlignmentViewport;
51   
52    import java.awt.Font;
53    import java.awt.Graphics;
54    import java.awt.event.ActionEvent;
55    import java.awt.event.ActionListener;
56    import java.beans.PropertyChangeEvent;
57    import java.beans.PropertyChangeListener;
58    import java.io.File;
59    import java.io.FileOutputStream;
60    import java.util.ArrayList;
61    import java.util.List;
62   
63    import javax.swing.ButtonGroup;
64    import javax.swing.JMenuItem;
65    import javax.swing.JRadioButtonMenuItem;
66    import javax.swing.event.InternalFrameAdapter;
67    import javax.swing.event.InternalFrameEvent;
68   
69    import org.jibble.epsgraphics.EpsGraphics2D;
70   
71    /**
72    * DOCUMENT ME!
73    *
74    * @author $author$
75    * @version $Revision$
76    */
 
77    public class TreePanel extends GTreePanel
78    {
79    String treeType;
80   
81    String scoreModelName; // if tree computed
82   
83    String treeTitle; // if tree loaded
84   
85    SimilarityParamsI similarityParams;
86   
87    private TreeCanvas treeCanvas;
88   
89    TreeModel tree;
90   
91    private AlignViewport av;
92   
93    /**
94    * Creates a new TreePanel object.
95    *
96    * @param ap
97    * @param type
98    * @param modelName
99    * @param options
100    */
 
101  0 toggle public TreePanel(AlignmentPanel ap, String type, String modelName,
102    SimilarityParamsI options)
103    {
104  0 super();
105  0 this.similarityParams = options;
106  0 initTreePanel(ap, type, modelName, null, null);
107   
108    // We know this tree has distances. JBPNote TODO: prolly should add this as
109    // a userdefined default
110    // showDistances(true);
111    }
112   
 
113  9 toggle public TreePanel(AlignmentPanel alignPanel, NewickFile newtree,
114    String theTitle, AlignmentView inputData)
115    {
116  9 super();
117  9 this.treeTitle = theTitle;
118  9 initTreePanel(alignPanel, null, null, newtree, inputData);
119    }
120   
 
121  0 toggle public AlignmentI getAlignment()
122    {
123  0 return getTreeCanvas().getViewport().getAlignment();
124    }
125   
 
126  0 toggle public AlignmentViewport getViewPort()
127    {
128    // @Mungo - Why don't we return our own viewport ???
129  0 return getTreeCanvas().getViewport();
130    }
131   
 
132  9 toggle void initTreePanel(AlignmentPanel ap, String type, String modelName,
133    NewickFile newTree, AlignmentView inputData)
134    {
135   
136  9 av = ap.av;
137  9 this.treeType = type;
138  9 this.scoreModelName = modelName;
139   
140  9 treeCanvas = new TreeCanvas(this, ap, scrollPane);
141  9 scrollPane.setViewportView(treeCanvas);
142   
143  9 PaintRefresher.Register(this, ap.av.getSequenceSetId());
144   
145  9 buildAssociatedViewMenu();
146   
147  9 final PropertyChangeListener listener = addAlignmentListener();
148   
149    /*
150    * remove listener when window is closed, so that this
151    * panel can be garbage collected
152    */
153  9 addInternalFrameListener(new InternalFrameAdapter()
154    {
 
155  8 toggle @Override
156    public void internalFrameClosed(InternalFrameEvent evt)
157    {
158  8 if (av != null)
159    {
160  8 av.removePropertyChangeListener(listener);
161    }
162    }
163    });
164   
165  9 TreeLoader tl = new TreeLoader(newTree, inputData);
166  9 tl.start();
167   
168    }
169   
170    /**
171    * @return
172    */
 
173  9 toggle protected PropertyChangeListener addAlignmentListener()
174    {
175  9 final PropertyChangeListener listener = new PropertyChangeListener()
176    {
 
177  0 toggle @Override
178    public void propertyChange(PropertyChangeEvent evt)
179    {
180  0 if (evt.getPropertyName().equals("alignment"))
181    {
182  0 if (tree == null)
183    {
184  0 System.out.println("tree is null");
185    // TODO: deal with case when a change event is received whilst a
186    // tree is still being calculated - should save reference for
187    // processing message later.
188  0 return;
189    }
190  0 if (evt.getNewValue() == null)
191    {
192  0 System.out.println(
193    "new alignment sequences vector value is null");
194    }
195   
196  0 tree.updatePlaceHolders((List<SequenceI>) evt.getNewValue());
197  0 treeCanvas.nameHash.clear(); // reset the mapping between canvas
198    // rectangles and leafnodes
199  0 repaint();
200    }
201    }
202    };
203  9 av.addPropertyChangeListener(listener);
204  9 return listener;
205    }
206   
 
207  0 toggle @Override
208    public void viewMenu_menuSelected()
209    {
210  0 buildAssociatedViewMenu();
211    }
212   
 
213  9 toggle void buildAssociatedViewMenu()
214    {
215  9 AlignmentPanel[] aps = PaintRefresher
216    .getAssociatedPanels(av.getSequenceSetId());
217  9 if (aps.length == 1 && getTreeCanvas().getAssociatedPanel() == aps[0])
218    {
219  1 associateLeavesMenu.setVisible(false);
220  1 return;
221    }
222   
223  8 associateLeavesMenu.setVisible(true);
224   
225  8 if ((viewMenu
226    .getItem(viewMenu.getItemCount() - 2) instanceof JMenuItem))
227    {
228  8 viewMenu.insertSeparator(viewMenu.getItemCount() - 1);
229    }
230   
231  8 associateLeavesMenu.removeAll();
232   
233  8 JRadioButtonMenuItem item;
234  8 ButtonGroup buttonGroup = new ButtonGroup();
235  8 int i, iSize = aps.length;
236  8 final TreePanel thisTreePanel = this;
237  32 for (i = 0; i < iSize; i++)
238    {
239  24 final AlignmentPanel ap = aps[i];
240  24 item = new JRadioButtonMenuItem(ap.av.getViewName(),
241    ap == treeCanvas.getAssociatedPanel());
242  24 buttonGroup.add(item);
243  24 item.addActionListener(new ActionListener()
244    {
 
245  0 toggle @Override
246    public void actionPerformed(ActionEvent evt)
247    {
248  0 treeCanvas.applyToAllViews = false;
249  0 treeCanvas.setAssociatedPanel(ap);
250  0 treeCanvas.setViewport(ap.av);
251  0 PaintRefresher.Register(thisTreePanel, ap.av.getSequenceSetId());
252    }
253    });
254   
255  24 associateLeavesMenu.add(item);
256    }
257   
258  8 final JRadioButtonMenuItem itemf = new JRadioButtonMenuItem(
259    MessageManager.getString("label.all_views"));
260  8 buttonGroup.add(itemf);
261  8 itemf.setSelected(treeCanvas.applyToAllViews);
262  8 itemf.addActionListener(new ActionListener()
263    {
 
264  0 toggle @Override
265    public void actionPerformed(ActionEvent evt)
266    {
267  0 treeCanvas.applyToAllViews = itemf.isSelected();
268    }
269    });
270  8 associateLeavesMenu.add(itemf);
271   
272    }
273   
 
274    class TreeLoader extends Thread
275    {
276    private NewickFile newtree;
277   
278    private AlignmentView odata = null;
279   
 
280  9 toggle public TreeLoader(NewickFile newickFile, AlignmentView inputData)
281    {
282  9 this.newtree = newickFile;
283  9 this.odata = inputData;
284   
285  9 if (newickFile != null)
286    {
287    // Must be outside run(), as Jalview2XML tries to
288    // update distance/bootstrap visibility at the same time
289  9 showBootstrap(newickFile.HasBootstrap());
290  9 showDistances(newickFile.HasDistances());
291    }
292    }
293   
 
294  9 toggle @Override
295    public void run()
296    {
297   
298  9 if (newtree != null)
299    {
300  9 tree = new TreeModel(av.getAlignment().getSequencesArray(), odata,
301    newtree);
302  9 if (tree.getOriginalData() == null)
303    {
304  9 originalSeqData.setVisible(false);
305    }
306    }
307    else
308    {
309  0 ScoreModelI sm = ScoreModels.getInstance()
310    .getScoreModel(scoreModelName,
311    treeCanvas.getAssociatedPanel());
312  0 TreeBuilder njtree = treeType.equals(TreeBuilder.NEIGHBOUR_JOINING)
313    ? new NJTree(av, sm, similarityParams)
314    : new AverageDistanceTree(av, sm, similarityParams);
315  0 tree = new TreeModel(njtree);
316  0 showDistances(true);
317    }
318   
319  9 tree.reCount(tree.getTopNode());
320  9 tree.findHeight(tree.getTopNode());
321  9 treeCanvas.setTree(tree);
322  9 treeCanvas.repaint();
323  9 av.setCurrentTree(tree);
324  9 if (av.getSortByTree())
325    {
326  0 sortByTree_actionPerformed();
327    }
328    }
329    }
330   
 
331  17 toggle public void showDistances(boolean b)
332    {
333  17 treeCanvas.setShowDistances(b);
334  17 distanceMenu.setSelected(b);
335    }
336   
 
337  17 toggle public void showBootstrap(boolean b)
338    {
339  17 treeCanvas.setShowBootstrap(b);
340  17 bootstrapMenu.setSelected(b);
341    }
342   
 
343  8 toggle public void showPlaceholders(boolean b)
344    {
345  8 placeholdersMenu.setState(b);
346  8 treeCanvas.setMarkPlaceholders(b);
347    }
348   
349    /**
350    * DOCUMENT ME!
351    *
352    * @return DOCUMENT ME!
353    */
 
354  13 toggle public TreeModel getTree()
355    {
356  13 return tree;
357    }
358   
359    /**
360    * DOCUMENT ME!
361    *
362    * @param e
363    * DOCUMENT ME!
364    */
 
365  0 toggle @Override
366    public void textbox_actionPerformed(ActionEvent e)
367    {
368  0 CutAndPasteTransfer cap = new CutAndPasteTransfer();
369   
370  0 String newTitle = getPanelTitle();
371   
372  0 NewickFile fout = new NewickFile(tree.getTopNode());
373  0 try
374    {
375  0 cap.setText(fout.print(tree.hasBootstrap(), tree.hasDistances(),
376    tree.hasRootDistance()));
377  0 Desktop.addInternalFrame(cap, newTitle, 500, 100);
378    } catch (OutOfMemoryError oom)
379    {
380  0 new OOMWarning("generating newick tree file", oom);
381  0 cap.dispose();
382    }
383   
384    }
385   
386    /**
387    * DOCUMENT ME!
388    *
389    * @param e
390    * DOCUMENT ME!
391    */
 
392  0 toggle @Override
393    public void saveAsNewick_actionPerformed(ActionEvent e)
394    {
395    // TODO: JAL-3048 save newick file for Jalview-JS
396  0 JalviewFileChooser chooser = new JalviewFileChooser(
397    jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
398  0 chooser.setFileView(new JalviewFileView());
399  0 chooser.setDialogTitle(
400    MessageManager.getString("label.save_tree_as_newick"));
401  0 chooser.setToolTipText(MessageManager.getString("action.save"));
402   
403  0 int value = chooser.showSaveDialog(null);
404   
405  0 if (value == JalviewFileChooser.APPROVE_OPTION)
406    {
407  0 String choice = chooser.getSelectedFile().getPath();
408  0 jalview.bin.Cache.setProperty("LAST_DIRECTORY",
409    chooser.getSelectedFile().getParent());
410   
411  0 try
412    {
413  0 jalview.io.NewickFile fout = new jalview.io.NewickFile(
414    tree.getTopNode());
415  0 String output = fout.print(tree.hasBootstrap(), tree.hasDistances(),
416    tree.hasRootDistance());
417  0 java.io.PrintWriter out = new java.io.PrintWriter(
418    new java.io.FileWriter(choice));
419  0 out.println(output);
420  0 out.close();
421    } catch (Exception ex)
422    {
423  0 ex.printStackTrace();
424    }
425    }
426    }
427   
428    /**
429    * DOCUMENT ME!
430    *
431    * @param e
432    * DOCUMENT ME!
433    */
 
434  0 toggle @Override
435    public void printMenu_actionPerformed(ActionEvent e)
436    {
437    // Putting in a thread avoids Swing painting problems
438  0 treeCanvas.startPrinting();
439    }
440   
 
441  0 toggle @Override
442    public void originalSeqData_actionPerformed(ActionEvent e)
443    {
444  0 AlignmentView originalData = tree.getOriginalData();
445  0 if (originalData == null)
446    {
447  0 jalview.bin.Cache.log.info(
448    "Unexpected call to originalSeqData_actionPerformed - should have hidden this menu action.");
449  0 return;
450    }
451    // decide if av alignment is sufficiently different to original data to
452    // warrant a new window to be created
453    // create new alignmnt window with hidden regions (unhiding hidden regions
454    // yields unaligned seqs)
455    // or create a selection box around columns in alignment view
456    // test Alignment(SeqCigar[])
457  0 char gc = '-';
458  0 try
459    {
460    // we try to get the associated view's gap character
461    // but this may fail if the view was closed...
462  0 gc = av.getGapCharacter();
463   
464    } catch (Exception ex)
465    {
466    }
467   
468  0 Object[] alAndColsel = originalData.getAlignmentAndHiddenColumns(gc);
469   
470  0 if (alAndColsel != null && alAndColsel[0] != null)
471    {
472    // AlignmentOrder origorder = new AlignmentOrder(alAndColsel[0]);
473   
474  0 AlignmentI al = new Alignment((SequenceI[]) alAndColsel[0]);
475  0 AlignmentI dataset = (av != null && av.getAlignment() != null)
476    ? av.getAlignment().getDataset()
477    : null;
478  0 if (dataset != null)
479    {
480  0 al.setDataset(dataset);
481    }
482   
483  0 if (true)
484    {
485    // make a new frame!
486  0 AlignFrame af = new AlignFrame(al, (HiddenColumns) alAndColsel[1],
487    AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
488   
489    // >>>This is a fix for the moment, until a better solution is
490    // found!!<<<
491    // af.getFeatureRenderer().transferSettings(alignFrame.getFeatureRenderer());
492   
493    // af.addSortByOrderMenuItem(ServiceName + " Ordering",
494    // msaorder);
495   
496  0 Desktop.addInternalFrame(af, MessageManager.formatMessage(
497    "label.original_data_for_params", new Object[]
498    { this.title }), AlignFrame.DEFAULT_WIDTH,
499    AlignFrame.DEFAULT_HEIGHT);
500    }
501    }
502    }
503   
504    /**
505    * DOCUMENT ME!
506    *
507    * @param e
508    * DOCUMENT ME!
509    */
 
510  8 toggle @Override
511    public void fitToWindow_actionPerformed(ActionEvent e)
512    {
513  8 treeCanvas.fitToWindow = fitToWindow.isSelected();
514  8 repaint();
515    }
516   
517    /**
518    * sort the associated alignment view by the current tree.
519    *
520    * @param e
521    */
 
522  0 toggle @Override
523    public void sortByTree_actionPerformed()
524    {
525   
526  0 if (treeCanvas.applyToAllViews)
527    {
528  0 final ArrayList<CommandI> commands = new ArrayList<>();
529  0 for (AlignmentPanel ap : PaintRefresher
530    .getAssociatedPanels(av.getSequenceSetId()))
531    {
532  0 commands.add(sortAlignmentIn(ap.av.getAlignPanel()));
533    }
534  0 av.getAlignPanel().alignFrame.addHistoryItem(new CommandI()
535    {
536   
 
537  0 toggle @Override
538    public void undoCommand(AlignmentI[] views)
539    {
540  0 for (CommandI tsort : commands)
541    {
542  0 tsort.undoCommand(views);
543    }
544    }
545   
 
546  0 toggle @Override
547    public int getSize()
548    {
549  0 return commands.size();
550    }
551   
 
552  0 toggle @Override
553    public String getDescription()
554    {
555  0 return "Tree Sort (many views)";
556    }
557   
 
558  0 toggle @Override
559    public void doCommand(AlignmentI[] views)
560    {
561   
562  0 for (CommandI tsort : commands)
563    {
564  0 tsort.doCommand(views);
565    }
566    }
567    });
568  0 for (AlignmentPanel ap : PaintRefresher
569    .getAssociatedPanels(av.getSequenceSetId()))
570    {
571    // ensure all the alignFrames refresh their GI after adding an undo item
572  0 ap.alignFrame.updateEditMenuBar();
573    }
574    }
575    else
576    {
577  0 treeCanvas.getAssociatedPanel().alignFrame
578    .addHistoryItem(
579    sortAlignmentIn(treeCanvas.getAssociatedPanel()));
580    }
581   
582    }
583   
 
584  0 toggle public CommandI sortAlignmentIn(AlignmentPanel ap)
585    {
586    // TODO: move to alignment view controller
587  0 AlignmentViewport viewport = ap.av;
588  0 SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
589  0 AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
590  0 CommandI undo;
591  0 undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment());
592   
593  0 ap.paintAlignment(true, false);
594  0 return undo;
595    }
596   
597    /**
598    * DOCUMENT ME!
599    *
600    * @param e
601    * DOCUMENT ME!
602    */
 
603  0 toggle @Override
604    public void font_actionPerformed(ActionEvent e)
605    {
606  0 if (treeCanvas == null)
607    {
608  0 return;
609    }
610   
611  0 new FontChooser(this);
612    }
613   
 
614  6 toggle public Font getTreeFont()
615    {
616  6 return treeCanvas.font;
617    }
618   
 
619  8 toggle public void setTreeFont(Font f)
620    {
621  8 if (treeCanvas != null)
622    {
623  8 treeCanvas.setFont(f);
624    }
625    }
626   
627    /**
628    * DOCUMENT ME!
629    *
630    * @param e
631    * DOCUMENT ME!
632    */
 
633  0 toggle @Override
634    public void distanceMenu_actionPerformed(ActionEvent e)
635    {
636  0 treeCanvas.setShowDistances(distanceMenu.isSelected());
637    }
638   
639    /**
640    * DOCUMENT ME!
641    *
642    * @param e
643    * DOCUMENT ME!
644    */
 
645  0 toggle @Override
646    public void bootstrapMenu_actionPerformed(ActionEvent e)
647    {
648  0 treeCanvas.setShowBootstrap(bootstrapMenu.isSelected());
649    }
650   
651    /**
652    * DOCUMENT ME!
653    *
654    * @param e
655    * DOCUMENT ME!
656    */
 
657  0 toggle @Override
658    public void placeholdersMenu_actionPerformed(ActionEvent e)
659    {
660  0 treeCanvas.setMarkPlaceholders(placeholdersMenu.isSelected());
661    }
662   
663    /**
664    * Outputs the Tree in image format (currently EPS or PNG). The user is
665    * prompted for the file to save to, and for EPS (unless a preference is
666    * already set) for the choice of Text or Lineart for character rendering.
667    */
 
668  0 toggle @Override
669    public void writeTreeImage(TYPE imageFormat)
670    {
671  0 int width = treeCanvas.getWidth();
672  0 int height = treeCanvas.getHeight();
673  0 ImageWriterI writer = new ImageWriterI()
674    {
 
675  0 toggle @Override
676    public void exportImage(Graphics g) throws Exception
677    {
678  0 treeCanvas.draw(g, width, height);
679    }
680    };
681  0 String tree = MessageManager.getString("label.tree");
682  0 ImageExporter exporter = new ImageExporter(writer, null, imageFormat,
683    tree);
684  0 exporter.doExport(null, this, width, height, tree.toLowerCase());
685    }
686   
687    /**
688    * change node labels to the annotation referred to by labelClass TODO:
689    * promote to a datamodel modification that can be undone TODO: make argument
690    * one case of a generic transformation function ie { undoStep = apply(Tree,
691    * TransformFunction)};
692    *
693    * @param labelClass
694    */
 
695  0 toggle public void changeNames(final String labelClass)
696    {
697  0 tree.applyToNodes(new NodeTransformI()
698    {
699   
 
700  0 toggle @Override
701    public void transform(BinaryNode node)
702    {
703  0 if (node instanceof SequenceNode
704    && !((SequenceNode) node).isPlaceholder()
705    && !((SequenceNode) node).isDummy())
706    {
707  0 String newname = null;
708  0 SequenceI sq = (SequenceI) ((SequenceNode) node).element();
709  0 if (sq != null)
710    {
711    // search dbrefs, features and annotation
712  0 List<DBRefEntry> refs = jalview.util.DBRefUtils
713    .selectRefs(sq.getDBRefs(), new String[]
714    { labelClass.toUpperCase() });
715  0 if (refs != null)
716    {
717  0 for (int i = 0, ni = refs.size(); i < ni; i++)
718    {
719  0 if (newname == null)
720    {
721  0 newname = new String(refs.get(i).getAccessionId());
722    }
723    else
724    {
725  0 newname += "; " + refs.get(i).getAccessionId();
726    }
727    }
728    }
729  0 if (newname == null)
730    {
731  0 List<SequenceFeature> features = sq.getFeatures()
732    .getPositionalFeatures(labelClass);
733  0 for (SequenceFeature feature : features)
734    {
735  0 if (newname == null)
736    {
737  0 newname = feature.getDescription();
738    }
739    else
740    {
741  0 newname = newname + "; " + feature.getDescription();
742    }
743    }
744    }
745    }
746  0 if (newname != null)
747    {
748    // String oldname = ((SequenceNode) node).getName();
749    // TODO : save oldname in the undo object for this modification.
750  0 ((SequenceNode) node).setName(newname);
751    }
752    }
753    }
754    });
755    }
756   
757    /**
758    * Formats a localised title for the tree panel, like
759    * <p>
760    * Neighbour Joining Using BLOSUM62
761    * <p>
762    * For a tree loaded from file, just uses the file name
763    *
764    * @return
765    */
 
766  0 toggle public String getPanelTitle()
767    {
768  0 if (treeTitle != null)
769    {
770  0 return treeTitle;
771    }
772   
773    /*
774    * i18n description of Neighbour Joining or Average Distance method
775    */
776  0 String treecalcnm = MessageManager
777    .getString("label.tree_calc_" + treeType.toLowerCase());
778   
779    /*
780    * short score model name (long description can be too long)
781    */
782  0 String smn = scoreModelName;
783   
784    /*
785    * put them together as <method> Using <model>
786    */
787  0 final String ttl = MessageManager.formatMessage("label.calc_title",
788    treecalcnm, smn);
789  0 return ttl;
790    }
791   
792    /**
793    * Builds an EPS image and writes it to the specified file.
794    *
795    * @param outFile
796    * @param textOption
797    * true for Text character rendering, false for Lineart
798    */
 
799  0 toggle protected void writeEpsFile(File outFile, boolean textOption)
800    {
801  0 try
802    {
803  0 int width = treeCanvas.getWidth();
804  0 int height = treeCanvas.getHeight();
805   
806  0 FileOutputStream out = new FileOutputStream(
807    outFile);
808  0 EpsGraphics2D pg = new EpsGraphics2D("Tree", out, 0, 0, width,
809    height);
810  0 pg.setAccurateTextMode(!textOption);
811  0 treeCanvas.draw(pg, width, height);
812   
813  0 pg.flush();
814  0 pg.close();
815    } catch (Exception ex)
816    {
817  0 System.err.println("Error writing tree as EPS");
818  0 ex.printStackTrace();
819    }
820    }
821   
 
822  0 toggle public AlignViewport getViewport()
823    {
824  0 return av;
825    }
826   
 
827  0 toggle public void setViewport(AlignViewport av)
828    {
829  0 this.av = av;
830    }
831   
 
832  23 toggle public TreeCanvas getTreeCanvas()
833    {
834  23 return treeCanvas;
835    }
836    }