removed applet code
[jalview.git] / forester / java / src / org / forester / archaeopteryx / MainFrame.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2010 Christian M. Zmasek
6 // All rights reserved
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21 //
22 // Contact: phylosoft @ gmail . com
23 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
24
25 package org.forester.archaeopteryx;
26
27 import java.awt.Color;
28 import java.awt.Component;
29 import java.awt.Container;
30 import java.awt.Font;
31 import java.awt.event.ActionEvent;
32 import java.awt.event.ActionListener;
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Locale;
39 import java.util.Map;
40 import java.util.NoSuchElementException;
41
42 import javax.swing.Box;
43 import javax.swing.JCheckBoxMenuItem;
44 import javax.swing.JFileChooser;
45 import javax.swing.JFrame;
46 import javax.swing.JLabel;
47 import javax.swing.JMenu;
48 import javax.swing.JMenuBar;
49 import javax.swing.JMenuItem;
50 import javax.swing.JOptionPane;
51 import javax.swing.JPanel;
52 import javax.swing.JRadioButtonMenuItem;
53 import javax.swing.JTextField;
54 import javax.swing.SwingUtilities;
55 import javax.swing.filechooser.FileFilter;
56
57 import org.forester.archaeopteryx.AptxUtil.GraphicsExportType;
58 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;
59 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
60 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;
61 import org.forester.archaeopteryx.tools.AncestralTaxonomyInferrer;
62 import org.forester.archaeopteryx.tools.InferenceManager;
63 import org.forester.archaeopteryx.tools.ProcessPool;
64 import org.forester.archaeopteryx.tools.ProcessRunning;
65 import org.forester.io.parsers.nhx.NHXParser.TAXONOMY_EXTRACTION;
66 import org.forester.io.writers.PhylogenyWriter;
67 import org.forester.phylogeny.Phylogeny;
68 import org.forester.phylogeny.PhylogenyMethods;
69 import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY;
70 import org.forester.phylogeny.PhylogenyNode;
71 import org.forester.phylogeny.PhylogenyNode.NH_CONVERSION_SUPPORT_VALUE_STYLE;
72 import org.forester.phylogeny.data.Annotation;
73 import org.forester.phylogeny.data.NodeDataField;
74 import org.forester.phylogeny.data.NodeVisualData.NodeFill;
75 import org.forester.phylogeny.data.NodeVisualData.NodeShape;
76 import org.forester.phylogeny.iterators.PhylogenyNodeIterator;
77 import org.forester.sdi.GSDI;
78 import org.forester.sdi.GSDIR;
79 import org.forester.sdi.SDIException;
80 import org.forester.util.ForesterConstants;
81 import org.forester.util.ForesterUtil;
82 import org.forester.util.WindowsUtils;
83
84 public abstract class MainFrame extends JFrame implements ActionListener {
85
86     final static NHFilter            nhfilter                                = new NHFilter();
87     final static NHXFilter           nhxfilter                               = new NHXFilter();
88     final static XMLFilter           xmlfilter                               = new XMLFilter();
89     final static TolFilter           tolfilter                               = new TolFilter();
90     final static NexusFilter         nexusfilter                             = new NexusFilter();
91     final static PdfFilter           pdffilter                               = new PdfFilter();
92     final static GraphicsFileFilter  graphicsfilefilter                      = new GraphicsFileFilter();
93     final static MsaFileFilter       msafilter                               = new MsaFileFilter();
94     final static SequencesFileFilter seqsfilter                              = new SequencesFileFilter();
95     final static DefaultFilter       defaultfilter                           = new DefaultFilter();
96     static final String              USE_MOUSEWHEEL_SHIFT_TO_ROTATE          = "rotate with mousewheel + Shift (or A and S), D toggles between horizontal and radial labels";
97     static final String              PHYLOXML_REF_TOOL_TIP                   = AptxConstants.PHYLOXML_REFERENCE;                                                                                                                                                //TODO //FIXME
98     static final String              APTX_REF_TOOL_TIP                       = AptxConstants.APTX_REFERENCE;
99     private static final long        serialVersionUID                        = 3655000897845508358L;
100     final static Font                menu_font                               = new Font( Configuration.getDefaultFontFamilyName(),
101                                                                                          Font.PLAIN,
102                                                                                          10 );
103     static final String              TYPE_MENU_HEADER                        = "Type";
104     static final String              RECTANGULAR_TYPE_CBMI_LABEL             = "Rectangular";
105     static final String              EURO_TYPE_CBMI_LABEL                    = "Euro Type";
106     static final String              CURVED_TYPE_CBMI_LABEL                  = "Curved";
107     static final String              TRIANGULAR_TYPE_CBMI_LABEL              = "Triangular";
108     static final String              CONVEX_TYPE_CBMI_LABEL                  = "Convex";
109     static final String              ROUNDED_TYPE_CBMI_LABEL                 = "Rounded";
110     static final String              UNROOTED_TYPE_CBMI_LABEL                = "Unrooted (alpha)";                                                                                                                                                          //TODO
111     static final String              CIRCULAR_TYPE_CBMI_LABEL                = "Circular (alpha)";                                                                                                                                                          //TODO
112     static final String              OPTIONS_HEADER                          = "Options";
113     static final String              SEARCH_SUBHEADER                        = "Search:";
114     static final String              DISPLAY_SUBHEADER                       = "Display:";
115     static final String              SEARCH_TERMS_ONLY_LABEL                 = "Words";
116     static final String              SEARCH_REGEX_LABEL                      = "Regex";
117     static final String              SEARCH_CASE_SENSITIVE_LABEL             = "Match Case";
118     static final String              INVERSE_SEARCH_RESULT_LABEL             = "Inverse";
119     static final String              COLOR_BY_TAXONOMIC_GROUP                = "Colorize by Taxonomic Group";
120     static final String              DISPLAY_SCALE_LABEL                     = "Scale";
121     static final String              NON_LINED_UP_CLADOGRAMS_LABEL           = "Non-Lined Up Cladogram";
122     static final String              LABEL_DIRECTION_LABEL                   = "Radial Labels";
123     static final String              LABEL_DIRECTION_TIP                     = "To use radial node labels in radial and unrooted display types";
124     static final String              SEARCH_WITH_REGEX_TIP                   = "To search using regular expressions (~Java/Perl syntax). For example, use \"^B.+\\d{2,}$\" to search for everything starting with a B and ending with at least two digits.";
125     static final String              SCREEN_ANTIALIAS_LABEL                  = "Antialias";
126     static final String              COLOR_LABELS_LABEL                      = "Colorize Labels Same as Parent Branch";
127     static final String              BG_GRAD_LABEL                           = "Background Color Gradient";
128     static final String              DISPLAY_NODE_BOXES_LABEL_EXT            = "Shapes for External Nodes";
129     static final String              DISPLAY_NODE_BOXES_LABEL_INT            = "Shapes for Internal Nodes";
130     static final String              DISPLAY_NODE_BOXES_LABEL_MARKED         = "Shapes for Nodes with Visual Data";
131     static final String              SHOW_OVERVIEW_LABEL                     = "Overview";
132     static final String              FONT_SIZE_MENU_LABEL                    = "Font Size";
133     static final String              NONUNIFORM_CLADOGRAMS_LABEL             = "Lined Up Cladogram";
134     static final String              SHOW_DOMAIN_LABELS_LABEL                = "Domain Labels";
135     static final String              SHOW_ANN_REF_SOURCE_LABEL               = "Seq Annotation Ref Sources";
136     static final String              COLOR_LABELS_TIP                        = "To use parent branch colors for node labels as well, need to turn off taxonomy dependent colorization and turn on branch colorization for this to become apparent";
137     static final String              ABBREV_SN_LABEL                         = "Abbreviate Scientific Taxonomic Names";
138     static final String              TAXONOMY_COLORIZE_NODE_SHAPES_LABEL     = "Colorize Node Shapes According to Taxonomy";
139     static final String              CYCLE_NODE_SHAPE_LABEL                  = "Cycle Node Shapes";
140     static final String              CYCLE_NODE_FILL_LABEL                   = "Cycle Node Fill Type";
141     static final String              CHOOSE_NODE_SIZE_LABEL                  = "Choose Node Shape Size";
142     static final String              SHOW_CONF_STDDEV_LABEL                  = "Confidence Standard Deviations";
143     static final String              USE_BRACKETS_FOR_CONF_IN_NH_LABEL       = "Use Brackets for Confidence Values";
144     static final String              USE_INTERNAL_NAMES_FOR_CONF_IN_NH_LABEL = "Use Internal Node Names for Confidence Values";
145     static final String              SHOW_BASIC_TREE_INFORMATION_LABEL       = "Basic Tree Information";
146     static final String              RIGHT_LINE_UP_DOMAINS                   = "Right-align Domain Architectures";
147     static final String              LINE_UP_RENDERABLE_DATA                 = "Line Up Diagrams (such as Domain Architectures)";
148     static final String              INFER_ANCESTOR_TAXONOMIES               = "Infer Ancestor Taxonomies";
149     static final String              OBTAIN_DETAILED_TAXONOMIC_INFORMATION   = "Obtain Detailed Taxonomic Information";
150     JMenuBar                         _jmenubar;
151     JMenu                            _file_jmenu;
152     JMenu                            _tools_menu;
153     JMenu                            _view_jmenu;
154     JMenu                            _options_jmenu;
155     JMenu                            _font_size_menu;
156     JMenu                            _help_jmenu;
157     JMenuItem[]                      _load_phylogeny_from_webservice_menu_items;
158     // Analysis menu
159     JMenu                            _analysis_menu;
160     JMenuItem                        _load_species_tree_item;
161     JMenuItem                        _gsdi_item;
162     JMenuItem                        _gsdir_item;
163     JMenuItem                        _lineage_inference;
164     // file menu:
165     JMenuItem                        _open_item;
166     JMenuItem                        _open_url_item;
167     JMenuItem                        _save_item;
168     JMenuItem                        _save_all_item;
169     JMenuItem                        _close_item;
170     JMenuItem                        _exit_item;
171     JMenuItem                        _new_item;
172     JMenuItem                        _print_item;
173     JMenuItem                        _write_to_pdf_item;
174     JMenuItem                        _write_to_jpg_item;
175     JMenuItem                        _write_to_gif_item;
176     JMenuItem                        _write_to_tif_item;
177     JMenuItem                        _write_to_png_item;
178     JMenuItem                        _write_to_bmp_item;
179     // tools menu:
180     JMenuItem                        _midpoint_root_item;
181     JMenuItem                        _taxcolor_item;
182     JMenuItem                        _confcolor_item;
183     JMenuItem                        _color_rank_jmi;
184     JMenuItem                        _collapse_species_specific_subtrees;
185     
186     JMenuItem                        _obtain_detailed_taxonomic_information_jmi;
187     JMenuItem                        _obtain_detailed_taxonomic_information_deleting_jmi;
188     JMenuItem                        _obtain_seq_information_jmi;
189     JMenuItem                        _move_node_names_to_tax_sn_jmi;
190     JMenuItem                        _move_node_names_to_seq_names_jmi;
191     JMenuItem                        _extract_tax_code_from_node_names_jmi;
192     JMenuItem                        _annotate_item;
193     JMenuItem                        _remove_branch_color_item;
194     JMenuItem                        _remove_visual_styles_item;
195     JMenuItem                        _delete_selected_nodes_item;
196     JMenuItem                        _delete_not_selected_nodes_item;
197     // font size menu:
198     JMenuItem                        _super_tiny_fonts_item;
199     JMenuItem                        _tiny_fonts_item;
200     JMenuItem                        _small_fonts_item;
201     JMenuItem                        _medium_fonts_item;
202     JMenuItem                        _large_fonts_item;
203     // options menu:
204     // _  screen and print
205     JMenuItem                        _choose_font_mi;
206     JMenuItem                        _switch_colors_mi;
207     JCheckBoxMenuItem                _label_direction_cbmi;
208     // _  screen display
209     JCheckBoxMenuItem                _screen_antialias_cbmi;
210     JCheckBoxMenuItem                _background_gradient_cbmi;
211     JRadioButtonMenuItem             _non_lined_up_cladograms_rbmi;
212     JRadioButtonMenuItem             _ext_node_dependent_cladogram_rbmi;
213     JCheckBoxMenuItem                _color_by_taxonomic_group_cbmi;
214     JCheckBoxMenuItem                _show_scale_cbmi;                                                                                                                                                                                                      //TODO fix me
215     JCheckBoxMenuItem                _show_overview_cbmi;
216     JCheckBoxMenuItem                _show_domain_labels;
217     JCheckBoxMenuItem                _show_annotation_ref_source;
218     JCheckBoxMenuItem                _abbreviate_scientific_names;
219     JCheckBoxMenuItem                _color_labels_same_as_parent_branch;
220     JMenuItem                        _overview_placment_mi;
221     JMenuItem                        _choose_minimal_confidence_mi;
222     JCheckBoxMenuItem                _show_default_node_shapes_internal_cbmi;
223     JCheckBoxMenuItem                _show_default_node_shapes_external_cbmi;
224     JCheckBoxMenuItem                _show_default_node_shapes_for_marked_cbmi;
225     JMenuItem                        _cycle_node_shape_mi;
226     JMenuItem                        _cycle_node_fill_mi;
227     JMenuItem                        _choose_node_size_mi;
228     JMenuItem                        _cycle_data_return;
229     JCheckBoxMenuItem                _show_confidence_stddev_cbmi;
230     JCheckBoxMenuItem                _right_line_up_domains_cbmi;
231     JCheckBoxMenuItem                _line_up_renderable_data_cbmi;
232     JCheckBoxMenuItem                _collapsed_with_average_height_cbmi;
233     JCheckBoxMenuItem                _show_abbreviated_labels_for_collapsed_nodes_cbmi;
234     // _  print
235     JCheckBoxMenuItem                _graphics_export_visible_only_cbmi;
236     JCheckBoxMenuItem                _antialias_print_cbmi;
237     JCheckBoxMenuItem                _print_black_and_white_cbmi;
238     //JMenuItem                        _print_size_mi;
239     JMenuItem                        _choose_pdf_width_mi;
240     // _  parsing
241     JCheckBoxMenuItem                _internal_number_are_confidence_for_nh_parsing_cbmi;
242     JRadioButtonMenuItem             _extract_taxonomy_no_rbmi;
243     JRadioButtonMenuItem             _extract_taxonomy_agressive_rbmi;
244     JRadioButtonMenuItem             _extract_taxonomy_pfam_strict_rbmi;
245     JRadioButtonMenuItem             _extract_taxonomy_pfam_relaxed_rbmi;
246     JCheckBoxMenuItem                _replace_underscores_cbmi;
247     JCheckBoxMenuItem                _allow_errors_in_distance_to_parent_cbmi;
248     JCheckBoxMenuItem                _use_brackets_for_conf_in_nh_export_cbmi;
249     JCheckBoxMenuItem                _use_internal_names_for_conf_in_nh_export_cbmi;
250     JCheckBoxMenuItem                _parse_beast_style_extended_nexus_tags_cbmi;
251     // _  search
252     JCheckBoxMenuItem                _search_case_senstive_cbmi;
253     JCheckBoxMenuItem                _search_whole_words_only_cbmi;
254     JCheckBoxMenuItem                _inverse_search_result_cbmi;
255     JCheckBoxMenuItem                _search_with_regex_cbmi;
256     JCheckBoxMenuItem                _color_all_found_nodes_when_coloring_subtree_cbmi;
257     // type menu:
258     JMenu                            _type_menu;
259     JCheckBoxMenuItem                _rectangular_type_cbmi;
260     JCheckBoxMenuItem                _triangular_type_cbmi;
261     JCheckBoxMenuItem                _curved_type_cbmi;
262     JCheckBoxMenuItem                _convex_type_cbmi;
263     JCheckBoxMenuItem                _euro_type_cbmi;
264     JCheckBoxMenuItem                _rounded_type_cbmi;
265     JCheckBoxMenuItem                _unrooted_type_cbmi;
266     JCheckBoxMenuItem                _circular_type_cbmi;
267     // view as text menu:
268     JMenuItem                        _view_as_NH_item;
269     JMenuItem                        _view_as_XML_item;
270     JMenuItem                        _view_as_nexus_item;
271     JMenuItem                        _display_basic_information_item;
272     // help menu:
273     JMenuItem                        _about_item;
274     JMenuItem                        _help_item;
275     JMenuItem                        _website_item;
276     JMenuItem                        _mailing_list_item;
277     JMenuItem                        _phyloxml_website_item;
278     JMenuItem                        _phyloxml_ref_item;
279     JMenuItem                        _aptx_ref_item;
280     //
281     File                             _current_dir;
282     JFileChooser                     _writetopdf_filechooser;
283     JFileChooser                     _save_filechooser;
284     JFileChooser                     _writetographics_filechooser;
285     // process menu:
286     JMenu                            _process_menu;
287     MainPanel                        _mainpanel;
288     Container                        _contentpane;
289     final LinkedList<TextFrame>      _textframes                             = new LinkedList<TextFrame>();                                                                                                                                                  ;
290     Configuration                    _configuration;
291     Options                          _options;
292     private Phylogeny                _species_tree;
293     InferenceManager                 _inference_manager;
294     final ProcessPool                _process_pool;
295     private String                   _previous_node_annotation_ref;
296
297     MainFrame() {
298         _process_pool = ProcessPool.createInstance();
299         _writetopdf_filechooser = new JFileChooser();
300         _writetopdf_filechooser.setMultiSelectionEnabled( false );
301         _writetopdf_filechooser.addChoosableFileFilter( pdffilter );
302         _writetographics_filechooser = new JFileChooser();
303         _writetographics_filechooser.setMultiSelectionEnabled( false );
304         _writetographics_filechooser.addChoosableFileFilter( graphicsfilefilter );
305         _save_filechooser = new JFileChooser();
306         _save_filechooser.setMultiSelectionEnabled( false );
307         _save_filechooser.setFileFilter( xmlfilter );
308         _save_filechooser.addChoosableFileFilter( nhfilter );
309         _save_filechooser.addChoosableFileFilter( nexusfilter );
310         _save_filechooser.addChoosableFileFilter( _save_filechooser.getAcceptAllFileFilter() );
311         try {
312             final String home_dir = System.getProperty( "user.home" );
313             _save_filechooser.setCurrentDirectory( new File( home_dir ) );
314             _writetopdf_filechooser.setCurrentDirectory( new File( home_dir ) );
315             _writetographics_filechooser.setCurrentDirectory( new File( home_dir ) );
316         }
317         catch ( final Exception e ) {
318             e.printStackTrace();
319             // Do nothing. Not important.
320         }
321     }
322
323     /**
324      * Action performed.
325      */
326     @Override
327     public void actionPerformed( final ActionEvent e ) {
328         final Object o = e.getSource();
329       
330         if ( o == _exit_item ) {
331             close();
332         }
333         else if ( o == _gsdi_item ) {
334             if ( isSubtreeDisplayed() ) {
335                 return;
336             }
337             executeGSDI();
338         }
339         else if ( o == _gsdir_item ) {
340             if ( isSubtreeDisplayed() ) {
341                 return;
342             }
343             executeGSDIR();
344         }
345         else if ( o == _taxcolor_item ) {
346             taxColor();
347         }
348         else if ( o == _confcolor_item ) {
349             confColor();
350         }
351         else if ( o == _color_rank_jmi ) {
352             colorRank();
353         }
354         else if ( o == _collapse_species_specific_subtrees ) {
355             if ( isSubtreeDisplayed() ) {
356                 return;
357             }
358             if ( getCurrentTreePanel() != null ) {
359                 getCurrentTreePanel().collapseSpeciesSpecificSubtrees();
360             }
361         }
362         else if ( o == _remove_branch_color_item ) {
363             if ( isSubtreeDisplayed() ) {
364                 return;
365             }
366             removeBranchColors();
367         }
368         else if ( o == _remove_visual_styles_item ) {
369             if ( isSubtreeDisplayed() ) {
370                 return;
371             }
372             removeVisualStyles();
373         }
374         else if ( o == _midpoint_root_item ) {
375             if ( isSubtreeDisplayed() ) {
376                 return;
377             }
378             midpointRoot();
379         }
380         else if ( o == _delete_selected_nodes_item ) {
381             if ( isSubtreeDisplayed() ) {
382                 return;
383             }
384             deleteSelectedNodes( true );
385         }
386         else if ( o == _delete_not_selected_nodes_item ) {
387             if ( isSubtreeDisplayed() ) {
388                 return;
389             }
390             deleteSelectedNodes( false );
391         }
392         else if ( o == _annotate_item ) {
393             annotateSequences();
394         }
395         else if ( o == _switch_colors_mi ) {
396             switchColors();
397         }
398         else if ( o == _display_basic_information_item ) {
399             if ( getCurrentTreePanel() != null ) {
400                 displayBasicInformation( getCurrentTreePanel().getTreeFile() );
401             }
402         }
403         else if ( o == _view_as_NH_item ) {
404             viewAsNH();
405         }
406         else if ( o == _view_as_XML_item ) {
407             viewAsXML();
408         }
409         else if ( o == _view_as_nexus_item ) {
410             viewAsNexus();
411         }
412         else if ( o == _super_tiny_fonts_item ) {
413             if ( getCurrentTreePanel() != null ) {
414                 getCurrentTreePanel().setSuperTinyFonts();
415                 getCurrentTreePanel().repaint();
416             }
417         }
418         else if ( o == _tiny_fonts_item ) {
419             if ( getCurrentTreePanel() != null ) {
420                 getCurrentTreePanel().setTinyFonts();
421                 getCurrentTreePanel().repaint();
422             }
423         }
424         else if ( o == _small_fonts_item ) {
425             if ( getCurrentTreePanel() != null ) {
426                 getCurrentTreePanel().setSmallFonts();
427                 getCurrentTreePanel().repaint();
428             }
429         }
430         else if ( o == _medium_fonts_item ) {
431             if ( getCurrentTreePanel() != null ) {
432                 getCurrentTreePanel().setMediumFonts();
433                 getCurrentTreePanel().repaint();
434             }
435         }
436         else if ( o == _large_fonts_item ) {
437             if ( getCurrentTreePanel() != null ) {
438                 getCurrentTreePanel().setLargeFonts();
439                 getCurrentTreePanel().repaint();
440             }
441         }
442         else if ( o == _choose_font_mi ) {
443             chooseFont();
444         }
445         else if ( o == _choose_minimal_confidence_mi ) {
446             chooseMinimalConfidence();
447         }
448         else if ( o == _choose_node_size_mi ) {
449             chooseNodeSize( getOptions(), this );
450         }
451         else if ( o == _overview_placment_mi ) {
452             MainFrame.cycleOverview( getOptions(), getCurrentTreePanel() );
453         }
454         else if ( o == _cycle_node_fill_mi ) {
455             MainFrame.cycleNodeFill( getOptions() );
456         }
457         else if ( o == _cycle_node_shape_mi ) {
458             MainFrame.cycleNodeShape( getOptions() );
459         }
460         else if ( o == _cycle_data_return ) {
461             MainFrame.cycleNodeDataReturn( getOptions(), getConfiguration() );
462         }
463         else if ( o == _screen_antialias_cbmi ) {
464             updateOptions( getOptions() );
465             updateScreenTextAntialias( getMainPanel().getTreePanels() );
466         }
467         else if ( o == _background_gradient_cbmi ) {
468             updateOptions( getOptions() );
469         }
470         else if ( o == _show_domain_labels ) {
471             updateOptions( getOptions() );
472         }
473         else if ( o == _show_annotation_ref_source ) {
474             updateOptions( getOptions() );
475         }
476         else if ( o == _abbreviate_scientific_names ) {
477             updateOptions( getOptions() );
478         }
479         else if ( o == _color_labels_same_as_parent_branch ) {
480             updateOptions( getOptions() );
481         }
482         else if ( o == _show_default_node_shapes_internal_cbmi ) {
483             updateOptions( getOptions() );
484         }
485         else if ( o == _show_default_node_shapes_external_cbmi ) {
486             updateOptions( getOptions() );
487         }
488         else if ( o == _show_default_node_shapes_for_marked_cbmi ) {
489             updateOptions( getOptions() );
490         }
491         else if ( o == _non_lined_up_cladograms_rbmi ) {
492             updateOptions( getOptions() );
493             showWhole();
494         }
495         else if ( o == _ext_node_dependent_cladogram_rbmi ) {
496             updateOptions( getOptions() );
497             showWhole();
498         }
499         else if ( o == _search_case_senstive_cbmi ) {
500             if ( ( _search_with_regex_cbmi != null ) && _search_case_senstive_cbmi.isSelected() ) {
501                 _search_with_regex_cbmi.setSelected( false );
502             }
503             updateOptions( getOptions() );
504             getMainPanel().getControlPanel().search0();
505             getMainPanel().getControlPanel().search1();
506         }
507         else if ( o == _search_whole_words_only_cbmi ) {
508             if ( ( _search_with_regex_cbmi != null ) && _search_whole_words_only_cbmi.isSelected() ) {
509                 _search_with_regex_cbmi.setSelected( false );
510             }
511             updateOptions( getOptions() );
512             getMainPanel().getControlPanel().search0();
513             getMainPanel().getControlPanel().search1();
514         }
515         else if ( o == _inverse_search_result_cbmi ) {
516             updateOptions( getOptions() );
517             getMainPanel().getControlPanel().search0();
518             getMainPanel().getControlPanel().search1();
519         }
520         else if ( o == _search_with_regex_cbmi ) {
521             if ( ( _search_whole_words_only_cbmi != null ) && _search_with_regex_cbmi.isSelected() ) {
522                 _search_whole_words_only_cbmi.setSelected( false );
523             }
524             if ( ( _search_case_senstive_cbmi != null ) && _search_with_regex_cbmi.isSelected() ) {
525                 _search_case_senstive_cbmi.setSelected( false );
526             }
527             updateOptions( getOptions() );
528             getMainPanel().getControlPanel().search0();
529             getMainPanel().getControlPanel().search1();
530         }
531         else if ( o == _color_all_found_nodes_when_coloring_subtree_cbmi ) {
532             updateOptions( getOptions() );
533         }
534         else if ( o == _parse_beast_style_extended_nexus_tags_cbmi ) {
535             updateOptions( getOptions() );
536         }
537         else if ( o == _show_scale_cbmi ) {
538             updateOptions( getOptions() );
539         }
540         else if ( o == _color_by_taxonomic_group_cbmi ) {
541             updateOptions( getOptions() );
542         }
543         else if ( o == _show_confidence_stddev_cbmi ) {
544             updateOptions( getOptions() );
545         }
546         else if ( o == _use_brackets_for_conf_in_nh_export_cbmi ) {
547             if ( _use_brackets_for_conf_in_nh_export_cbmi.isSelected() ) {
548                 _use_internal_names_for_conf_in_nh_export_cbmi.setSelected( false );
549             }
550             updateOptions( getOptions() );
551         }
552         else if ( o == _use_internal_names_for_conf_in_nh_export_cbmi ) {
553             if ( _use_internal_names_for_conf_in_nh_export_cbmi.isSelected() ) {
554                 _use_brackets_for_conf_in_nh_export_cbmi.setSelected( false );
555             }
556             updateOptions( getOptions() );
557         }
558         else if ( o == _label_direction_cbmi ) {
559             updateOptions( getOptions() );
560         }
561         else if ( o == _show_overview_cbmi ) {
562             updateOptions( getOptions() );
563             if ( getCurrentTreePanel() != null ) {
564                 getCurrentTreePanel().updateOvSizes();
565             }
566         }
567         else if ( o == _line_up_renderable_data_cbmi ) {
568             if ( !_line_up_renderable_data_cbmi.isSelected() ) {
569                 _right_line_up_domains_cbmi.setSelected( false );
570             }
571             updateOptions( getOptions() );
572         }
573         
574         else if ( o == _collapsed_with_average_height_cbmi ) {
575             if ( _collapsed_with_average_height_cbmi.isSelected() ) {
576                 _collapsed_with_average_height_cbmi.setSelected( true );
577             }
578             updateOptions( getOptions() );
579         }
580         else if ( o == _show_abbreviated_labels_for_collapsed_nodes_cbmi ) {
581             if ( _show_abbreviated_labels_for_collapsed_nodes_cbmi.isSelected() ) {
582                 _show_abbreviated_labels_for_collapsed_nodes_cbmi.setSelected( true );
583             }
584             updateOptions( getOptions() );
585         }
586         else if ( o == _right_line_up_domains_cbmi ) {
587             if ( _right_line_up_domains_cbmi.isSelected() ) {
588                 _line_up_renderable_data_cbmi.setSelected( true );
589             }
590             updateOptions( getOptions() );
591         }
592         else if ( ( o == _rectangular_type_cbmi ) || ( o == _triangular_type_cbmi ) || ( o == _curved_type_cbmi )
593                 || ( o == _convex_type_cbmi ) || ( o == _euro_type_cbmi ) || ( o == _rounded_type_cbmi )
594                 || ( o == _unrooted_type_cbmi ) || ( o == _circular_type_cbmi ) ) {
595             typeChanged( o );
596         }
597         else if ( o == _about_item ) {
598             about();
599         }
600         else if ( o == _help_item ) {
601             try {
602                 AptxUtil.openWebsite( AptxConstants.APTX_DOC_SITE );
603             }
604             catch ( final IOException e1 ) {
605                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
606             }
607         }
608         else if ( o == _website_item ) {
609             try {
610                 AptxUtil.openWebsite( AptxConstants.APTX_WEB_SITE);
611             }
612             catch ( final IOException e1 ) {
613                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
614             }
615         }
616         else if ( o == _mailing_list_item ) {
617             try {
618                 AptxUtil.openWebsite( AptxConstants.APTX_MAILING_LIST );
619             }
620             catch ( final IOException e1 ) {
621                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
622             }
623         }
624         else if ( o == _phyloxml_website_item ) {
625             try {
626                 AptxUtil.openWebsite( AptxConstants.PHYLOXML_WEB_SITE );
627             }
628             catch ( final IOException e1 ) {
629                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
630             }
631         }
632         else if ( o == _aptx_ref_item ) {
633             try {
634                 AptxUtil.openWebsite( AptxConstants.APTX_REFERENCE_URL );
635             }
636             catch ( final IOException e1 ) {
637                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
638             }
639         }
640         else if ( o == _phyloxml_ref_item ) {
641             try {
642                 AptxUtil.openWebsite( AptxConstants.PHYLOXML_REFERENCE_URL );
643             }
644             catch ( final IOException e1 ) {
645                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
646             }
647         }
648         else if ( o == _write_to_pdf_item ) {
649             final File curr_dir = writeToPdf( _mainpanel.getCurrentPhylogeny(),
650                                               getMainPanel(),
651                                               _writetopdf_filechooser,
652                                               _current_dir,
653                                               getContentPane(),
654                                               this );
655             if ( curr_dir != null ) {
656                 setCurrentDir( curr_dir );
657             }
658         }
659         else if ( o == _save_all_item ) {
660             writeAllToFile();
661         }
662         else if ( o == _write_to_jpg_item ) {
663             final File new_dir = writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
664                                                       GraphicsExportType.JPG,
665                                                       _mainpanel,
666                                                       _writetographics_filechooser,
667                                                       this,
668                                                       getContentPane(),
669                                                       _current_dir );
670             if ( new_dir != null ) {
671                 setCurrentDir( new_dir );
672             }
673         }
674         else if ( o == _write_to_gif_item ) {
675             final File new_dir = writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
676                                                       GraphicsExportType.GIF,
677                                                       _mainpanel,
678                                                       _writetographics_filechooser,
679                                                       this,
680                                                       getContentPane(),
681                                                       _current_dir );
682             if ( new_dir != null ) {
683                 setCurrentDir( new_dir );
684             }
685         }
686         else if ( o == _write_to_tif_item ) {
687             final File new_dir = writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
688                                                       GraphicsExportType.TIFF,
689                                                       _mainpanel,
690                                                       _writetographics_filechooser,
691                                                       this,
692                                                       getContentPane(),
693                                                       _current_dir );
694             if ( new_dir != null ) {
695                 setCurrentDir( new_dir );
696             }
697         }
698         else if ( o == _write_to_bmp_item ) {
699             final File new_dir = writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
700                                                       GraphicsExportType.BMP,
701                                                       _mainpanel,
702                                                       _writetographics_filechooser,
703                                                       this,
704                                                       getContentPane(),
705                                                       _current_dir );
706             if ( new_dir != null ) {
707                 setCurrentDir( new_dir );
708             }
709         }
710         else if ( o == _write_to_png_item ) {
711             final File new_dir = writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
712                                                       GraphicsExportType.PNG,
713                                                       _mainpanel,
714                                                       _writetographics_filechooser,
715                                                       this,
716                                                       getContentPane(),
717                                                       _current_dir );
718             if ( new_dir != null ) {
719                 setCurrentDir( new_dir );
720             }
721         }
722         else if ( o == _print_item ) {
723             print( getCurrentTreePanel(), getOptions(), this );
724         }
725         else if ( o == _save_item ) {
726             final File new_dir = writeToFile( _mainpanel.getCurrentPhylogeny(),
727                                               getMainPanel(),
728                                               _save_filechooser,
729                                               _current_dir,
730                                               getContentPane(),
731                                               this );
732             if ( new_dir != null ) {
733                 setCurrentDir( new_dir );
734             }
735         }
736         else if ( o == _graphics_export_visible_only_cbmi ) {
737             updateOptions( getOptions() );
738         }
739         else if ( o == _antialias_print_cbmi ) {
740             updateOptions( getOptions() );
741         }
742         else if ( o == _print_black_and_white_cbmi ) {
743             updateOptions( getOptions() );
744         }
745         else if ( o == _choose_pdf_width_mi ) {
746             choosePdfWidth();
747         }
748         else if ( o == _lineage_inference ) {
749             if ( isSubtreeDisplayed() ) {
750                 JOptionPane.showMessageDialog( this,
751                                                "Subtree is shown.",
752                                                "Cannot infer ancestral taxonomies",
753                                                JOptionPane.ERROR_MESSAGE );
754                 return;
755             }
756             executeLineageInference();
757         }
758         else {
759             if ( _load_phylogeny_from_webservice_menu_items != null ) {
760                 for( int i = 0; i < _load_phylogeny_from_webservice_menu_items.length; ++i ) {
761                     if ( o == _load_phylogeny_from_webservice_menu_items[ i ] ) {
762                         readPhylogeniesFromWebservice( i );
763                     }
764                 }
765             }
766         }
767         _contentpane.repaint();
768     }
769
770     public Configuration getConfiguration() {
771         return _configuration;
772     }
773
774     /**
775      * This method returns the current external node data which
776      * has been selected by the user by clicking the "Return ..."
777      * menu item. This method is expected to be called from Javascript or
778      * something like it.
779      *
780      * @return current external node data as String
781      */
782     public String getCurrentExternalNodesDataBuffer() {
783         return getCurrentTreePanel().getCurrentExternalNodesDataBufferAsString();
784     }
785
786     public int getCurrentExternalNodesDataBufferChangeCounter() {
787         return getCurrentTreePanel().getCurrentExternalNodesDataBufferChangeCounter();
788     }
789
790     public int getCurrentExternalNodesDataBufferLength() {
791         return getCurrentTreePanel().getCurrentExternalNodesDataBufferAsString().length();
792     }
793
794     public InferenceManager getInferenceManager() {
795         return _inference_manager;
796     }
797
798     public MainPanel getMainPanel() {
799         return _mainpanel;
800     }
801
802     public Options getOptions() {
803         return _options;
804     }
805
806     public ProcessPool getProcessPool() {
807         return _process_pool;
808     }
809
810     public void showTextFrame( final String s, final String title ) {
811         checkTextFrames();
812         _textframes.addLast( TextFrame.instantiate( s, title, _textframes ) );
813     }
814
815     public void showWhole() {
816         _mainpanel.getControlPanel().showWhole();
817     }
818
819     public void updateProcessMenu() {
820         // In general Swing is not thread safe.
821         // See "Swing's Threading Policy".
822         SwingUtilities.invokeLater( new Runnable() {
823
824             @Override
825             public void run() {
826                 doUpdateProcessMenu();
827             }
828         } );
829     }
830
831     private void annotateSequences() {
832         if ( getCurrentTreePanel() != null ) {
833             List<PhylogenyNode> nodes = null;
834             if ( ( getCurrentTreePanel().getFoundNodes0() != null )
835                     || ( getCurrentTreePanel().getFoundNodes1() != null ) ) {
836                 nodes = getCurrentTreePanel().getFoundNodesAsListOfPhylogenyNodes();
837             }
838             if ( ( nodes == null ) || nodes.isEmpty() ) {
839                 JOptionPane
840                         .showMessageDialog( this,
841                                             "Need to select nodes, either via direct selection or via the \"Search\" function",
842                                             "No nodes selected for annotation",
843                                             JOptionPane.ERROR_MESSAGE );
844                 return;
845             }
846             final Phylogeny phy = getMainPanel().getCurrentPhylogeny();
847             if ( ( phy != null ) && !phy.isEmpty() ) {
848                 final JTextField ref_field = new JTextField( 10 );
849                 final JTextField desc_filed = new JTextField( 20 );
850                 ref_field.setText( ForesterUtil.isEmpty( getPreviousNodeAnnotationReference() ) ? ""
851                         : getPreviousNodeAnnotationReference() );
852                 final JPanel my_panel = new JPanel();
853                 my_panel.add( new JLabel( "Reference " ) );
854                 my_panel.add( ref_field );
855                 my_panel.add( Box.createHorizontalStrut( 15 ) );
856                 my_panel.add( new JLabel( "Description " ) );
857                 my_panel.add( desc_filed );
858                 final int result = JOptionPane.showConfirmDialog( null,
859                                                                   my_panel,
860                                                                   "Enter the sequence annotation(s) for the "
861                                                                           + nodes.size() + " selected nodes",
862                                                                   JOptionPane.OK_CANCEL_OPTION );
863                 if ( result == JOptionPane.OK_OPTION ) {
864                     String ref = ref_field.getText();
865                     String desc = desc_filed.getText();
866                     if ( !ForesterUtil.isEmpty( ref ) ) {
867                         ref = ref.trim();
868                         ref = ref.replaceAll( "\\s+", " " );
869                         if ( ( ref.indexOf( ':' ) < 1 ) || ( ref.indexOf( ':' ) > ( ref.length() - 2 ) )
870                                 || ( ref.length() < 3 ) ) {
871                             JOptionPane.showMessageDialog( this,
872                                                            "Reference needs to be in the form of \"GO:1234567\"",
873                                                            "Illegal Format for Annotation Reference",
874                                                            JOptionPane.ERROR_MESSAGE );
875                             return;
876                         }
877                     }
878                     if ( ref != null ) {
879                         setPreviousNodeAnnotationReference( ref );
880                     }
881                     if ( desc != null ) {
882                         desc = desc.trim();
883                         desc = desc.replaceAll( "\\s+", " " );
884                     }
885                     if ( !ForesterUtil.isEmpty( ref ) || !ForesterUtil.isEmpty( desc ) ) {
886                         for( final PhylogenyNode n : nodes ) {
887                             ForesterUtil.ensurePresenceOfSequence( n );
888                             final Annotation ann = ForesterUtil.isEmpty( ref ) ? new Annotation()
889                                     : new Annotation( ref );
890                             if ( !ForesterUtil.isEmpty( desc ) ) {
891                                 ann.setDesc( desc );
892                             }
893                             n.getNodeData().getSequence().addAnnotation( ann );
894                         }
895                     }
896                     getMainPanel().getControlPanel().showAnnotations();
897                 }
898             }
899         }
900     }
901
902     private void chooseFont() {
903         final FontChooser fc = new FontChooser();
904         fc.setFont( getMainPanel().getTreeFontSet().getLargeFont() );
905         fc.showDialog( this, "Select the Base Font" );
906         getMainPanel().getTreeFontSet().setBaseFont( fc.getFont() );
907         getControlPanel().displayedPhylogenyMightHaveChanged( true );
908         if ( getMainPanel().getCurrentTreePanel() != null ) {
909             getMainPanel().getCurrentTreePanel().resetPreferredSize();
910             getMainPanel().getCurrentTreePanel().updateOvSizes();
911         }
912        
913         repaint();
914     }
915
916     private void chooseMinimalConfidence() {
917         final String s = ( String ) JOptionPane
918                 .showInputDialog( this,
919                                   "Please enter the minimum for confidence values to be displayed.\n"
920                                           + "[current value: " + getOptions().getMinConfidenceValue() + "]\n",
921                                   "Minimal Confidence Value",
922                                   JOptionPane.QUESTION_MESSAGE,
923                                   null,
924                                   null,
925                                   getOptions().getMinConfidenceValue() );
926         if ( !ForesterUtil.isEmpty( s ) ) {
927             boolean success = true;
928             double m = 0.0;
929             final String m_str = s.trim();
930             if ( !ForesterUtil.isEmpty( m_str ) ) {
931                 try {
932                     m = Double.parseDouble( m_str );
933                 }
934                 catch ( final Exception ex ) {
935                     success = false;
936                 }
937             }
938             else {
939                 success = false;
940             }
941             if ( success && ( m >= 0.0 ) ) {
942                 getOptions().setMinConfidenceValue( m );
943             }
944         }
945     }
946
947     private void deleteSelectedNodes( final boolean delete ) {
948         final Phylogeny phy = getMainPanel().getCurrentPhylogeny();
949         if ( ( phy == null ) || ( phy.getNumberOfExternalNodes() < 2 ) ) {
950             return;
951         }
952         final List<PhylogenyNode> nodes = new ArrayList<PhylogenyNode>();
953         if ( ( getCurrentTreePanel().getFoundNodes0() != null ) || ( getCurrentTreePanel().getFoundNodes1() != null ) ) {
954             final List<PhylogenyNode> all_selected_nodes = getCurrentTreePanel().getFoundNodesAsListOfPhylogenyNodes();
955             for( final PhylogenyNode n : all_selected_nodes ) {
956                 if ( n.isExternal() ) {
957                     nodes.add( n );
958                 }
959             }
960         }
961         String function = "Retain";
962         if ( delete ) {
963             function = "Delete";
964         }
965         if ( ( nodes == null ) || nodes.isEmpty() ) {
966             JOptionPane
967                     .showMessageDialog( this,
968                                         "Need to select external nodes, either via direct selection or via the \"Search\" function",
969                                         "No external nodes selected to " + function.toLowerCase(),
970                                         JOptionPane.ERROR_MESSAGE );
971             return;
972         }
973         final int todo = nodes.size();
974         final int ext = phy.getNumberOfExternalNodes();
975         int res = todo;
976         if ( delete ) {
977             res = ext - todo;
978         }
979         if ( res < 1 ) {
980             JOptionPane.showMessageDialog( this,
981                                            "Cannot delete all nodes",
982                                            "Attempt to delete all nodes ",
983                                            JOptionPane.ERROR_MESSAGE );
984             return;
985         }
986         final int result = JOptionPane.showConfirmDialog( null, function + " " + todo
987                 + " external node(s), from a total of " + ext + " external nodes," + "\nresulting in tree with " + res
988                 + " nodes?", function + " external nodes", JOptionPane.OK_CANCEL_OPTION );
989         if ( result == JOptionPane.OK_OPTION ) {
990             if ( !delete ) {
991                 final List<PhylogenyNode> to_delete = new ArrayList<PhylogenyNode>();
992                 for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
993                     final PhylogenyNode n = it.next();
994                     if ( !nodes.contains( n ) ) {
995                         to_delete.add( n );
996                     }
997                 }
998                 for( final PhylogenyNode n : to_delete ) {
999                     phy.deleteSubtree( n, true );
1000                 }
1001             }
1002             else {
1003                 for( final PhylogenyNode n : nodes ) {
1004                     phy.deleteSubtree( n, true );
1005                 }
1006             }
1007             resetSearch();
1008             getCurrentTreePanel().setNodeInPreorderToNull();
1009             phy.externalNodesHaveChanged();
1010             phy.clearHashIdToNodeMap();
1011             phy.recalculateNumberOfExternalDescendants( true );
1012             getCurrentTreePanel().resetNodeIdToDistToLeafMap();
1013             getCurrentTreePanel().setEdited( true );
1014             repaint();
1015         }
1016     }
1017
1018     private void doUpdateProcessMenu() {
1019         if ( _process_pool.size() > 0 ) {
1020             if ( _process_menu == null ) {
1021                 _process_menu = createMenu( "", getConfiguration() );
1022                 _process_menu.setForeground( Color.RED );
1023             }
1024             _process_menu.removeAll();
1025             final String text = "processes running: " + _process_pool.size();
1026             _process_menu.setText( text );
1027             _jmenubar.add( _process_menu );
1028             for( int i = 0; i < _process_pool.size(); ++i ) {
1029                 final ProcessRunning p = _process_pool.getProcessByIndex( i );
1030                 _process_menu.add( customizeJMenuItem( new JMenuItem( p.getName() + " [" + p.getStart() + "]" ) ) );
1031             }
1032         }
1033         else {
1034             if ( _process_menu != null ) {
1035                 _process_menu.removeAll();
1036                 _jmenubar.remove( _process_menu );
1037             }
1038         }
1039         _jmenubar.validate();
1040         _jmenubar.repaint();
1041         repaint();
1042     }
1043
1044     private String getPreviousNodeAnnotationReference() {
1045         return _previous_node_annotation_ref;
1046     }
1047
1048     private void removeBranchColors() {
1049         if ( getMainPanel().getCurrentPhylogeny() != null ) {
1050             AptxUtil.removeBranchColors( getMainPanel().getCurrentPhylogeny() );
1051         }
1052     }
1053
1054     private void removeVisualStyles() {
1055         if ( getMainPanel().getCurrentPhylogeny() != null ) {
1056             AptxUtil.removeVisualStyles( getMainPanel().getCurrentPhylogeny() );
1057         }
1058     }
1059
1060     private void setPreviousNodeAnnotationReference( final String previous_node_annotation_ref ) {
1061         _previous_node_annotation_ref = previous_node_annotation_ref;
1062     }
1063
1064     private void writeAllToFile() {
1065         if ( ( getMainPanel().getTabbedPane() == null ) || ( getMainPanel().getTabbedPane().getTabCount() < 1 ) ) {
1066             return;
1067         }
1068         final File my_dir = getCurrentDir();
1069         if ( my_dir != null ) {
1070             _save_filechooser.setCurrentDirectory( my_dir );
1071         }
1072         _save_filechooser.setSelectedFile( new File( "" ) );
1073         final int result = _save_filechooser.showSaveDialog( _contentpane );
1074         final File file = _save_filechooser.getSelectedFile();
1075         setCurrentDir( _save_filechooser.getCurrentDirectory() );
1076         if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
1077             if ( file.exists() ) {
1078                 final int i = JOptionPane.showConfirmDialog( this,
1079                                                              file + " already exists. Overwrite?",
1080                                                              "Warning",
1081                                                              JOptionPane.OK_CANCEL_OPTION,
1082                                                              JOptionPane.WARNING_MESSAGE );
1083                 if ( i != JOptionPane.OK_OPTION ) {
1084                     return;
1085                 }
1086                 else {
1087                     try {
1088                         file.delete();
1089                     }
1090                     catch ( final Exception e ) {
1091                         JOptionPane.showMessageDialog( this,
1092                                                        "Failed to delete: " + file,
1093                                                        "Error",
1094                                                        JOptionPane.WARNING_MESSAGE );
1095                     }
1096                 }
1097             }
1098             final int count = getMainPanel().getTabbedPane().getTabCount();
1099             final List<Phylogeny> trees = new ArrayList<Phylogeny>();
1100             for( int i = 0; i < count; ++i ) {
1101                 final Phylogeny phy = getMainPanel().getPhylogeny( i );
1102                 if ( ForesterUtil.isEmpty( phy.getName() )
1103                         && !ForesterUtil.isEmpty( getMainPanel().getTabbedPane().getTitleAt( i ) ) ) {
1104                     phy.setName( getMainPanel().getTabbedPane().getTitleAt( i ) );
1105                 }
1106                 trees.add( phy );
1107                 getMainPanel().getTreePanels().get( i ).setEdited( false );
1108             }
1109             final PhylogenyWriter writer = new PhylogenyWriter();
1110             try {
1111                 writer.toPhyloXML( file, trees, 0, ForesterUtil.LINE_SEPARATOR );
1112             }
1113             catch ( final IOException e ) {
1114                 JOptionPane.showMessageDialog( this,
1115                                                "Failed to write to: " + file,
1116                                                "Error",
1117                                                JOptionPane.WARNING_MESSAGE );
1118             }
1119         }
1120     }
1121
1122     void activateSaveAllIfNeeded() {
1123         if ( ( getMainPanel().getTabbedPane() != null ) && ( getMainPanel().getTabbedPane().getTabCount() > 1 ) ) {
1124             _save_all_item.setEnabled( true );
1125         }
1126         else {
1127             _save_all_item.setEnabled( false );
1128         }
1129     }
1130
1131     void buildFileMenu() {
1132         _file_jmenu = MainFrame.createMenu( "File", getConfiguration() );
1133         _file_jmenu.add( _save_item = new JMenuItem( "Save Tree As..." ) );
1134         _file_jmenu.addSeparator();
1135         _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) );
1136         if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" ) || AptxUtil.canWriteFormat( "TIF" ) ) {
1137             _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) );
1138         }
1139         _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) );
1140         _file_jmenu.add( _write_to_jpg_item = new JMenuItem( "Export to JPG file..." ) );
1141         if ( AptxUtil.canWriteFormat( "gif" ) ) {
1142             _file_jmenu.add( _write_to_gif_item = new JMenuItem( "Export to GIF file..." ) );
1143         }
1144         if ( AptxUtil.canWriteFormat( "bmp" ) ) {
1145             _file_jmenu.add( _write_to_bmp_item = new JMenuItem( "Export to BMP file..." ) );
1146         }
1147         _file_jmenu.addSeparator();
1148         _file_jmenu.add( _print_item = new JMenuItem( "Print..." ) );
1149         _file_jmenu.addSeparator();
1150         _file_jmenu.add( _exit_item = new JMenuItem( "Exit" ) );
1151         customizeJMenuItem( _save_item );
1152         customizeJMenuItem( _write_to_pdf_item );
1153         customizeJMenuItem( _write_to_png_item );
1154         customizeJMenuItem( _write_to_jpg_item );
1155         customizeJMenuItem( _write_to_gif_item );
1156         customizeJMenuItem( _write_to_tif_item );
1157         customizeJMenuItem( _write_to_bmp_item );
1158         customizeJMenuItem( _print_item );
1159         customizeJMenuItem( _exit_item );
1160         _jmenubar.add( _file_jmenu );
1161     }
1162
1163     void buildFontSizeMenu() {
1164         _font_size_menu = createMenu( FONT_SIZE_MENU_LABEL, getConfiguration() );
1165         _font_size_menu.add( _super_tiny_fonts_item = new JMenuItem( "Super Tiny Fonts" ) );
1166         _font_size_menu.add( _tiny_fonts_item = new JMenuItem( "Tiny Fonts" ) );
1167         _font_size_menu.add( _small_fonts_item = new JMenuItem( "Small Fonts" ) );
1168         _font_size_menu.add( _medium_fonts_item = new JMenuItem( "Medium Fonts" ) );
1169         _font_size_menu.add( _large_fonts_item = new JMenuItem( "Large Fonts" ) );
1170         customizeJMenuItem( _super_tiny_fonts_item );
1171         customizeJMenuItem( _tiny_fonts_item );
1172         customizeJMenuItem( _small_fonts_item );
1173         customizeJMenuItem( _medium_fonts_item );
1174         customizeJMenuItem( _large_fonts_item );
1175         _jmenubar.add( _font_size_menu );
1176     }
1177
1178     void buildHelpMenu() {
1179         _help_jmenu = createMenu( "Help", getConfiguration() );
1180         _help_jmenu.add( _help_item = new JMenuItem( "Documentation" ) );
1181         _help_jmenu.addSeparator();
1182         _help_jmenu.add( _website_item = new JMenuItem( "Archaeopteryx Home" ) );
1183         _help_jmenu.add( _mailing_list_item = new JMenuItem( "Mailing List" ) );
1184         _aptx_ref_item = new JMenuItem( "Archaeopteryx Reference" ); //TODO need to add this...
1185         _help_jmenu.add( _phyloxml_website_item = new JMenuItem( "phyloXML Home" ) );
1186         _help_jmenu.add( _phyloxml_ref_item = new JMenuItem( "phyloXML Reference" ) );
1187         _help_jmenu.addSeparator();
1188         _help_jmenu.add( _about_item = new JMenuItem( "About" ) );
1189         customizeJMenuItem( _help_item );
1190         customizeJMenuItem( _website_item );
1191         customizeJMenuItem( _mailing_list_item );
1192         customizeJMenuItem( _phyloxml_website_item );
1193         customizeJMenuItem( _aptx_ref_item );
1194         customizeJMenuItem( _phyloxml_ref_item );
1195         customizeJMenuItem( _about_item );
1196         _phyloxml_ref_item.setToolTipText( PHYLOXML_REF_TOOL_TIP );
1197         _aptx_ref_item.setToolTipText( APTX_REF_TOOL_TIP );
1198         _jmenubar.add( _help_jmenu );
1199     }
1200
1201     void buildTypeMenu() {
1202         _type_menu = createMenu( TYPE_MENU_HEADER, getConfiguration() );
1203         _type_menu.add( _rectangular_type_cbmi = new JCheckBoxMenuItem( MainFrame.RECTANGULAR_TYPE_CBMI_LABEL ) );
1204         _type_menu.add( _euro_type_cbmi = new JCheckBoxMenuItem( MainFrame.EURO_TYPE_CBMI_LABEL ) );
1205         _type_menu.add( _rounded_type_cbmi = new JCheckBoxMenuItem( MainFrame.ROUNDED_TYPE_CBMI_LABEL ) );
1206         _type_menu.add( _curved_type_cbmi = new JCheckBoxMenuItem( MainFrame.CURVED_TYPE_CBMI_LABEL ) );
1207         _type_menu.add( _triangular_type_cbmi = new JCheckBoxMenuItem( MainFrame.TRIANGULAR_TYPE_CBMI_LABEL ) );
1208         _type_menu.add( _convex_type_cbmi = new JCheckBoxMenuItem( MainFrame.CONVEX_TYPE_CBMI_LABEL ) );
1209         _type_menu.add( _unrooted_type_cbmi = new JCheckBoxMenuItem( MainFrame.UNROOTED_TYPE_CBMI_LABEL ) );
1210         _type_menu.add( _circular_type_cbmi = new JCheckBoxMenuItem( MainFrame.CIRCULAR_TYPE_CBMI_LABEL ) );
1211         customizeCheckBoxMenuItem( _rectangular_type_cbmi, false );
1212         customizeCheckBoxMenuItem( _triangular_type_cbmi, false );
1213         customizeCheckBoxMenuItem( _euro_type_cbmi, false );
1214         customizeCheckBoxMenuItem( _rounded_type_cbmi, false );
1215         customizeCheckBoxMenuItem( _curved_type_cbmi, false );
1216         customizeCheckBoxMenuItem( _convex_type_cbmi, false );
1217         customizeCheckBoxMenuItem( _unrooted_type_cbmi, false );
1218         customizeCheckBoxMenuItem( _circular_type_cbmi, false );
1219         _triangular_type_cbmi.setToolTipText( "not suitable for phylograms" );
1220         _curved_type_cbmi.setToolTipText( "not suitable for phylograms" );
1221         _unrooted_type_cbmi.setToolTipText( MainFrame.USE_MOUSEWHEEL_SHIFT_TO_ROTATE );
1222         _circular_type_cbmi.setToolTipText( MainFrame.USE_MOUSEWHEEL_SHIFT_TO_ROTATE );
1223         initializeTypeMenu( getOptions() );
1224         _jmenubar.add( _type_menu );
1225     }
1226
1227     void buildViewMenu() {
1228         _view_jmenu = createMenu( "View", getConfiguration() );
1229         _view_jmenu.add( _display_basic_information_item = new JMenuItem( SHOW_BASIC_TREE_INFORMATION_LABEL ) );
1230         _view_jmenu.addSeparator();
1231         _view_jmenu.add( _view_as_XML_item = new JMenuItem( "as phyloXML" ) );
1232         _view_jmenu.add( _view_as_NH_item = new JMenuItem( "as Newick" ) );
1233         _view_jmenu.add( _view_as_nexus_item = new JMenuItem( "as Nexus" ) );
1234         customizeJMenuItem( _display_basic_information_item );
1235         customizeJMenuItem( _view_as_NH_item );
1236         customizeJMenuItem( _view_as_XML_item );
1237         customizeJMenuItem( _view_as_nexus_item );
1238         _jmenubar.add( _view_jmenu );
1239     }
1240
1241     void checkTextFrames() {
1242         if ( _textframes.size() > 5 ) {
1243             try {
1244                 if ( _textframes.getFirst() != null ) {
1245                     _textframes.getFirst().removeMe();
1246                 }
1247                 else {
1248                     _textframes.removeFirst();
1249                 }
1250             }
1251             catch ( final NoSuchElementException e ) {
1252                 // Ignore.
1253             }
1254         }
1255     }
1256
1257     void choosePdfWidth() {
1258         final String s = ( String ) JOptionPane.showInputDialog( this,
1259                                                                  "Please enter the default line width for PDF export.\n"
1260                                                                          + "[current value: "
1261                                                                          + getOptions().getPrintLineWidth() + "]\n",
1262                                                                  "Line Width for PDF Export",
1263                                                                  JOptionPane.QUESTION_MESSAGE,
1264                                                                  null,
1265                                                                  null,
1266                                                                  getOptions().getPrintLineWidth() );
1267         if ( !ForesterUtil.isEmpty( s ) ) {
1268             boolean success = true;
1269             float f = 0.0f;
1270             final String m_str = s.trim();
1271             if ( !ForesterUtil.isEmpty( m_str ) ) {
1272                 try {
1273                     f = Float.parseFloat( m_str );
1274                 }
1275                 catch ( final Exception ex ) {
1276                     success = false;
1277                 }
1278             }
1279             else {
1280                 success = false;
1281             }
1282             if ( success && ( f > 0.0 ) ) {
1283                 getOptions().setPrintLineWidth( f );
1284             }
1285         }
1286     }
1287
1288     void close() {
1289         removeAllTextFrames();
1290         if ( _mainpanel != null ) {
1291             _mainpanel.terminate();
1292         }
1293         if ( _contentpane != null ) {
1294             _contentpane.removeAll();
1295         }
1296         setVisible( false );
1297         dispose();
1298     }
1299
1300     void colorRank() {
1301         if ( _mainpanel.getCurrentTreePanel() != null ) {
1302             final Map<String, Integer> present_ranks = AptxUtil.getRankCounts( _mainpanel.getCurrentTreePanel().getPhylogeny());
1303             final String[] ranks = AptxUtil.getAllPossibleRanks(present_ranks);
1304             String rank = ( String ) JOptionPane
1305                     .showInputDialog( this,
1306                                       "What rank should the colorization be based on",
1307                                       "Rank Selection",
1308                                       JOptionPane.QUESTION_MESSAGE,
1309                                       null,
1310                                       ranks,
1311                                       null );
1312             if ( !ForesterUtil.isEmpty( rank ) ) {
1313                 if ( rank.indexOf( '(' ) > 0 ) {
1314                     rank = rank.substring( 0, rank.indexOf( '(' ) ).trim();
1315                 }
1316                 _mainpanel.getCurrentTreePanel().colorRank( rank );
1317             }
1318         }
1319     }
1320
1321     void confColor() {
1322         if ( _mainpanel.getCurrentTreePanel() != null ) {
1323             _mainpanel.getCurrentTreePanel().confColor();
1324         }
1325     }
1326
1327     void customizeCheckBoxMenuItem( final JCheckBoxMenuItem item, final boolean is_selected ) {
1328         if ( item != null ) {
1329             item.setFont( MainFrame.menu_font );
1330             if ( !getConfiguration().isUseNativeUI() ) {
1331                 item.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
1332                 item.setForeground( getConfiguration().getGuiMenuTextColor() );
1333             }
1334             item.setSelected( is_selected );
1335             item.addActionListener( this );
1336         }
1337     }
1338
1339     JMenuItem customizeJMenuItem( final JMenuItem jmi ) {
1340         if ( jmi != null ) {
1341             jmi.setFont( MainFrame.menu_font );
1342             if ( !getConfiguration().isUseNativeUI() ) {
1343                 jmi.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
1344                 jmi.setForeground( getConfiguration().getGuiMenuTextColor() );
1345             }
1346             jmi.addActionListener( this );
1347         }
1348         return jmi;
1349     }
1350
1351     void customizeRadioButtonMenuItem( final JRadioButtonMenuItem item, final boolean is_selected ) {
1352         if ( item != null ) {
1353             item.setFont( MainFrame.menu_font );
1354             if ( !getConfiguration().isUseNativeUI() ) {
1355                 item.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
1356                 item.setForeground( getConfiguration().getGuiMenuTextColor() );
1357             }
1358             item.setSelected( is_selected );
1359             item.addActionListener( this );
1360         }
1361     }
1362
1363     void displayBasicInformation( final File treefile ) {
1364         if ( ( _mainpanel.getCurrentPhylogeny() != null ) && !_mainpanel.getCurrentPhylogeny().isEmpty() ) {
1365             String title = "Basic Information";
1366             if ( !ForesterUtil.isEmpty( _mainpanel.getCurrentPhylogeny().getName() ) ) {
1367                 title = title + " for \"" + _mainpanel.getCurrentPhylogeny().getName() + "\"";
1368             }
1369             showTextFrame( AptxUtil.createBasicInformation( _mainpanel.getCurrentPhylogeny(), treefile ), title );
1370         }
1371     }
1372
1373     void exceptionOccuredDuringOpenFile( final Exception e ) {
1374         try {
1375             _mainpanel.getCurrentTreePanel().setArrowCursor();
1376         }
1377         catch ( final Exception ex ) {
1378             // Do nothing.
1379         }
1380         JOptionPane.showMessageDialog( this,
1381                                        ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ),
1382                                        "Error during File|Open",
1383                                        JOptionPane.ERROR_MESSAGE );
1384     }
1385
1386     void executeGSDI() {
1387         if ( !isOKforSDI( false, true ) ) {
1388             return;
1389         }
1390         if ( !_mainpanel.getCurrentPhylogeny().isRooted() ) {
1391             JOptionPane.showMessageDialog( this,
1392                                            "Gene tree is not rooted.",
1393                                            "Cannot execute GSDI",
1394                                            JOptionPane.ERROR_MESSAGE );
1395             return;
1396         }
1397         final Phylogeny gene_tree = _mainpanel.getCurrentPhylogeny().copy();
1398         gene_tree.setAllNodesToNotCollapse();
1399         gene_tree.recalculateNumberOfExternalDescendants( false );
1400         GSDI gsdi = null;
1401         final Phylogeny species_tree = getSpeciesTree().copy();
1402         try {
1403             gsdi = new GSDI( gene_tree, species_tree, false, true, true, true );
1404         }
1405         catch ( final SDIException e ) {
1406             JOptionPane.showMessageDialog( this,
1407                                            e.getLocalizedMessage(),
1408                                            "Error during GSDI",
1409                                            JOptionPane.ERROR_MESSAGE );
1410             return;
1411         }
1412         catch ( final Exception e ) {
1413             AptxUtil.unexpectedException( e );
1414             return;
1415         }
1416         gene_tree.setRerootable( false );
1417         gene_tree.clearHashIdToNodeMap();
1418         gene_tree.recalculateNumberOfExternalDescendants( true );
1419         _mainpanel.addPhylogenyInNewTab( gene_tree, getConfiguration(), "gene tree", null );
1420         getMainPanel().getControlPanel().setShowEvents( true );
1421         showWhole();
1422         final int selected = _mainpanel.getTabbedPane().getSelectedIndex();
1423         _mainpanel.addPhylogenyInNewTab( species_tree, getConfiguration(), "species tree", null );
1424         showWhole();
1425         _mainpanel.getTabbedPane().setSelectedIndex( selected );
1426         showWhole();
1427         _mainpanel.getCurrentTreePanel().setEdited( true );
1428         final int poly = PhylogenyMethods.countNumberOfPolytomies( species_tree );
1429         if ( gsdi.getStrippedExternalGeneTreeNodes().size() > 0 ) {
1430             JOptionPane.showMessageDialog( this,
1431                                            "Duplications: " + gsdi.getDuplicationsSum() + "\n"
1432                                                    + "Potential duplications: "
1433                                                    + gsdi.getSpeciationOrDuplicationEventsSum() + "\n"
1434                                                    + "Speciations: " + gsdi.getSpeciationsSum() + "\n"
1435                                                    + "Stripped gene tree nodes: "
1436                                                    + gsdi.getStrippedExternalGeneTreeNodes().size() + "\n"
1437                                                    + "Taxonomy linkage based on: " + gsdi.getTaxCompBase() + "\n"
1438                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1439                                            "GSDI successfully completed",
1440                                            JOptionPane.WARNING_MESSAGE );
1441         }
1442         else {
1443             JOptionPane.showMessageDialog( this,
1444                                            "Duplications: " + gsdi.getDuplicationsSum() + "\n"
1445                                                    + "Potential duplications: "
1446                                                    + gsdi.getSpeciationOrDuplicationEventsSum() + "\n"
1447                                                    + "Speciations: " + gsdi.getSpeciationsSum() + "\n"
1448                                                    + "Stripped gene tree nodes: "
1449                                                    + gsdi.getStrippedExternalGeneTreeNodes().size() + "\n"
1450                                                    + "Taxonomy linkage based on: " + gsdi.getTaxCompBase() + "\n"
1451                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1452                                            "GSDI successfully completed",
1453                                            JOptionPane.INFORMATION_MESSAGE );
1454         }
1455     }
1456
1457     void executeGSDIR() {
1458         if ( !isOKforSDI( false, false ) ) {
1459             return;
1460         }
1461         final int p = PhylogenyMethods.countNumberOfPolytomies( _mainpanel.getCurrentPhylogeny() );
1462         if ( ( p > 0 )
1463                 && !( ( p == 1 ) && ( _mainpanel.getCurrentPhylogeny().getRoot().getNumberOfDescendants() == 3 ) ) ) {
1464             JOptionPane.showMessageDialog( this,
1465                                            "Gene tree is not completely binary",
1466                                            "Cannot execute GSDI",
1467                                            JOptionPane.ERROR_MESSAGE );
1468             return;
1469         }
1470         final Phylogeny gene_tree = _mainpanel.getCurrentPhylogeny().copy();
1471         gene_tree.setAllNodesToNotCollapse();
1472         gene_tree.recalculateNumberOfExternalDescendants( false );
1473         GSDIR gsdir = null;
1474         final Phylogeny species_tree = getSpeciesTree().copy();
1475         try {
1476             gsdir = new GSDIR( gene_tree, species_tree, true, true, true );
1477         }
1478         catch ( final SDIException e ) {
1479             JOptionPane.showMessageDialog( this,
1480                                            e.getLocalizedMessage(),
1481                                            "Error during GSDIR",
1482                                            JOptionPane.ERROR_MESSAGE );
1483             return;
1484         }
1485         catch ( final Exception e ) {
1486             AptxUtil.unexpectedException( e );
1487             return;
1488         }
1489         final Phylogeny result_gene_tree = gsdir.getMinDuplicationsSumGeneTree();
1490         result_gene_tree.setRerootable( false );
1491         result_gene_tree.clearHashIdToNodeMap();
1492         result_gene_tree.recalculateNumberOfExternalDescendants( true );
1493         PhylogenyMethods.orderAppearance( result_gene_tree.getRoot(), true, true, DESCENDANT_SORT_PRIORITY.NODE_NAME );
1494         _mainpanel.addPhylogenyInNewTab( result_gene_tree, getConfiguration(), "gene tree", null );
1495         getMainPanel().getControlPanel().setShowEvents( true );
1496         showWhole();
1497         final int selected = _mainpanel.getTabbedPane().getSelectedIndex();
1498         _mainpanel.addPhylogenyInNewTab( species_tree, getConfiguration(), "species tree", null );
1499         showWhole();
1500         _mainpanel.getTabbedPane().setSelectedIndex( selected );
1501         showWhole();
1502         _mainpanel.getCurrentTreePanel().setEdited( true );
1503         final int poly = PhylogenyMethods.countNumberOfPolytomies( species_tree );
1504         if ( gsdir.getStrippedExternalGeneTreeNodes().size() > 0 ) {
1505             JOptionPane.showMessageDialog( this,
1506                                            "Minimal duplications: " + gsdir.getMinDuplicationsSum() + "\n"
1507                                                    + "Speciations: " + gsdir.getSpeciationsSum() + "\n"
1508                                                    + "Stripped gene tree nodes: "
1509                                                    + gsdir.getStrippedExternalGeneTreeNodes().size() + "\n"
1510                                                    + "Taxonomy linkage based on: " + gsdir.getTaxCompBase() + "\n"
1511                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1512                                            "GSDIR successfully completed",
1513                                            JOptionPane.WARNING_MESSAGE );
1514         }
1515         else {
1516             JOptionPane.showMessageDialog( this,
1517                                            "Minimal duplications: " + gsdir.getMinDuplicationsSum() + "\n"
1518                                                    + "Speciations: " + gsdir.getSpeciationsSum() + "\n"
1519                                                    + "Stripped gene tree nodes: "
1520                                                    + gsdir.getStrippedExternalGeneTreeNodes().size() + "\n"
1521                                                    + "Taxonomy linkage based on: " + gsdir.getTaxCompBase() + "\n"
1522                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1523                                            "GSDIR successfully completed",
1524                                            JOptionPane.INFORMATION_MESSAGE );
1525         }
1526     }
1527
1528     void executeLineageInference() {
1529         if ( ( _mainpanel.getCurrentPhylogeny() == null ) || ( _mainpanel.getCurrentPhylogeny().isEmpty() ) ) {
1530             return;
1531         }
1532         if ( !_mainpanel.getCurrentPhylogeny().isRooted() ) {
1533             JOptionPane.showMessageDialog( this,
1534                                            "Phylogeny is not rooted.",
1535                                            "Cannot infer ancestral taxonomies",
1536                                            JOptionPane.ERROR_MESSAGE );
1537             return;
1538         }
1539         final AncestralTaxonomyInferrer inferrer = new AncestralTaxonomyInferrer( this,
1540                                                                                   _mainpanel.getCurrentTreePanel(),
1541                                                                                   _mainpanel.getCurrentPhylogeny()
1542                                                                                           .copy() );
1543         new Thread( inferrer ).start();
1544     }
1545
1546     boolean GAndSDoHaveMoreThanOneSpeciesInComman( final Phylogeny gene_tree ) {
1547         if ( ( gene_tree == null ) || gene_tree.isEmpty() ) {
1548             JOptionPane.showMessageDialog( this,
1549                                            "Gene tree and species tree have no species in common.",
1550                                            "Error during SDI",
1551                                            JOptionPane.ERROR_MESSAGE );
1552             return false;
1553         }
1554         else if ( gene_tree.getNumberOfExternalNodes() < 2 ) {
1555             JOptionPane.showMessageDialog( this,
1556                                            "Gene tree and species tree have only one species in common.",
1557                                            "Error during SDI",
1558                                            JOptionPane.ERROR_MESSAGE );
1559             return false;
1560         }
1561         else {
1562             return true;
1563         }
1564     }
1565
1566     ControlPanel getControlPanel() {
1567         return getMainPanel().getControlPanel();
1568     }
1569
1570     File getCurrentDir() {
1571         if ( ( _current_dir == null ) || !_current_dir.canRead() ) {
1572             if ( ForesterUtil.isWindows() ) {
1573                 try {
1574                     _current_dir = new File( WindowsUtils.getCurrentUserDesktopPath() );
1575                 }
1576                 catch ( final Exception e ) {
1577                     _current_dir = null;
1578                 }
1579             }
1580         }
1581         if ( ( _current_dir == null ) || !_current_dir.canRead() ) {
1582             if ( System.getProperty( "user.home" ) != null ) {
1583                 _current_dir = new File( System.getProperty( "user.home" ) );
1584             }
1585             else if ( System.getProperty( "user.dir" ) != null ) {
1586                 _current_dir = new File( System.getProperty( "user.dir" ) );
1587             }
1588         }
1589         return _current_dir;
1590     }
1591
1592     TreePanel getCurrentTreePanel() {
1593         return getMainPanel().getCurrentTreePanel();
1594     }
1595
1596     JMenu getHelpMenu() {
1597         return _help_jmenu;
1598     }
1599
1600     JCheckBoxMenuItem getlabelDirectionCbmi() {
1601         return _label_direction_cbmi;
1602     }
1603
1604     JMenuBar getMenuBarOfMainFrame() {
1605         return _jmenubar;
1606     }
1607
1608     final Phylogeny getSpeciesTree() {
1609         return _species_tree;
1610     }
1611
1612     void initializeTypeMenu( final Options options ) {
1613         setTypeMenuToAllUnselected();
1614         switch ( options.getPhylogenyGraphicsType() ) {
1615             case CONVEX:
1616                 _convex_type_cbmi.setSelected( true );
1617                 break;
1618             case CURVED:
1619                 _curved_type_cbmi.setSelected( true );
1620                 break;
1621             case EURO_STYLE:
1622                 _euro_type_cbmi.setSelected( true );
1623                 break;
1624             case ROUNDED:
1625                 _rounded_type_cbmi.setSelected( true );
1626                 break;
1627             case TRIANGULAR:
1628                 _triangular_type_cbmi.setSelected( true );
1629                 break;
1630             case UNROOTED:
1631                 _unrooted_type_cbmi.setSelected( true );
1632                 break;
1633             case CIRCULAR:
1634                 _circular_type_cbmi.setSelected( true );
1635                 break;
1636             default:
1637                 _rectangular_type_cbmi.setSelected( true );
1638                 break;
1639         }
1640     }
1641
1642     boolean isOKforSDI( final boolean species_tree_has_to_binary, final boolean gene_tree_has_to_binary ) {
1643         if ( ( _mainpanel.getCurrentPhylogeny() == null ) || _mainpanel.getCurrentPhylogeny().isEmpty() ) {
1644             return false;
1645         }
1646         else if ( ( getSpeciesTree() == null ) || getSpeciesTree().isEmpty() ) {
1647             JOptionPane.showMessageDialog( this,
1648                                            "No species tree loaded",
1649                                            "Cannot execute GSDI",
1650                                            JOptionPane.ERROR_MESSAGE );
1651             return false;
1652         }
1653         else if ( species_tree_has_to_binary && !getSpeciesTree().isCompletelyBinary() ) {
1654             JOptionPane.showMessageDialog( this,
1655                                            "Species tree is not completely binary",
1656                                            "Cannot execute GSDI",
1657                                            JOptionPane.ERROR_MESSAGE );
1658             return false;
1659         }
1660         else if ( gene_tree_has_to_binary && !_mainpanel.getCurrentPhylogeny().isCompletelyBinary() ) {
1661             JOptionPane.showMessageDialog( this,
1662                                            "Gene tree is not completely binary",
1663                                            "Cannot execute GSDI",
1664                                            JOptionPane.ERROR_MESSAGE );
1665             return false;
1666         }
1667         else {
1668             return true;
1669         }
1670     }
1671
1672     boolean isSubtreeDisplayed() {
1673         if ( getCurrentTreePanel() != null ) {
1674             if ( getCurrentTreePanel().isCurrentTreeIsSubtree() ) {
1675                 JOptionPane
1676                         .showMessageDialog( this,
1677                                             "This operation can only be performed on a complete tree, not on the currently displayed sub-tree only.",
1678                                             "Operation can not be exectuted on a sub-tree",
1679                                             JOptionPane.WARNING_MESSAGE );
1680                 return true;
1681             }
1682         }
1683         return false;
1684     }
1685
1686     void midpointRoot() {
1687         if ( _mainpanel.getCurrentTreePanel() != null ) {
1688             _mainpanel.getCurrentTreePanel().midpointRoot();
1689         }
1690     }
1691
1692     void readPhylogeniesFromWebservice( final int i ) {
1693         final UrlTreeReader reader = new UrlTreeReader( this, i );
1694         new Thread( reader ).start();
1695     }
1696
1697     void removeAllTextFrames() {
1698         for( final TextFrame tf : _textframes ) {
1699             if ( tf != null ) {
1700                 tf.close();
1701             }
1702         }
1703         _textframes.clear();
1704     }
1705
1706     void resetSearch() {
1707         getMainPanel().getCurrentTreePanel().setFoundNodes0( null );
1708         getMainPanel().getCurrentTreePanel().setFoundNodes1( null );
1709         getMainPanel().getControlPanel().setSearchFoundCountsOnLabel0( 0 );
1710         getMainPanel().getControlPanel().getSearchFoundCountsLabel0().setVisible( false );
1711         getMainPanel().getControlPanel().getSearchTextField0().setText( "" );
1712         getMainPanel().getControlPanel().getSearchResetButton0().setEnabled( false );
1713         getMainPanel().getControlPanel().getSearchResetButton0().setVisible( false );
1714         getMainPanel().getControlPanel().setSearchFoundCountsOnLabel1( 0 );
1715         getMainPanel().getControlPanel().getSearchFoundCountsLabel1().setVisible( false );
1716         getMainPanel().getControlPanel().getSearchTextField1().setText( "" );
1717         getMainPanel().getControlPanel().getSearchResetButton1().setEnabled( false );
1718         getMainPanel().getControlPanel().getSearchResetButton1().setVisible( false );
1719     }
1720
1721     void setConfiguration( final Configuration configuration ) {
1722         _configuration = configuration;
1723     }
1724
1725     void setCurrentDir( final File current_dir ) {
1726         _current_dir = current_dir;
1727     }
1728
1729     void setInferenceManager( final InferenceManager i ) {
1730         _inference_manager = i;
1731     }
1732
1733     void setOptions( final Options options ) {
1734         _options = options;
1735     }
1736
1737     void setSelectedTypeInTypeMenu( final PHYLOGENY_GRAPHICS_TYPE type ) {
1738         setTypeMenuToAllUnselected();
1739         switch ( type ) {
1740             case CIRCULAR:
1741                 _circular_type_cbmi.setSelected( true );
1742                 break;
1743             case CONVEX:
1744                 _convex_type_cbmi.setSelected( true );
1745                 break;
1746             case CURVED:
1747                 _curved_type_cbmi.setSelected( true );
1748                 break;
1749             case EURO_STYLE:
1750                 _euro_type_cbmi.setSelected( true );
1751                 break;
1752             case ROUNDED:
1753                 _rounded_type_cbmi.setSelected( true );
1754                 break;
1755             case RECTANGULAR:
1756                 _rectangular_type_cbmi.setSelected( true );
1757                 break;
1758             case TRIANGULAR:
1759                 _triangular_type_cbmi.setSelected( true );
1760                 break;
1761             case UNROOTED:
1762                 _unrooted_type_cbmi.setSelected( true );
1763                 break;
1764             default:
1765                 throw new IllegalArgumentException( "unknown type: " + type );
1766         }
1767     }
1768
1769     final void setSpeciesTree( final Phylogeny species_tree ) {
1770         _species_tree = species_tree;
1771     }
1772
1773     void setTypeMenuToAllUnselected() {
1774         _convex_type_cbmi.setSelected( false );
1775         _curved_type_cbmi.setSelected( false );
1776         _euro_type_cbmi.setSelected( false );
1777         _rounded_type_cbmi.setSelected( false );
1778         _triangular_type_cbmi.setSelected( false );
1779         _rectangular_type_cbmi.setSelected( false );
1780         _unrooted_type_cbmi.setSelected( false );
1781         _circular_type_cbmi.setSelected( false );
1782     }
1783
1784     void switchColors() {
1785         final TreeColorSet colorset = _mainpanel.getTreeColorSet();
1786         final ColorSchemeChooser csc = new ColorSchemeChooser( getMainPanel(), colorset );
1787         csc.setVisible( true );
1788     }
1789
1790     void taxColor() {
1791         if ( _mainpanel.getCurrentTreePanel() != null ) {
1792             _mainpanel.getCurrentTreePanel().taxColor();
1793         }
1794     }
1795
1796     void typeChanged( final Object o ) {
1797         updateTypeCheckboxes( getOptions(), o );
1798         updateOptions( getOptions() );
1799         if ( getCurrentTreePanel() != null ) {
1800             final PHYLOGENY_GRAPHICS_TYPE previous_type = getCurrentTreePanel().getPhylogenyGraphicsType();
1801             final PHYLOGENY_GRAPHICS_TYPE new_type = getOptions().getPhylogenyGraphicsType();
1802             if ( ( ( previous_type == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( new_type != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) )
1803                     || ( ( previous_type == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) && ( new_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) )
1804                     || ( ( previous_type != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( new_type == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) )
1805                     || ( ( previous_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) && ( new_type == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) ) {
1806                 getCurrentTreePanel().getControlPanel().showWhole();
1807             }
1808             if ( getCurrentTreePanel().isPhyHasBranchLengths() && ( new_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
1809                 getCurrentTreePanel().getControlPanel().setDrawPhylogramEnabled( true );
1810             }
1811             else {
1812                 getCurrentTreePanel().getControlPanel().setDrawPhylogramEnabled( false );
1813             }
1814             getCurrentTreePanel().setPhylogenyGraphicsType( getOptions().getPhylogenyGraphicsType() );
1815             updateScreenTextAntialias( getMainPanel().getTreePanels() );
1816             if ( getCurrentTreePanel().getControlPanel().getDynamicallyHideData() != null ) {
1817                 if ( new_type == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
1818                     getCurrentTreePanel().getControlPanel().getDynamicallyHideData().setEnabled( false );
1819                 }
1820                 else {
1821                     getCurrentTreePanel().getControlPanel().getDynamicallyHideData().setEnabled( true );
1822                 }
1823             }
1824         }
1825     }
1826
1827     void updateOptions( final Options options ) {
1828         options.setAntialiasScreen( ( _screen_antialias_cbmi != null ) && _screen_antialias_cbmi.isSelected() );
1829         options.setBackgroundColorGradient( ( _background_gradient_cbmi != null )
1830                 && _background_gradient_cbmi.isSelected() );
1831         options.setShowDomainLabels( ( _show_domain_labels != null ) && _show_domain_labels.isSelected() );
1832         options.setShowAnnotationRefSource( ( _show_annotation_ref_source != null )
1833                 && _show_annotation_ref_source.isSelected() );
1834         options.setAbbreviateScientificTaxonNames( ( _abbreviate_scientific_names != null )
1835                 && _abbreviate_scientific_names.isSelected() );
1836         options.setColorLabelsSameAsParentBranch( ( _color_labels_same_as_parent_branch != null )
1837                 && _color_labels_same_as_parent_branch.isSelected() );
1838         options.setShowDefaultNodeShapesInternal( ( _show_default_node_shapes_internal_cbmi != null )
1839                 && _show_default_node_shapes_internal_cbmi.isSelected() );
1840         options.setShowDefaultNodeShapesExternal( ( _show_default_node_shapes_external_cbmi != null )
1841                 && _show_default_node_shapes_external_cbmi.isSelected() );
1842         options.setShowDefaultNodeShapesForMarkedNodes( ( _show_default_node_shapes_for_marked_cbmi != null )
1843                 && _show_default_node_shapes_for_marked_cbmi.isSelected() );
1844         if ( ( _non_lined_up_cladograms_rbmi != null ) && ( _non_lined_up_cladograms_rbmi.isSelected() ) ) {
1845             options.setCladogramType( CLADOGRAM_TYPE.NON_LINED_UP );
1846         }
1847         else if ( ( _ext_node_dependent_cladogram_rbmi != null ) && ( _ext_node_dependent_cladogram_rbmi.isSelected() ) ) {
1848             options.setCladogramType( CLADOGRAM_TYPE.LINED_UP );
1849         }
1850         options.setSearchCaseSensitive( ( _search_case_senstive_cbmi != null )
1851                 && _search_case_senstive_cbmi.isSelected() );
1852         if ( ( _show_scale_cbmi != null ) && _show_scale_cbmi.isEnabled() ) {
1853             options.setShowScale( _show_scale_cbmi.isSelected() );
1854         }
1855         if ( _label_direction_cbmi != null ) {
1856             if ( _label_direction_cbmi.isSelected() ) {
1857                 options.setNodeLabelDirection( NODE_LABEL_DIRECTION.RADIAL );
1858             }
1859             else {
1860                 options.setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL );
1861             }
1862         }
1863         options.setShowOverview( ( _show_overview_cbmi != null ) && _show_overview_cbmi.isSelected() );
1864         options.setShowConfidenceStddev( ( _show_confidence_stddev_cbmi != null )
1865                 && _show_confidence_stddev_cbmi.isSelected() );
1866         if ( ( _color_by_taxonomic_group_cbmi != null ) && _color_by_taxonomic_group_cbmi.isEnabled() ) {
1867             options.setColorByTaxonomicGroup( _color_by_taxonomic_group_cbmi.isSelected() );
1868         }
1869         options.setAntialiasPrint( ( _antialias_print_cbmi != null ) && _antialias_print_cbmi.isSelected() );
1870         if ( ( _use_brackets_for_conf_in_nh_export_cbmi != null )
1871                 && _use_brackets_for_conf_in_nh_export_cbmi.isSelected() ) {
1872             options.setNhConversionSupportValueStyle( NH_CONVERSION_SUPPORT_VALUE_STYLE.IN_SQUARE_BRACKETS );
1873         }
1874         else if ( ( _use_internal_names_for_conf_in_nh_export_cbmi != null )
1875                 && _use_internal_names_for_conf_in_nh_export_cbmi.isSelected() ) {
1876             options.setNhConversionSupportValueStyle( NH_CONVERSION_SUPPORT_VALUE_STYLE.AS_INTERNAL_NODE_NAMES );
1877         }
1878         else {
1879             options.setNhConversionSupportValueStyle( NH_CONVERSION_SUPPORT_VALUE_STYLE.NONE );
1880         }
1881         options.setPrintBlackAndWhite( ( _print_black_and_white_cbmi != null )
1882                 && _print_black_and_white_cbmi.isSelected() );
1883         options.setInternalNumberAreConfidenceForNhParsing( ( _internal_number_are_confidence_for_nh_parsing_cbmi != null )
1884                 && _internal_number_are_confidence_for_nh_parsing_cbmi.isSelected() );
1885         if ( ( _extract_taxonomy_pfam_strict_rbmi != null ) && _extract_taxonomy_pfam_strict_rbmi.isSelected() ) {
1886             options.setTaxonomyExtraction( TAXONOMY_EXTRACTION.PFAM_STYLE_STRICT );
1887         }
1888         else if ( ( _extract_taxonomy_pfam_relaxed_rbmi != null ) && _extract_taxonomy_pfam_relaxed_rbmi.isSelected() ) {
1889             options.setTaxonomyExtraction( TAXONOMY_EXTRACTION.PFAM_STYLE_RELAXED );
1890         }
1891         else if ( ( _extract_taxonomy_agressive_rbmi != null ) && _extract_taxonomy_agressive_rbmi.isSelected() ) {
1892             options.setTaxonomyExtraction( TAXONOMY_EXTRACTION.AGGRESSIVE );
1893         }
1894         else if ( ( _extract_taxonomy_no_rbmi != null ) && _extract_taxonomy_no_rbmi.isSelected() ) {
1895             options.setTaxonomyExtraction( TAXONOMY_EXTRACTION.NO );
1896         }
1897         options.setReplaceUnderscoresInNhParsing( ( _replace_underscores_cbmi != null )
1898                 && _replace_underscores_cbmi.isSelected() );
1899         options.setAllowErrorsInDistanceToParent( ( _allow_errors_in_distance_to_parent_cbmi != null )
1900                 && _allow_errors_in_distance_to_parent_cbmi.isSelected() );
1901         options.setMatchWholeTermsOnly( ( _search_whole_words_only_cbmi != null )
1902                 && _search_whole_words_only_cbmi.isSelected() );
1903         options.setSearchWithRegex( ( _search_with_regex_cbmi != null ) && _search_with_regex_cbmi.isSelected() );
1904         options.setInverseSearchResult( ( _inverse_search_result_cbmi != null )
1905                 && _inverse_search_result_cbmi.isSelected() );
1906         if ( _graphics_export_visible_only_cbmi != null ) {
1907             options.setGraphicsExportVisibleOnly( _graphics_export_visible_only_cbmi.isSelected() );    
1908         }
1909         if ( ( _rectangular_type_cbmi != null ) && _rectangular_type_cbmi.isSelected() ) {
1910             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1911         }
1912         else if ( ( _triangular_type_cbmi != null ) && _triangular_type_cbmi.isSelected() ) {
1913             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.TRIANGULAR );
1914         }
1915         else if ( ( _curved_type_cbmi != null ) && _curved_type_cbmi.isSelected() ) {
1916             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CURVED );
1917         }
1918         else if ( ( _convex_type_cbmi != null ) && _convex_type_cbmi.isSelected() ) {
1919             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CONVEX );
1920         }
1921         else if ( ( _euro_type_cbmi != null ) && _euro_type_cbmi.isSelected() ) {
1922             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE );
1923         }
1924         else if ( ( _rounded_type_cbmi != null ) && _rounded_type_cbmi.isSelected() ) {
1925             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.ROUNDED );
1926         }
1927         else if ( ( _unrooted_type_cbmi != null ) && _unrooted_type_cbmi.isSelected() ) {
1928             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
1929         }
1930         else if ( ( _circular_type_cbmi != null ) && _circular_type_cbmi.isSelected() ) {
1931             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CIRCULAR );
1932         }
1933         if ( ( _right_line_up_domains_cbmi != null ) && _right_line_up_domains_cbmi.isEnabled() ) {
1934             options.setRightLineUpDomains( _right_line_up_domains_cbmi.isSelected() );
1935         }
1936         if ( ( _line_up_renderable_data_cbmi != null ) && _line_up_renderable_data_cbmi.isEnabled() ) {
1937             options.setLineUpRendarableNodeData( _line_up_renderable_data_cbmi.isSelected() );
1938         }
1939         if ( ( _color_all_found_nodes_when_coloring_subtree_cbmi != null ) && _color_all_found_nodes_when_coloring_subtree_cbmi.isEnabled() ) {
1940             options.setColorAllFoundNodesWhenColoringSubtree( _color_all_found_nodes_when_coloring_subtree_cbmi.isSelected() );
1941         }
1942         if ( ( _parse_beast_style_extended_nexus_tags_cbmi != null ) && _parse_beast_style_extended_nexus_tags_cbmi.isEnabled() ) {
1943             options.setParseBeastStyleExtendedNexusTags(_parse_beast_style_extended_nexus_tags_cbmi.isSelected() );
1944         }
1945         if ( ( _collapsed_with_average_height_cbmi != null ) && _collapsed_with_average_height_cbmi.isEnabled() ) {
1946             options.setCollapsedWithAverageHeigh(_collapsed_with_average_height_cbmi.isSelected() );
1947         }
1948         if ( ( _show_abbreviated_labels_for_collapsed_nodes_cbmi != null ) && _show_abbreviated_labels_for_collapsed_nodes_cbmi.isEnabled() ) {
1949             options.setShowAbbreviatedLabelsForCollapsedNodes(_show_abbreviated_labels_for_collapsed_nodes_cbmi.isSelected() );
1950         }
1951         
1952     }
1953
1954     void updateTypeCheckboxes( final Options options, final Object o ) {
1955         setTypeMenuToAllUnselected();
1956         ( ( JCheckBoxMenuItem ) o ).setSelected( true );
1957     }
1958
1959     void viewAsNexus() {
1960         if ( ( _mainpanel.getCurrentPhylogeny() != null ) && !_mainpanel.getCurrentPhylogeny().isEmpty() ) {
1961             String title = "Nexus";
1962             if ( !ForesterUtil.isEmpty( _mainpanel.getCurrentPhylogeny().getName() ) ) {
1963                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1964             }
1965             showTextFrame( _mainpanel.getCurrentPhylogeny().toNexus( getOptions().getNhConversionSupportValueStyle() ),
1966                            title );
1967         }
1968     }
1969
1970     void viewAsNH() {
1971         if ( ( _mainpanel.getCurrentPhylogeny() != null ) && !_mainpanel.getCurrentPhylogeny().isEmpty() ) {
1972             String title = "New Hampshire";
1973             if ( !ForesterUtil.isEmpty( _mainpanel.getCurrentPhylogeny().getName() ) ) {
1974                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1975             }
1976             showTextFrame( _mainpanel.getCurrentPhylogeny().toNewHampshire( getOptions()
1977                                    .getNhConversionSupportValueStyle() ),
1978                            title );
1979         }
1980     }
1981
1982     void viewAsXML() {
1983         if ( ( _mainpanel.getCurrentPhylogeny() != null ) && !_mainpanel.getCurrentPhylogeny().isEmpty() ) {
1984             String title = "phyloXML";
1985             if ( !ForesterUtil.isEmpty( _mainpanel.getCurrentPhylogeny().getName() ) ) {
1986                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1987             }
1988             showTextFrame( _mainpanel.getCurrentPhylogeny().toPhyloXML( 0 ), title );
1989         }
1990     }
1991
1992     private static void cycleNodeDataReturn( final Options op, final Configuration conf ) {
1993         switch ( op.getExtDescNodeDataToReturn() ) {
1994             case UNKNOWN:
1995                 op.setExtDescNodeDataToReturn( NodeDataField.DOMAINS_ALL );
1996                 break;
1997             case DOMAINS_ALL:
1998                 op.setExtDescNodeDataToReturn( NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN );
1999                 break;
2000             case DOMAINS_COLLAPSED_PER_PROTEIN:
2001                 op.setExtDescNodeDataToReturn( NodeDataField.SEQ_ANNOTATIONS );
2002                 break;
2003             case SEQ_ANNOTATIONS:
2004                 op.setExtDescNodeDataToReturn( NodeDataField.GO_TERM_IDS );
2005                 break;
2006             case GO_TERM_IDS:
2007                 op.setExtDescNodeDataToReturn( NodeDataField.SEQUENCE_MOL_SEQ_FASTA );
2008                 break;
2009             case SEQUENCE_MOL_SEQ_FASTA:
2010                 if ( ( conf != null ) && ( conf.getExtDescNodeDataToReturn() != null )
2011                         && ( conf.getExtDescNodeDataToReturn() != NodeDataField.DOMAINS_ALL )
2012                         && ( conf.getExtDescNodeDataToReturn() != NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN )
2013                         && ( conf.getExtDescNodeDataToReturn() != NodeDataField.SEQ_ANNOTATIONS )
2014                         && ( conf.getExtDescNodeDataToReturn() != NodeDataField.GO_TERM_IDS )
2015                         && ( conf.getExtDescNodeDataToReturn() != NodeDataField.SEQUENCE_MOL_SEQ_FASTA ) ) {
2016                     op.setExtDescNodeDataToReturn( conf.getExtDescNodeDataToReturn() );
2017                 }
2018                 else {
2019                     op.setExtDescNodeDataToReturn( NodeDataField.UNKNOWN );
2020                 }
2021                 break;
2022             default:
2023                 op.setExtDescNodeDataToReturn( NodeDataField.UNKNOWN );
2024         }
2025     }
2026
2027     /**
2028      * Display the about box.
2029      */
2030     void about() {
2031         final StringBuffer about = new StringBuffer( "Archaeopteryx\nVersion " + AptxConstants.VERSION + "\n" );
2032         about.append( "Copyright (C) 2016 Christian M Zmasek\n" );
2033         about.append( "All Rights Reserved\n" );
2034         about.append( "License: GNU Lesser General Public License (LGPL)\n" );
2035         about.append( "Last modified: " + AptxConstants.PRG_DATE + "\n" );
2036         about.append( "Based on: " + ForesterUtil.getForesterLibraryInformation() + "\n" );
2037         
2038         if  ( _configuration.isCouldReadConfigFile() ) {
2039             about.append( "Using configuration file: " + _configuration.config_filename + "\n" );
2040         }
2041         else {
2042             about.append( "Not using a configuration file\n" );
2043         }
2044         
2045         about.append( "phyloXML version : " + ForesterConstants.PHYLO_XML_VERSION + "\n" );
2046         about.append( "phyloXML location: " + ForesterConstants.PHYLO_XML_LOCATION + "\n" );
2047         if ( !ForesterUtil.isEmpty( ForesterUtil.JAVA_VERSION ) && !ForesterUtil.isEmpty( ForesterUtil.JAVA_VENDOR ) ) {
2048             about.append( "[your Java version: " + ForesterUtil.JAVA_VERSION + " " + ForesterUtil.JAVA_VENDOR + "]\n" );
2049         }
2050         if ( !ForesterUtil.isEmpty( ForesterUtil.OS_NAME ) && !ForesterUtil.isEmpty( ForesterUtil.OS_ARCH )
2051                 && !ForesterUtil.isEmpty( ForesterUtil.OS_VERSION ) ) {
2052             about.append( "[your OS: " + ForesterUtil.OS_NAME + " " + ForesterUtil.OS_ARCH + " "
2053                     + ForesterUtil.OS_VERSION + "]\n" );
2054         }
2055         final Runtime rt = java.lang.Runtime.getRuntime();
2056         final long free_memory = rt.freeMemory() / 1000000;
2057         final long total_memory = rt.totalMemory() / 1000000;
2058         about.append( "[free memory: " + free_memory + "MB, total memory: " + total_memory + "MB]\n" );
2059         about.append( "[locale: " + Locale.getDefault() + "]\n" );
2060         about.append( "References:\n" );
2061         about.append( AptxConstants.PHYLOXML_REFERENCE_SHORT + "\n" );
2062         about.append( "For more information & download:\n" );
2063         about.append( AptxConstants.APTX_WEB_SITE + "\n" );
2064         about.append( "Documentation:\n" );
2065         about.append( AptxConstants.APTX_DOC_SITE + "\n" );
2066         about.append( "Comments: " + AptxConstants.AUTHOR_EMAIL );
2067         JOptionPane.showMessageDialog( null, about, AptxConstants.PRG_NAME, JOptionPane.PLAIN_MESSAGE );
2068     }
2069
2070     static void chooseNodeSize( final Options options, final Component parent ) {
2071         final String s = ( String ) JOptionPane.showInputDialog( parent,
2072                                                                  "Please enter the default size for node shapes.\n"
2073                                                                          + "[current value: "
2074                                                                          + options.getDefaultNodeShapeSize() + "]\n",
2075                                                                  "Node Shape Size",
2076                                                                  JOptionPane.QUESTION_MESSAGE,
2077                                                                  null,
2078                                                                  null,
2079                                                                  options.getDefaultNodeShapeSize() );
2080         if ( !ForesterUtil.isEmpty( s ) ) {
2081             boolean success = true;
2082             double m = 0.0;
2083             final String m_str = s.trim();
2084             if ( !ForesterUtil.isEmpty( m_str ) ) {
2085                 try {
2086                     m = Double.parseDouble( m_str );
2087                 }
2088                 catch ( final Exception ex ) {
2089                     success = false;
2090                 }
2091             }
2092             else {
2093                 success = false;
2094             }
2095             if ( success && ( m >= 0.0 ) ) {
2096                 final short size = ForesterUtil.roundToShort( m );
2097                 if ( size >= 0.0 ) {
2098                     options.setDefaultNodeShapeSize( size );
2099                 }
2100             }
2101         }
2102     }
2103
2104     static String createCurrentFontDesc( final TreeFontSet tree_font_set ) {
2105         return tree_font_set.getLargeFont().getFamily() + " " + tree_font_set.getLargeFont().getSize();
2106     }
2107
2108     static JMenu createMenu( final String title, final Configuration conf ) {
2109         final JMenu jmenu = new JMenu( title );
2110         if ( !conf.isUseNativeUI() ) {
2111             jmenu.setFont( MainFrame.menu_font );
2112             jmenu.setBackground( conf.getGuiMenuBackgroundColor() );
2113             jmenu.setForeground( conf.getGuiMenuTextColor() );
2114         }
2115         return jmenu;
2116     }
2117
2118     static JMenuItem customizeMenuItemAsLabel( final JMenuItem label, final Configuration configuration ) {
2119         label.setFont( MainFrame.menu_font.deriveFont( Font.BOLD ) );
2120         if ( !configuration.isUseNativeUI() ) {
2121             label.setBackground( configuration.getGuiMenuBackgroundColor() );
2122             label.setForeground( configuration.getGuiMenuTextColor() );
2123             label.setOpaque( true );
2124         }
2125         label.setSelected( false );
2126         label.setEnabled( false );
2127         return label;
2128     }
2129
2130     static void cycleNodeFill( final Options op ) {
2131         switch ( op.getDefaultNodeFill() ) {
2132             case GRADIENT:
2133                 op.setDefaultNodeFill( NodeFill.SOLID );
2134                 break;
2135             case NONE:
2136                 op.setDefaultNodeFill( NodeFill.GRADIENT );
2137                 break;
2138             case SOLID:
2139                 op.setDefaultNodeFill( NodeFill.NONE );
2140                 break;
2141             default:
2142                 throw new RuntimeException( "unknown fill: " + op.getDefaultNodeFill() );
2143         }
2144     }
2145
2146     static void cycleNodeShape( final Options op ) {
2147         switch ( op.getDefaultNodeShape() ) {
2148             case CIRCLE:
2149                 op.setDefaultNodeShape( NodeShape.RECTANGLE );
2150                 break;
2151             case RECTANGLE:
2152                 op.setDefaultNodeShape( NodeShape.CIRCLE );
2153                 break;
2154             default:
2155                 throw new RuntimeException( "unknown shape: " + op.getDefaultNodeShape() );
2156         }
2157     }
2158
2159     static void cycleOverview( final Options op, final TreePanel tree_panel ) {
2160         switch ( op.getOvPlacement() ) {
2161             case LOWER_LEFT:
2162                 op.setOvPlacement( Options.OVERVIEW_PLACEMENT_TYPE.UPPER_LEFT );
2163                 break;
2164             case LOWER_RIGHT:
2165                 op.setOvPlacement( Options.OVERVIEW_PLACEMENT_TYPE.LOWER_LEFT );
2166                 break;
2167             case UPPER_LEFT:
2168                 op.setOvPlacement( Options.OVERVIEW_PLACEMENT_TYPE.UPPER_RIGHT );
2169                 break;
2170             case UPPER_RIGHT:
2171                 op.setOvPlacement( Options.OVERVIEW_PLACEMENT_TYPE.LOWER_RIGHT );
2172                 break;
2173             default:
2174                 throw new RuntimeException( "unknown placement: " + op.getOvPlacement() );
2175         }
2176         if ( tree_panel != null ) {
2177             tree_panel.updateOvSettings();
2178         }
2179     }
2180
2181     static void exceptionOccuredDuringSaveAs( final Exception e, final TreePanel tp, final Component comp ) {
2182         try {
2183             tp.setArrowCursor();
2184         }
2185         catch ( final Exception ex ) {
2186             // Do nothing.
2187         }
2188         JOptionPane.showMessageDialog( comp, "Exception" + e, "Error during File|SaveAs", JOptionPane.ERROR_MESSAGE );
2189     }
2190
2191     static void print( final TreePanel tp, final Options op, final Component c ) {
2192         if ( ( tp == null ) || ( tp.getPhylogeny() == null ) || tp.getPhylogeny().isEmpty() ) {
2193             return;
2194         }
2195         final String job_name = AptxConstants.PRG_NAME;
2196         boolean error = false;
2197         String printer_name = null;
2198         try {
2199             printer_name = Printer.print( tp, job_name );
2200         }
2201         catch ( final Exception e ) {
2202             error = true;
2203             JOptionPane.showMessageDialog( c, e.getMessage(), "Printing Error", JOptionPane.ERROR_MESSAGE );
2204         }
2205         if ( !error && ( printer_name != null ) ) {
2206             String msg = "Printing data sent to printer";
2207             if ( printer_name.length() > 1 ) {
2208                 msg += " [" + printer_name + "]";
2209             }
2210             JOptionPane.showMessageDialog( c, msg, "Printing...", JOptionPane.INFORMATION_MESSAGE );
2211         }
2212         if ( !op.isPrintUsingActualSize() ) {
2213             tp.getControlPanel().showWhole();
2214         }
2215     }
2216
2217     static void printPhylogenyToPdf( final String file_name,
2218                                      final Options opts,
2219                                      final TreePanel tp,
2220                                      final Component comp ) {
2221        
2222         String pdf_written_to = "";
2223         boolean error = false;
2224         try {
2225             if ( opts.isPrintUsingActualSize() ) {
2226                 pdf_written_to = PdfExporter.writePhylogenyToPdf( file_name, tp, tp.getWidth() , tp.getHeight()  );
2227             }
2228             else {
2229                 // Never false.
2230             }
2231         }
2232         catch ( final IOException e ) {
2233             error = true;
2234             JOptionPane.showMessageDialog( comp, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE );
2235         }
2236         if ( !error ) {
2237             if ( !ForesterUtil.isEmpty( pdf_written_to ) ) {
2238                 JOptionPane.showMessageDialog( comp,
2239                                                "Wrote PDF to: " + pdf_written_to,
2240                                                "Information",
2241                                                JOptionPane.INFORMATION_MESSAGE );
2242             }
2243             else {
2244                 JOptionPane.showMessageDialog( comp,
2245                                                "There was an unknown problem when attempting to write to PDF file: \""
2246                                                        + file_name + "\"",
2247                                                "Error",
2248                                                JOptionPane.ERROR_MESSAGE );
2249             }
2250         }
2251         if ( !opts.isPrintUsingActualSize() ) {
2252             tp.getControlPanel().showWhole();
2253         }
2254     }
2255
2256     static void setCycleDataReturnMenuItem( final JMenuItem mi, final Options options ) {
2257         if ( ( options != null ) && ( options.getExtDescNodeDataToReturn() != null ) ) {
2258             mi.setText( "Cycle Node Return Data... (current: " + options.getExtDescNodeDataToReturn().toString() + ")" );
2259         }
2260         else {
2261             mi.setText( "Cycle Node Return Data..." );
2262         }
2263     }
2264
2265     static void setCycleNodeFillMenuItem( final JMenuItem mi, final Options options ) {
2266         if ( ( options != null ) && ( options.getDefaultNodeFill() != null ) ) {
2267             mi.setText( "Cycle Node Shape Fill Type... (current: "
2268                     + options.getDefaultNodeFill().toString().toLowerCase() + ")" );
2269         }
2270         else {
2271             mi.setText( "Cycle Node Shape Fill Type..." );
2272         }
2273     }
2274
2275     static void setCycleNodeShapeMenuItem( final JMenuItem mi, final Options options ) {
2276         if ( ( options != null ) && ( options.getDefaultNodeShape() != null ) ) {
2277             mi.setText( "Cycle Node Shape Fill Type... (current: "
2278                     + options.getDefaultNodeShape().toString().toLowerCase() + ")" );
2279         }
2280         else {
2281             mi.setText( "Cycle Node Shape Fill Type..." );
2282         }
2283     }
2284
2285     static void setOvPlacementColorChooseMenuItem( final JMenuItem mi, final Options options ) {
2286         if ( ( options != null ) && ( options.getOvPlacement() != null ) ) {
2287             mi.setText( "Cycle Overview Placement... (current: " + options.getOvPlacement() + ")" );
2288         }
2289         else {
2290             mi.setText( "Cycle Overview Placement..." );
2291         }
2292     }
2293
2294     static void setTextColorChooseMenuItem( final JMenuItem mi, final TreePanel tree_panel ) {
2295         if ( ( tree_panel != null ) && ( tree_panel.getTreeColorSet() != null ) ) {
2296             mi.setText( "Select Color Scheme... (current: " + tree_panel.getTreeColorSet().getCurrentColorSchemeName()
2297                     + ")" );
2298         }
2299         else {
2300             mi.setText( "Select Color Scheme..." );
2301         }
2302     }
2303
2304     static void setTextForFontChooserMenuItem( final JMenuItem mi, final String font_desc ) {
2305         mi.setText( "Select Default Font... (current: " + font_desc + ")" );
2306     }
2307
2308     static void setTextForPdfLineWidthChooserMenuItem( final JMenuItem mi, final Options o ) {
2309         mi.setText( "Enter Default Line Width for PDF Export... (current: " + o.getPrintLineWidth() + ")" );
2310     }
2311
2312     static void setTextMinSupportMenuItem( final JMenuItem mi, final Options options, final TreePanel current_tree_panel ) {
2313         if ( ( current_tree_panel == null ) || ( current_tree_panel.getPhylogeny() == null ) ) {
2314             mi.setEnabled( true );
2315         }
2316         else if ( AptxUtil.isHasAtLeastOneBranchWithSupportValues( current_tree_panel.getPhylogeny() ) ) {
2317             mi.setEnabled( true );
2318         }
2319         else {
2320             mi.setEnabled( false );
2321         }
2322         mi.setText( "Enter Min Confidence Value... (current: " + options.getMinConfidenceValue() + ")" );
2323     }
2324
2325     static void setTextNodeSizeMenuItem( final JMenuItem mi, final Options options ) {
2326         mi.setText( "Enter Default Node Shape Size... (current: " + options.getDefaultNodeShapeSize() + ")" );
2327     }
2328
2329     static void updateScreenTextAntialias( final List<TreePanel> treepanels ) {
2330         for( final TreePanel tree_panel : treepanels ) {
2331             tree_panel.setTextAntialias();
2332         }
2333     }
2334
2335     static boolean writeAsNewHampshire( final TreePanel tp, final Options op, boolean exception, final File file ) {
2336         try {
2337             final PhylogenyWriter writer = new PhylogenyWriter();
2338             writer.toNewHampshire( tp.getPhylogeny(), true, op.getNhConversionSupportValueStyle(), file );
2339         }
2340         catch ( final Exception e ) {
2341             exception = true;
2342             exceptionOccuredDuringSaveAs( e, tp, tp );
2343         }
2344         return exception;
2345     }
2346
2347     static boolean writeAsNexus( final TreePanel tp, final Options op, boolean exception, final File file ) {
2348         try {
2349             final PhylogenyWriter writer = new PhylogenyWriter();
2350             writer.toNexus( file, tp.getPhylogeny(), op.getNhConversionSupportValueStyle() );
2351         }
2352         catch ( final Exception e ) {
2353             exception = true;
2354             exceptionOccuredDuringSaveAs( e, tp, tp );
2355         }
2356         return exception;
2357     }
2358
2359     static boolean writeAsPhyloXml( final TreePanel tp, final Options op, boolean exception, final File file ) {
2360         try {
2361             final PhylogenyWriter writer = new PhylogenyWriter();
2362             writer.toPhyloXML( file, tp.getPhylogeny(), 0 );
2363         }
2364         catch ( final Exception e ) {
2365             exception = true;
2366             exceptionOccuredDuringSaveAs( e, tp, tp );
2367         }
2368         return exception;
2369     }
2370
2371     static void writePhylogenyToGraphicsFile( final String file_name,
2372                                               final GraphicsExportType type,
2373                                               final MainPanel mp,
2374                                               final Component comp,
2375                                               final Container contentpane ) {
2376         mp.getCurrentTreePanel().calcParametersForPainting( mp.getCurrentTreePanel().getWidth(),
2377                                                             mp.getCurrentTreePanel().getHeight() );
2378         String file_written_to = "";
2379         boolean error = false;
2380         try {
2381             file_written_to = AptxUtil.writePhylogenyToGraphicsFile( file_name,
2382                                                                      mp.getCurrentTreePanel().getWidth(),
2383                                                                      mp.getCurrentTreePanel().getHeight(),
2384                                                                      mp.getCurrentTreePanel(),
2385                                                                      mp.getControlPanel(),
2386                                                                      type,
2387                                                                      mp.getOptions() );
2388         }
2389         catch ( final IOException e ) {
2390             error = true;
2391             JOptionPane.showMessageDialog( comp, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE );
2392         }
2393         if ( !error ) {
2394             if ( ( file_written_to != null ) && ( file_written_to.length() > 0 ) ) {
2395                 JOptionPane.showMessageDialog( comp,
2396                                                "Wrote image to: " + file_written_to,
2397                                                "Graphics Export",
2398                                                JOptionPane.INFORMATION_MESSAGE );
2399             }
2400             else {
2401                 JOptionPane.showMessageDialog( comp,
2402                                                "There was an unknown problem when attempting to write to an image file: \""
2403                                                        + file_name + "\"",
2404                                                "Error",
2405                                                JOptionPane.ERROR_MESSAGE );
2406             }
2407         }
2408         contentpane.repaint();
2409     }
2410
2411     static File writeToFile( final Phylogeny t,
2412                              final MainPanel mp,
2413                              final JFileChooser save_filechooser,
2414                              final File current_dir,
2415                              final Container contentpane,
2416                              final Component comp ) {
2417         File new_file = null;
2418         if ( t == null ) {
2419             return null;
2420         }
2421         String initial_filename = null;
2422         if ( mp.getCurrentTreePanel().getTreeFile() != null ) {
2423             try {
2424                 initial_filename = mp.getCurrentTreePanel().getTreeFile().getCanonicalPath();
2425             }
2426             catch ( final IOException e ) {
2427                 initial_filename = null;
2428             }
2429         }
2430         if ( !ForesterUtil.isEmpty( initial_filename ) ) {
2431             save_filechooser.setSelectedFile( new File( initial_filename ) );
2432         }
2433         else {
2434             save_filechooser.setSelectedFile( new File( "" ) );
2435         }
2436         final File my_dir = current_dir;
2437         if ( my_dir != null ) {
2438             save_filechooser.setCurrentDirectory( my_dir );
2439         }
2440         final int result = save_filechooser.showSaveDialog( contentpane );
2441         final File file = save_filechooser.getSelectedFile();
2442         new_file = save_filechooser.getCurrentDirectory();
2443         boolean exception = false;
2444         if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
2445             if ( file.exists() ) {
2446                 final int i = JOptionPane.showConfirmDialog( comp,
2447                                                              file + " already exists.\nOverwrite?",
2448                                                              "Overwrite?",
2449                                                              JOptionPane.OK_CANCEL_OPTION,
2450                                                              JOptionPane.QUESTION_MESSAGE );
2451                 if ( i != JOptionPane.OK_OPTION ) {
2452                     return null;
2453                 }
2454                 else {
2455                     final File to = new File( file.getAbsoluteFile().toString() + AptxConstants.BACKUP_FILE_SUFFIX );
2456                     try {
2457                         ForesterUtil.copyFile( file, to );
2458                     }
2459                     catch ( final Exception e ) {
2460                         JOptionPane.showMessageDialog( comp,
2461                                                        "Failed to create backup copy " + to,
2462                                                        "Failed to Create Backup Copy",
2463                                                        JOptionPane.WARNING_MESSAGE );
2464                     }
2465                     try {
2466                         file.delete();
2467                     }
2468                     catch ( final Exception e ) {
2469                         JOptionPane.showMessageDialog( comp,
2470                                                        "Failed to delete: " + file,
2471                                                        "Failed to Delete",
2472                                                        JOptionPane.WARNING_MESSAGE );
2473                     }
2474                 }
2475             }
2476             if ( save_filechooser.getFileFilter() == MainFrame.nhfilter ) {
2477                 exception = writeAsNewHampshire( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2478             }
2479             else if ( save_filechooser.getFileFilter() == MainFrame.xmlfilter ) {
2480                 exception = writeAsPhyloXml( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2481             }
2482             else if ( save_filechooser.getFileFilter() == MainFrame.nexusfilter ) {
2483                 exception = writeAsNexus( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2484             }
2485             // "*.*":
2486             else {
2487                 final String file_name = file.getName().trim().toLowerCase();
2488                 if ( file_name.endsWith( ".nh" ) || file_name.endsWith( ".newick" ) || file_name.endsWith( ".phy" )
2489                         || file_name.endsWith( ".tree" ) ) {
2490                     exception = writeAsNewHampshire( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2491                 }
2492                 else if ( file_name.endsWith( ".nex" ) || file_name.endsWith( ".nexus" ) ) {
2493                     exception = writeAsNexus( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2494                 }
2495                 // XML is default:
2496                 else {
2497                     exception = writeAsPhyloXml( mp.getCurrentTreePanel(), mp.getOptions(), exception, file );
2498                 }
2499             }
2500             if ( !exception ) {
2501                 mp.setTitleOfSelectedTab( file.getName() );
2502                 mp.getCurrentTreePanel().setTreeFile( file );
2503                 mp.getCurrentTreePanel().setEdited( false );
2504             }
2505         }
2506         return new_file;
2507     }
2508
2509     static File writeToGraphicsFile( final Phylogeny t,
2510                                      final GraphicsExportType type,
2511                                      final MainPanel mp,
2512                                      final JFileChooser writetographics_filechooser,
2513                                      final Component component,
2514                                      final Container contentpane,
2515                                      final File current_dir ) {
2516         File new_dir = null;
2517         if ( ( t == null ) || t.isEmpty() ) {
2518             return null;
2519         }
2520         String initial_filename = "";
2521         if ( mp.getCurrentTreePanel().getTreeFile() != null ) {
2522             initial_filename = mp.getCurrentTreePanel().getTreeFile().toString();
2523         }
2524         if ( initial_filename.indexOf( '.' ) > 0 ) {
2525             initial_filename = initial_filename.substring( 0, initial_filename.lastIndexOf( '.' ) );
2526         }
2527         initial_filename = initial_filename + "." + type;
2528         writetographics_filechooser.setSelectedFile( new File( initial_filename ) );
2529         final File my_dir = current_dir;
2530         if ( my_dir != null ) {
2531             writetographics_filechooser.setCurrentDirectory( my_dir );
2532         }
2533         final int result = writetographics_filechooser.showSaveDialog( contentpane );
2534         File file = writetographics_filechooser.getSelectedFile();
2535         //setCurrentDir( writetographics_filechooser.getCurrentDirectory() );
2536         new_dir = writetographics_filechooser.getCurrentDirectory();
2537         if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
2538             if ( !file.toString().toLowerCase().endsWith( type.toString() ) ) {
2539                 file = new File( file.toString() + "." + type );
2540             }
2541             if ( file.exists() ) {
2542                 final int i = JOptionPane.showConfirmDialog( component,
2543                                                              file + " already exists. Overwrite?",
2544                                                              "Warning",
2545                                                              JOptionPane.OK_CANCEL_OPTION,
2546                                                              JOptionPane.WARNING_MESSAGE );
2547                 if ( i != JOptionPane.OK_OPTION ) {
2548                     return null;
2549                 }
2550                 else {
2551                     try {
2552                         file.delete();
2553                     }
2554                     catch ( final Exception e ) {
2555                         JOptionPane.showMessageDialog( component,
2556                                                        "Failed to delete: " + file,
2557                                                        "Error",
2558                                                        JOptionPane.WARNING_MESSAGE );
2559                     }
2560                 }
2561             }
2562             writePhylogenyToGraphicsFile( file.toString(), type, mp, component, contentpane );
2563         }
2564         return new_dir;
2565     }
2566
2567     static File writeToPdf( final Phylogeny t,
2568                             final MainPanel mp,
2569                             final JFileChooser writetopdf_filechooser,
2570                             final File curr_dir,
2571                             final Container contentpane,
2572                             final Component component ) {
2573         if ( ( t == null ) || t.isEmpty() ) {
2574             return null;
2575         }
2576         String initial_filename = "";
2577         if ( mp.getCurrentTreePanel().getTreeFile() != null ) {
2578             initial_filename = mp.getCurrentTreePanel().getTreeFile().toString();
2579         }
2580         if ( initial_filename.indexOf( '.' ) > 0 ) {
2581             initial_filename = initial_filename.substring( 0, initial_filename.lastIndexOf( '.' ) );
2582         }
2583         initial_filename = initial_filename + ".pdf";
2584         writetopdf_filechooser.setSelectedFile( new File( initial_filename ) );
2585         final File my_dir = curr_dir;
2586         if ( my_dir != null ) {
2587             writetopdf_filechooser.setCurrentDirectory( my_dir );
2588         }
2589         final int result = writetopdf_filechooser.showSaveDialog( contentpane );
2590         File file = writetopdf_filechooser.getSelectedFile();
2591         // setCurrentDir( writetopdf_filechooser.getCurrentDirectory() );
2592         final File new_current_dir = writetopdf_filechooser.getCurrentDirectory();
2593         if ( ( file != null ) && ( result == JFileChooser.APPROVE_OPTION ) ) {
2594             if ( !file.toString().toLowerCase().endsWith( ".pdf" ) ) {
2595                 file = new File( file.toString() + ".pdf" );
2596             }
2597             if ( file.exists() ) {
2598                 final int i = JOptionPane.showConfirmDialog( component,
2599                                                              file + " already exists. Overwrite?",
2600                                                              "WARNING",
2601                                                              JOptionPane.OK_CANCEL_OPTION,
2602                                                              JOptionPane.WARNING_MESSAGE );
2603                 if ( i != JOptionPane.OK_OPTION ) {
2604                     return null;
2605                 }
2606             }
2607             printPhylogenyToPdf( file.toString(), mp.getOptions(), mp.getCurrentTreePanel(), component );
2608         }
2609         return new_current_dir;
2610     }
2611 }
2612
2613 class DefaultFilter extends FileFilter {
2614
2615     @Override
2616     public boolean accept( final File f ) {
2617         final String file_name = f.getName().trim().toLowerCase();
2618         return file_name.endsWith( ".nh" ) || file_name.endsWith( ".newick" ) || file_name.endsWith( ".phy" )
2619                 || file_name.endsWith( ".nwk" ) || file_name.endsWith( ".phb" ) || file_name.endsWith( ".ph" )
2620                 || file_name.endsWith( ".tr" ) || file_name.endsWith( ".dnd" ) || file_name.endsWith( ".tree" )
2621                 || file_name.endsWith( ".nhx" ) || file_name.endsWith( ".xml" ) || file_name.endsWith( ".phyloxml" )
2622                 || file_name.endsWith( "phylo.xml" ) || file_name.endsWith( ".pxml" ) || file_name.endsWith( ".nexus" )
2623                 || file_name.endsWith( ".nx" ) || file_name.endsWith( ".nex" ) || file_name.endsWith( ".tre" )
2624                 || file_name.endsWith( ".zip" ) || file_name.endsWith( ".tol" ) || file_name.endsWith( ".tolxml" )
2625                 || file_name.endsWith( ".con" ) || f.isDirectory();
2626     }
2627
2628     @Override
2629     public String getDescription() {
2630         return "All supported files (*.xml, *.phyloxml, *phylo.xml, *.nhx, *.nh, *.newick, *.nex, *.nexus, *.phy, *.tre, *.tree, *.tol, ...)";
2631     }
2632 }
2633
2634 class GraphicsFileFilter extends FileFilter {
2635
2636     @Override
2637     public boolean accept( final File f ) {
2638         final String file_name = f.getName().trim().toLowerCase();
2639         return file_name.endsWith( ".jpg" ) || file_name.endsWith( ".jpeg" ) || file_name.endsWith( ".png" )
2640                 || file_name.endsWith( ".gif" ) || file_name.endsWith( ".bmp" ) || f.isDirectory();
2641     }
2642
2643     @Override
2644     public String getDescription() {
2645         return "Image files (*.jpg, *.jpeg, *.png, *.gif, *.bmp)";
2646     }
2647 }
2648
2649 class MsaFileFilter extends FileFilter {
2650
2651     @Override
2652     public boolean accept( final File f ) {
2653         final String file_name = f.getName().trim().toLowerCase();
2654         return file_name.endsWith( ".msa" ) || file_name.endsWith( ".aln" ) || file_name.endsWith( ".fasta" )
2655                 || file_name.endsWith( ".fas" ) || file_name.endsWith( ".fa" ) || f.isDirectory();
2656     }
2657
2658     @Override
2659     public String getDescription() {
2660         return "Multiple sequence alignment files (*.msa, *.aln, *.fasta, *.fa, *.fas)";
2661     }
2662 }
2663
2664 class NexusFilter extends FileFilter {
2665
2666     @Override
2667     public boolean accept( final File f ) {
2668         final String file_name = f.getName().trim().toLowerCase();
2669         return file_name.endsWith( ".nex" ) || file_name.endsWith( ".nexus" ) || file_name.endsWith( ".nx" )
2670                 || file_name.endsWith( ".tre" ) || f.isDirectory();
2671     }
2672
2673     @Override
2674     public String getDescription() {
2675         return "Nexus files (*.nex, *.nexus, *.nx, *.tre)";
2676     }
2677 } // NexusFilter
2678
2679 class NHFilter extends FileFilter {
2680
2681     @Override
2682     public boolean accept( final File f ) {
2683         final String file_name = f.getName().trim().toLowerCase();
2684         return file_name.endsWith( ".nh" ) || file_name.endsWith( ".newick" ) || file_name.endsWith( ".phy" )
2685                 || file_name.endsWith( ".tr" ) || file_name.endsWith( ".tree" ) || file_name.endsWith( ".dnd" )
2686                 || file_name.endsWith( ".ph" ) || file_name.endsWith( ".phb" ) || file_name.endsWith( ".nwk" )
2687                 || f.isDirectory();
2688     }
2689
2690     @Override
2691     public String getDescription() {
2692         return "New Hampshire - Newick files (*.nh, *.newick, *.phy, *.tree, *.dnd, *.tr, *.ph, *.phb, *.nwk)";
2693     }
2694 } // NHFilter
2695
2696 class NHXFilter extends FileFilter {
2697
2698     @Override
2699     public boolean accept( final File f ) {
2700         final String file_name = f.getName().trim().toLowerCase();
2701         return file_name.endsWith( ".nhx" ) || f.isDirectory();
2702     }
2703
2704     @Override
2705     public String getDescription() {
2706         return "NHX files (*.nhx) [deprecated]";
2707     }
2708 }
2709
2710 class PdfFilter extends FileFilter {
2711
2712     @Override
2713     public boolean accept( final File f ) {
2714         return f.getName().trim().toLowerCase().endsWith( ".pdf" ) || f.isDirectory();
2715     }
2716
2717     @Override
2718     public String getDescription() {
2719         return "PDF files (*.pdf)";
2720     }
2721 } // PdfFilter
2722
2723 class SequencesFileFilter extends FileFilter {
2724
2725     @Override
2726     public boolean accept( final File f ) {
2727         final String file_name = f.getName().trim().toLowerCase();
2728         return file_name.endsWith( ".fasta" ) || file_name.endsWith( ".fa" ) || file_name.endsWith( ".fas" )
2729                 || file_name.endsWith( ".seqs" ) || f.isDirectory();
2730     }
2731
2732     @Override
2733     public String getDescription() {
2734         return "Sequences files (*.fasta, *.fa, *.fas, *.seqs )";
2735     }
2736 }
2737
2738 class TolFilter extends FileFilter {
2739
2740     @Override
2741     public boolean accept( final File f ) {
2742         final String file_name = f.getName().trim().toLowerCase();
2743         return ( file_name.endsWith( ".tol" ) || file_name.endsWith( ".tolxml" ) || file_name.endsWith( ".zip" ) || f
2744                 .isDirectory() ) && ( !file_name.endsWith( ".xml.zip" ) );
2745     }
2746
2747     @Override
2748     public String getDescription() {
2749         return "Tree of Life files (*.tol, *.tolxml)";
2750     }
2751 } // TolFilter
2752
2753 class XMLFilter extends FileFilter {
2754
2755     @Override
2756     public boolean accept( final File f ) {
2757         final String file_name = f.getName().trim().toLowerCase();
2758         return file_name.endsWith( ".xml" ) || file_name.endsWith( ".phyloxml" ) || file_name.endsWith( "phylo.xml" )
2759                 || file_name.endsWith( ".pxml" ) || file_name.endsWith( ".zip" ) || f.isDirectory();
2760     }
2761
2762     @Override
2763     public String getDescription() {
2764         return "phyloXML files (*.xml, *.phyloxml, *phylo.xml, *.pxml, *.zip)";
2765     }
2766 } // XMLFilter