Merge branch 'releases/Release_2_11_3_Branch'
[jalview.git] / archaeopteryx / ArchaeopteryxE.java
1
2 package org.forester.archaeopteryx;
3
4 import java.awt.BorderLayout;
5 import java.awt.Container;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8 import java.awt.event.ComponentAdapter;
9 import java.awt.event.ComponentEvent;
10 import java.io.ByteArrayOutputStream;
11 import java.io.File;
12 import java.io.IOException;
13 import java.net.URL;
14 import java.util.LinkedList;
15 import java.util.List;
16 import java.util.NoSuchElementException;
17
18 import javax.swing.ButtonGroup;
19 import javax.swing.JApplet;
20 import javax.swing.JCheckBoxMenuItem;
21 import javax.swing.JFileChooser;
22 import javax.swing.JMenu;
23 import javax.swing.JMenuBar;
24 import javax.swing.JMenuItem;
25 import javax.swing.JOptionPane;
26 import javax.swing.JRadioButtonMenuItem;
27 import javax.swing.UIManager;
28 import javax.swing.UnsupportedLookAndFeelException;
29 import javax.swing.event.ChangeEvent;
30 import javax.swing.event.ChangeListener;
31
32 import org.apache.commons.codec.binary.Base64;
33 import org.forester.archaeopteryx.AptxUtil.GraphicsExportType;
34 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;
35 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
36 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;
37 import org.forester.io.parsers.nhx.NHXParser.TAXONOMY_EXTRACTION;
38 import org.forester.phylogeny.Phylogeny;
39 import org.forester.phylogeny.PhylogenyMethods;
40 import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY;
41 import org.forester.phylogeny.data.SequenceRelation;
42 import org.forester.sdi.GSDI;
43 import org.forester.sdi.GSDIR;
44 import org.forester.sdi.SDIException;
45 import org.forester.util.ForesterConstants;
46 import org.forester.util.ForesterUtil;
47 import org.forester.util.WindowsUtils;
48
49 // Use like this:
50 // <applet archive="forester.jar"
51 // code="org.forester.archaeopteryx.ArchaeopteryxE.class"
52 // codebase="http://www.myserver.org/path/to/forester"
53 // width="600"
54 // height="500"
55 // alt="ArchaeopteryxE is not working on your system (requires at least Sun Java 1.5)!">
56 // <param name="url_of_tree_to_load"
57 // value="http://www.myserver.org/examples/data/apaf.xml">
58 // <param name="config_file"
59 // value="http://www.myserver.org/examples/config/config_file.txt">
60 // </applet>
61 public class ArchaeopteryxE extends JApplet implements ActionListener {
62
63     private final static String         NAME             = "ArchaeopteryxE";
64     private static final long           serialVersionUID = -1220055577935759443L;
65     private Configuration               _configuration;
66     private MainPanel                   _mainpanel;
67     private JMenuBar                    _jmenubar;
68     private JMenu                       _options_jmenu;
69     private JMenu                       _font_size_menu;
70     private JMenuItem                   _super_tiny_fonts_mi;
71     private JMenuItem                   _tiny_fonts_mi;
72     private JMenuItem                   _small_fonts_mi;
73     private JMenuItem                   _medium_fonts_mi;
74     private JMenuItem                   _large_fonts_mi;
75     private JMenu                       _tools_menu;
76     private JMenuItem                   _taxcolor_item;
77     private JMenuItem                   _confcolor_item;
78     private JMenuItem                   _midpoint_root_item;
79     private JMenu                       _view_jmenu;
80     private JMenuItem                   _view_as_XML_item;
81     private JMenuItem                   _view_as_NH_item;
82     private JMenuItem                   _view_as_nexus_item;
83     private JMenuItem                   _display_basic_information_item;
84     private JMenu                       _type_menu;
85     private JCheckBoxMenuItem           _rectangular_type_cbmi;
86     private JCheckBoxMenuItem           _triangular_type_cbmi;
87     private JCheckBoxMenuItem           _curved_type_cbmi;
88     private JCheckBoxMenuItem           _convex_type_cbmi;
89     private JCheckBoxMenuItem           _euro_type_cbmi;
90     private JCheckBoxMenuItem           _rounded_type_cbmi;
91     private JCheckBoxMenuItem           _unrooted_type_cbmi;
92     private JCheckBoxMenuItem           _circular_type_cbmi;
93     private JMenuItem                   _help_item;
94     private JMenuItem                   _about_item;
95     private JMenu                       _help_jmenu;
96     private JMenuItem                   _website_item;
97     private JMenuItem                   _phyloxml_website_item;
98     private JMenuItem                   _phyloxml_ref_item;
99     private JMenuItem                   _aptx_ref_item;
100     private JMenuItem                   _remove_branch_color_item;
101     private JMenuItem                   _remove_visual_styles_item;
102     private JCheckBoxMenuItem           _show_domain_labels;
103     private JCheckBoxMenuItem           _show_annotation_ref_source;
104     private JCheckBoxMenuItem           _color_labels_same_as_parent_branch;
105     private JCheckBoxMenuItem           _abbreviate_scientific_names;
106     private JCheckBoxMenuItem           _screen_antialias_cbmi;
107     private JCheckBoxMenuItem           _background_gradient_cbmi;
108     private JCheckBoxMenuItem           _color_by_taxonomic_group_cbmi;
109     private JRadioButtonMenuItem        _non_lined_up_cladograms_rbmi;
110     private JRadioButtonMenuItem        _uniform_cladograms_rbmi;
111     private JRadioButtonMenuItem        _ext_node_dependent_cladogram_rbmi;
112     private Options                     _options;
113     private JMenuItem                   _choose_font_mi;
114     private JMenuItem                   _switch_colors_mi;
115     JCheckBoxMenuItem                   _label_direction_cbmi;
116     private JCheckBoxMenuItem           _show_scale_cbmi;
117     private JCheckBoxMenuItem           _search_case_senstive_cbmi;
118     private JCheckBoxMenuItem           _search_whole_words_only_cbmi;
119     private JCheckBoxMenuItem           _inverse_search_result_cbmi;
120     private JCheckBoxMenuItem           _search_with_regex_cbmi;
121     private JCheckBoxMenuItem           _show_overview_cbmi;
122     private JMenuItem                   _choose_minimal_confidence_mi;
123     private JMenuItem                   _collapse_species_specific_subtrees;
124     private JMenuItem                   _overview_placment_mi;
125     private ButtonGroup                 _radio_group_1;
126     private JCheckBoxMenuItem           _show_default_node_shapes_internal_cbmi;
127     private JCheckBoxMenuItem           _show_default_node_shapes_external_cbmi;
128     private JCheckBoxMenuItem           _show_default_node_shapes_for_marked_cbmi;
129     private JMenuItem                   _cycle_node_shape_mi;
130     private JMenuItem                   _cycle_node_fill_mi;
131     private JMenuItem                   _choose_node_size_mi;
132     private JCheckBoxMenuItem           _show_confidence_stddev_cbmi;
133     private final LinkedList<TextFrame> _textframes      = new LinkedList<TextFrame>();
134     private JMenu                       _analysis_menu;
135     private JMenuItem                   _gsdi_item;
136     private JMenuItem                   _gsdir_item;
137     private Phylogeny                   _species_tree;
138     private JCheckBoxMenuItem           _right_line_up_domains_cbmi;
139     private JCheckBoxMenuItem           _line_up_renderable_data_cbmi;
140     // file menu:
141     private JMenuItem                   _save_item;
142     private JMenuItem                   _print_item;
143     private JMenuItem                   _write_to_pdf_item;
144     private JMenuItem                   _write_to_jpg_item;
145     private JMenuItem                   _write_to_gif_item;
146     private JMenuItem                   _write_to_tif_item;
147     private JMenuItem                   _write_to_png_item;
148     private JMenuItem                   _write_to_bmp_item;
149     private JMenu                       _file_jmenu;
150     private JFileChooser                _writetopdf_filechooser;
151     private File                        _current_dir;
152     private JFileChooser                _save_filechooser;
153     private JFileChooser                _writetographics_filechooser;
154     private JCheckBoxMenuItem           _graphics_export_visible_only_cbmi;
155     private JCheckBoxMenuItem           _antialias_print_cbmi;
156     private JCheckBoxMenuItem           _print_black_and_white_cbmi;
157     private JMenuItem                   _choose_pdf_width_mi;
158
159     @Override
160     public void actionPerformed( final ActionEvent e ) {
161         final Object o = e.getSource();
162         if ( o == _midpoint_root_item ) {
163             getMainPanel().getCurrentTreePanel().midpointRoot();
164         }
165         else if ( o == _gsdi_item ) {
166             if ( isSubtreeDisplayed() ) {
167                 return;
168             }
169             executeGSDI();
170         }
171         else if ( o == _gsdir_item ) {
172             if ( isSubtreeDisplayed() ) {
173                 return;
174             }
175             executeGSDIR();
176         }
177         else if ( o == _taxcolor_item ) {
178             getMainPanel().getCurrentTreePanel().taxColor();
179         }
180         else if ( o == _confcolor_item ) {
181             getMainPanel().getCurrentTreePanel().confColor();
182         }
183         else if ( o == _collapse_species_specific_subtrees ) {
184             if ( getCurrentTreePanel() != null ) {
185                 getCurrentTreePanel().collapseSpeciesSpecificSubtrees();
186             }
187         }
188         else if ( o == _remove_branch_color_item ) {
189             removeBranchColors();
190         }
191         else if ( o == _remove_visual_styles_item ) {
192             removeVisualStyles();
193         }
194         else if ( o == _switch_colors_mi ) {
195             switchColors();
196         }
197         else if ( o == _display_basic_information_item ) {
198             displayBasicInformation();
199         }
200         else if ( o == _view_as_NH_item ) {
201             viewAsNH();
202         }
203         else if ( o == _view_as_XML_item ) {
204             viewAsXML();
205         }
206         else if ( o == _view_as_nexus_item ) {
207             viewAsNexus();
208         }
209         else if ( o == _super_tiny_fonts_mi ) {
210             if ( getCurrentTreePanel() != null ) {
211                 getCurrentTreePanel().setSuperTinyFonts();
212                 getCurrentTreePanel().repaint();
213             }
214         }
215         else if ( o == _tiny_fonts_mi ) {
216             if ( getCurrentTreePanel() != null ) {
217                 getCurrentTreePanel().setTinyFonts();
218                 getCurrentTreePanel().repaint();
219             }
220         }
221         else if ( o == _small_fonts_mi ) {
222             if ( getCurrentTreePanel() != null ) {
223                 getCurrentTreePanel().setSmallFonts();
224                 getCurrentTreePanel().repaint();
225             }
226         }
227         else if ( o == _medium_fonts_mi ) {
228             if ( getCurrentTreePanel() != null ) {
229                 getCurrentTreePanel().setMediumFonts();
230                 getCurrentTreePanel().repaint();
231             }
232         }
233         else if ( o == _large_fonts_mi ) {
234             if ( getCurrentTreePanel() != null ) {
235                 getCurrentTreePanel().setLargeFonts();
236                 getCurrentTreePanel().repaint();
237             }
238         }
239         else if ( o == _choose_font_mi ) {
240             chooseFont();
241         }
242         else if ( o == _choose_minimal_confidence_mi ) {
243             chooseMinimalConfidence();
244         }
245         else if ( o == _choose_node_size_mi ) {
246             MainFrame.chooseNodeSize( getOptions(), this );
247         }
248         else if ( o == _overview_placment_mi ) {
249             MainFrame.cycleOverview( getOptions(), getCurrentTreePanel() );
250         }
251         else if ( o == _cycle_node_fill_mi ) {
252             MainFrame.cycleNodeFill( getOptions() );
253         }
254         else if ( o == _cycle_node_shape_mi ) {
255             MainFrame.cycleNodeShape( getOptions() );
256         }
257         else if ( o == _non_lined_up_cladograms_rbmi ) {
258             updateOptions( getOptions() );
259             _mainpanel.getControlPanel().showWhole();
260         }
261         else if ( o == _uniform_cladograms_rbmi ) {
262             updateOptions( getOptions() );
263             _mainpanel.getControlPanel().showWhole();
264         }
265         else if ( o == _ext_node_dependent_cladogram_rbmi ) {
266             updateOptions( getOptions() );
267             _mainpanel.getControlPanel().showWhole();
268         }
269         else if ( o == _search_case_senstive_cbmi ) {
270             updateOptions( getOptions() );
271             getMainPanel().getControlPanel().search0();
272             getMainPanel().getControlPanel().search1();
273         }
274         else if ( o == _search_whole_words_only_cbmi ) {
275             if ( ( _search_with_regex_cbmi != null ) && _search_whole_words_only_cbmi.isSelected() ) {
276                 _search_with_regex_cbmi.setSelected( false );
277             }
278             updateOptions( getOptions() );
279             getMainPanel().getControlPanel().search0();
280             getMainPanel().getControlPanel().search1();
281         }
282         else if ( o == _inverse_search_result_cbmi ) {
283             updateOptions( getOptions() );
284             getMainPanel().getControlPanel().search0();
285             getMainPanel().getControlPanel().search1();
286         }
287         else if ( o == _search_with_regex_cbmi ) {
288             if ( ( _search_whole_words_only_cbmi != null ) && _search_with_regex_cbmi.isSelected() ) {
289                 _search_whole_words_only_cbmi.setSelected( false );
290             }
291             if ( ( _search_case_senstive_cbmi != null ) && _search_with_regex_cbmi.isSelected() ) {
292                 _search_case_senstive_cbmi.setSelected( true );
293             }
294             updateOptions( getOptions() );
295             getMainPanel().getControlPanel().search0();
296             getMainPanel().getControlPanel().search1();
297         }
298         else if ( o == _show_scale_cbmi ) {
299             updateOptions( getOptions() );
300         }
301         else if ( o == _show_confidence_stddev_cbmi ) {
302             updateOptions( getOptions() );
303         }
304         else if ( o == _label_direction_cbmi ) {
305             updateOptions( getOptions() );
306         }
307         else if ( o == _abbreviate_scientific_names ) {
308             updateOptions( getOptions() );
309         }
310         else if ( o == _show_overview_cbmi ) {
311             updateOptions( getOptions() );
312             if ( getCurrentTreePanel() != null ) {
313                 getCurrentTreePanel().updateOvSizes();
314             }
315         }
316         else if ( ( o == _rectangular_type_cbmi ) || ( o == _triangular_type_cbmi ) || ( o == _curved_type_cbmi )
317                 || ( o == _convex_type_cbmi ) || ( o == _rounded_type_cbmi ) || ( o == _euro_type_cbmi )
318                 || ( o == _unrooted_type_cbmi ) || ( o == _circular_type_cbmi ) ) {
319             typeChanged( o );
320         }
321         else if ( o == _screen_antialias_cbmi ) {
322             updateOptions( getOptions() );
323             setupScreenTextAntialias( getMainPanel().getTreePanels(), isScreenAntialias() );
324         }
325         else if ( o == _background_gradient_cbmi ) {
326             updateOptions( getOptions() );
327         }
328         else if ( o == _show_domain_labels ) {
329             updateOptions( getOptions() );
330         }
331         else if ( o == _color_labels_same_as_parent_branch ) {
332             updateOptions( getOptions() );
333         }
334         else if ( o == _show_default_node_shapes_internal_cbmi ) {
335             updateOptions( getOptions() );
336         }
337         else if ( o == _show_default_node_shapes_external_cbmi ) {
338             updateOptions( getOptions() );
339         }
340         else if ( o == _about_item ) {
341             MainFrame.about();
342         }
343         else if ( o == _help_item ) {
344             try {
345                 AptxUtil.openWebsite( AptxConstants.APTX_DOC_SITE, true, this );
346             }
347             catch ( final IOException e1 ) {
348                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
349             }
350         }
351         else if ( o == _website_item ) {
352             try {
353                 AptxUtil.openWebsite( AptxConstants.APTX_WEB_SITE, true, this );
354             }
355             catch ( final IOException e1 ) {
356                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
357             }
358         }
359         else if ( o == _phyloxml_website_item ) {
360             try {
361                 AptxUtil.openWebsite( AptxConstants.PHYLOXML_WEB_SITE, true, this );
362             }
363             catch ( final IOException e1 ) {
364                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
365             }
366         }
367         else if ( o == _aptx_ref_item ) {
368             try {
369                 AptxUtil.openWebsite( AptxConstants.APTX_REFERENCE_URL, true, this );
370             }
371             catch ( final IOException e1 ) {
372                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
373             }
374         }
375         else if ( o == _phyloxml_ref_item ) {
376             try {
377                 AptxUtil.openWebsite( AptxConstants.PHYLOXML_REFERENCE_URL, true, this );
378             }
379             catch ( final IOException e1 ) {
380                 ForesterUtil.printErrorMessage( AptxConstants.PRG_NAME, e1.toString() );
381             }
382         }
383         else if ( o == _color_by_taxonomic_group_cbmi ) {
384             updateOptions( getOptions() );
385         }
386         else if ( o == _line_up_renderable_data_cbmi ) {
387             if ( !_line_up_renderable_data_cbmi.isSelected() ) {
388                 _right_line_up_domains_cbmi.setSelected( false );
389             }
390             updateOptions( getOptions() );
391         }
392         else if ( o == _right_line_up_domains_cbmi ) {
393             if ( _right_line_up_domains_cbmi.isSelected() ) {
394                 _line_up_renderable_data_cbmi.setSelected( true );
395             }
396             updateOptions( getOptions() );
397         }
398         else if ( o == _write_to_pdf_item ) {
399             final File curr_dir = MainFrame.writeToPdf( _mainpanel.getCurrentPhylogeny(),
400                                                         getMainPanel(),
401                                                         _writetopdf_filechooser,
402                                                         _current_dir,
403                                                         getContentPane(),
404                                                         this );
405             if ( curr_dir != null ) {
406                 setCurrentDir( curr_dir );
407             }
408         }
409         else if ( o == _write_to_jpg_item ) {
410             final File curr_dir = MainFrame.writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
411                                                                  GraphicsExportType.JPG,
412                                                                  _mainpanel,
413                                                                  _writetographics_filechooser,
414                                                                  this,
415                                                                  getContentPane(),
416                                                                  _current_dir );
417             if ( curr_dir != null ) {
418                 setCurrentDir( curr_dir );
419             }
420         }
421         else if ( o == _write_to_gif_item ) {
422             final File curr_dir = MainFrame.writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
423                                                                  GraphicsExportType.GIF,
424                                                                  _mainpanel,
425                                                                  _writetographics_filechooser,
426                                                                  this,
427                                                                  getContentPane(),
428                                                                  _current_dir );
429             if ( curr_dir != null ) {
430                 setCurrentDir( curr_dir );
431             }
432         }
433         else if ( o == _write_to_tif_item ) {
434             final File curr_dir = MainFrame.writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
435                                                                  GraphicsExportType.TIFF,
436                                                                  _mainpanel,
437                                                                  _writetographics_filechooser,
438                                                                  this,
439                                                                  getContentPane(),
440                                                                  _current_dir );
441             if ( curr_dir != null ) {
442                 setCurrentDir( curr_dir );
443             }
444         }
445         else if ( o == _write_to_bmp_item ) {
446             final File curr_dir = MainFrame.writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
447                                                                  GraphicsExportType.BMP,
448                                                                  _mainpanel,
449                                                                  _writetographics_filechooser,
450                                                                  this,
451                                                                  getContentPane(),
452                                                                  _current_dir );
453             if ( curr_dir != null ) {
454                 setCurrentDir( curr_dir );
455             }
456         }
457         else if ( o == _write_to_png_item ) {
458             final File curr_dir = MainFrame.writeToGraphicsFile( _mainpanel.getCurrentPhylogeny(),
459                                                                  GraphicsExportType.PNG,
460                                                                  _mainpanel,
461                                                                  _writetographics_filechooser,
462                                                                  this,
463                                                                  getContentPane(),
464                                                                  _current_dir );
465             if ( curr_dir != null ) {
466                 setCurrentDir( curr_dir );
467             }
468         }
469         else if ( o == _print_item ) {
470             MainFrame.print( getCurrentTreePanel(), getOptions(), this );
471         }
472         else if ( o == _save_item ) {
473             final File new_dir = MainFrame.writeToFile( _mainpanel.getCurrentPhylogeny(),
474                                                         getMainPanel(),
475                                                         _save_filechooser,
476                                                         _current_dir,
477                                                         getContentPane(),
478                                                         this );
479             if ( new_dir != null ) {
480                 setCurrentDir( new_dir );
481             }
482         }
483         else if ( o == _graphics_export_visible_only_cbmi ) {
484             updateOptions( getOptions() );
485         }
486         else if ( o == _antialias_print_cbmi ) {
487             updateOptions( getOptions() );
488         }
489         else if ( o == _print_black_and_white_cbmi ) {
490             updateOptions( getOptions() );
491         }
492         else if ( o == _choose_pdf_width_mi ) {
493             choosePdfWidth();
494         }
495         repaint();
496     }
497
498     @Override
499     public void destroy() {
500         AptxUtil.printAppletMessage( NAME, "going to be destroyed " );
501         removeAllTextFrames();
502         if ( getMainPanel() != null ) {
503             getMainPanel().terminate();
504         }
505     }
506
507     /**
508      * This method returns the current external node data which
509      * has been selected by the user by clicking the "Return ..."
510      * menu item. This method is expected to be called from Javascript or
511      * something like it.
512      *
513      * @return current external node data as String
514      */
515     public String getCurrentExternalNodesDataBuffer() {
516         return getCurrentTreePanel().getCurrentExternalNodesDataBufferAsString();
517     }
518
519     public int getCurrentExternalNodesDataBufferChangeCounter() {
520         return getCurrentTreePanel().getCurrentExternalNodesDataBufferChangeCounter();
521     }
522
523     public int getCurrentExternalNodesDataBufferLength() {
524         return getCurrentTreePanel().getCurrentExternalNodesDataBufferAsString().length();
525     }
526
527     /**
528      * This method returns the current phylogeny as a string in the chosen format
529      *
530      * @param format must be NH, NHX, NEXUS or PHYLOXML
531      * @return the phylogeny string
532      * @author Herve Menager
533      */
534     public String getCurrentPhylogeny( final String format ) {
535         removeAllTextFrames();
536         if ( ( getMainPanel().getCurrentPhylogeny() == null ) || getMainPanel().getCurrentPhylogeny().isEmpty()
537                 || ( getMainPanel().getCurrentPhylogeny().getNumberOfExternalNodes() > 10000 ) ) {
538             return new String();
539         }
540         switch ( ForesterConstants.PhylogeneticTreeFormats.valueOf( format ) ) {
541             case NH:
542                 return getMainPanel().getCurrentPhylogeny().toNewHampshire();
543             case NHX:
544                 return getMainPanel().getCurrentPhylogeny().toNewHampshireX();
545             case NEXUS:
546                 return getMainPanel().getCurrentPhylogeny().toNexus();
547             case PHYLOXML:
548                 return getMainPanel().getCurrentPhylogeny().toPhyloXML( -1 );
549             default:
550                 break;
551         }
552         return new String();
553     }
554
555     /**
556      * This method returns a view of the current phylogeny in a chosen
557      * graphics format, base64-encoded in a string so that in can be used
558      * from javascript.
559      *
560      * @param format must be GraphicsExportType (gif, jpg, pdf, png, tif, bmp)
561      * @return the phylogeny string
562      * @author Herve Menager
563      */
564     public String getCurrentPhylogenyGraphicsAsBase64EncodedString( final String format ) {
565         final ByteArrayOutputStream baos = new ByteArrayOutputStream();
566         try {
567             AptxUtil.writePhylogenyToGraphicsByteArrayOutputStream( baos,
568                                                                     _mainpanel.getWidth(),
569                                                                     _mainpanel.getHeight(),
570                                                                     getCurrentTreePanel(),
571                                                                     getCurrentTreePanel().getControlPanel(),
572                                                                     GraphicsExportType.valueOf( format ),
573                                                                     getOptions() );
574         }
575         catch ( final IOException ioe ) {
576             ForesterUtil.printErrorMessage( NAME, ioe.toString() );
577             ioe.printStackTrace();
578             JOptionPane.showMessageDialog( this,
579                                            NAME + ": Failed to generate graphics: " + "\nException: " + ioe,
580                                            "Failed to generate graphics",
581                                            JOptionPane.ERROR_MESSAGE );
582             return null;
583         }
584         final byte[] bytes = baos.toByteArray();
585         final String dataImg = Base64.encodeBase64String( bytes );
586         return dataImg;
587     }
588
589     public Options getOptions() {
590         return _options;
591     }
592
593     @Override
594     public void init() {
595         _writetopdf_filechooser = new JFileChooser();
596         _writetopdf_filechooser.setMultiSelectionEnabled( false );
597         _writetopdf_filechooser.addChoosableFileFilter( MainFrame.pdffilter );
598         _writetographics_filechooser = new JFileChooser();
599         _writetographics_filechooser.setMultiSelectionEnabled( false );
600         _writetographics_filechooser.addChoosableFileFilter( MainFrame.graphicsfilefilter );
601         _save_filechooser = new JFileChooser();
602         _save_filechooser.setMultiSelectionEnabled( false );
603         _save_filechooser.setFileFilter( MainFrame.xmlfilter );
604         _save_filechooser.addChoosableFileFilter( MainFrame.nhfilter );
605         _save_filechooser.addChoosableFileFilter( MainFrame.nexusfilter );
606         _save_filechooser.addChoosableFileFilter( _save_filechooser.getAcceptAllFileFilter() );
607         try {
608             final String home_dir = System.getProperty( "user.home" );
609             _save_filechooser.setCurrentDirectory( new File( home_dir ) );
610             _writetopdf_filechooser.setCurrentDirectory( new File( home_dir ) );
611             _writetographics_filechooser.setCurrentDirectory( new File( home_dir ) );
612         }
613         catch ( final Exception e ) {
614             e.printStackTrace();
615             // Do nothing. Not important.
616         }
617         final String config_filename = getParameter( AptxConstants.APPLET_PARAM_NAME_FOR_CONFIG_FILE_URL );
618         AptxUtil.printAppletMessage( NAME, "URL for configuration file is: " + config_filename );
619         final Configuration configuration = new Configuration( config_filename, true, true, true );
620         setConfiguration( configuration );
621         setOptions( Options.createInstance( configuration ) );
622         setupUI();
623         final String tree_url_str = getParameter( AptxConstants.APPLET_PARAM_NAME_FOR_URL_OF_TREE_TO_LOAD );
624         if ( ForesterUtil.isEmpty( tree_url_str ) ) {
625             ForesterUtil.printErrorMessage( NAME, "could not get tree URL from "
626                     + AptxConstants.APPLET_PARAM_NAME_FOR_URL_OF_TREE_TO_LOAD );
627             JOptionPane.showMessageDialog( this, NAME + ": could not get tree URL from "
628                     + AptxConstants.APPLET_PARAM_NAME_FOR_URL_OF_TREE_TO_LOAD, "Failed get URL", JOptionPane.ERROR_MESSAGE );
629             return;
630         }
631         AptxUtil.printAppletMessage( NAME, "URL for phylogenies is " + tree_url_str );
632         // Get URL to tree file
633         URL phys_url = null;
634         try {
635             phys_url = new URL( tree_url_str );
636         }
637         catch ( final Exception e ) {
638             ForesterUtil.printErrorMessage( NAME, "error: " + e );
639             e.printStackTrace();
640             JOptionPane.showMessageDialog( this, NAME + ": Could not create URL from: \"" + tree_url_str
641                     + "\"\nException: " + e, "Failed to create URL", JOptionPane.ERROR_MESSAGE );
642         }
643         if ( phys_url == null ) {
644             ForesterUtil.printErrorMessage( NAME, "failed to get tree URL from "
645                     + AptxConstants.APPLET_PARAM_NAME_FOR_URL_OF_TREE_TO_LOAD );
646             JOptionPane.showMessageDialog( this,
647                                            NAME + ": Could not create URL from: \"" + tree_url_str,
648                                            "Failed to create URL",
649                                            JOptionPane.ERROR_MESSAGE );
650             return;
651         }
652         // Load the tree from URL
653         Phylogeny[] phys = null;
654         try {
655             phys = AptxUtil.readPhylogeniesFromUrl( phys_url,
656                                                     getConfiguration().isValidatePhyloXmlAgainstSchema(),
657                                                     getConfiguration().isReplaceUnderscoresInNhParsing(),
658                                                     getConfiguration().isInternalNumberAreConfidenceForNhParsing(),
659                                                     getConfiguration().getTaxonomyExtraction(),
660                                                     getConfiguration().isMidpointReroot() );
661         }
662         catch ( final Exception e ) {
663             ForesterUtil.printErrorMessage( NAME, e.toString() );
664             e.printStackTrace();
665             JOptionPane.showMessageDialog( this,
666                                            NAME + ": Failed to read phylogenies: " + "\nException: " + e,
667                                            "Failed to read phylogenies",
668                                            JOptionPane.ERROR_MESSAGE );
669         }
670         if ( phys == null ) {
671             ForesterUtil.printErrorMessage( NAME, "phylogenies from [" + phys_url + "] are null" );
672             JOptionPane.showMessageDialog( this,
673                                            NAME + ": phylogenies from [" + phys_url + "] are null",
674                                            "Failed to read phylogenies",
675                                            JOptionPane.ERROR_MESSAGE );
676             return;
677         }
678         else if ( phys.length < 1 ) {
679             ForesterUtil.printErrorMessage( NAME, "phylogenies from [" + phys_url + "] are empty" );
680             JOptionPane.showMessageDialog( this,
681                                            NAME + ": phylogenies from [" + phys_url + "] are empty",
682                                            "Failed to read phylogenies",
683                                            JOptionPane.ERROR_MESSAGE );
684             return;
685         }
686         else {
687             AptxUtil.printAppletMessage( NAME, "loaded " + phys.length + " phylogenies from: " + phys_url );
688         }
689         //
690         final String species_tree_url_str = getParameter( AptxConstants.APPLET_PARAM_NAME_FOR_URL_OF_SPECIES_TREE_TO_LOAD );
691         if ( !ForesterUtil.isEmpty( species_tree_url_str ) ) {
692             AptxUtil.printAppletMessage( NAME, "URL of species tree to load: \"" + species_tree_url_str + "\"" );
693             Phylogeny[] species_trees = null;
694             try {
695                 final URL species_tree_url = new URL( species_tree_url_str );
696                 species_trees = AptxUtil.readPhylogeniesFromUrl( species_tree_url,
697                                                                  configuration.isValidatePhyloXmlAgainstSchema(),
698                                                                  configuration.isReplaceUnderscoresInNhParsing(),
699                                                                  false,
700                                                                  TAXONOMY_EXTRACTION.NO,
701                                                                  false );
702             }
703             catch ( final IOException e ) {
704                 ForesterUtil.printErrorMessage( NAME, "could not read species tree from  [" + species_tree_url_str
705                         + "]" );
706                 JOptionPane.showMessageDialog( this, NAME + ": could not read species tree from  ["
707                         + species_tree_url_str + "]", "Failed to read species tree", JOptionPane.ERROR_MESSAGE );
708             }
709             if ( ( species_trees != null ) && ( species_trees.length > 0 ) ) {
710                 AptxUtil.printAppletMessage( NAME, "successfully read species tree" );
711                 if ( species_trees[ 0 ].isEmpty() ) {
712                     ForesterUtil.printErrorMessage( NAME, "species tree is empty" );
713                 }
714                 else if ( !species_trees[ 0 ].isRooted() ) {
715                     ForesterUtil.printErrorMessage( NAME, "species tree is not rooted" );
716                 }
717                 else {
718                     setSpeciesTree( species_trees[ 0 ] );
719                     AptxUtil.printAppletMessage( NAME, "species tree OK" );
720                 }
721             }
722         }
723         try {
724             setVisible( false );
725             setMainPanel( new MainPanelApplets( getConfiguration(), this ) );
726             _jmenubar = new JMenuBar();
727             if ( !getConfiguration().isHideControlPanelAndMenubar() ) {
728                 buildFileMenu();
729                 if ( !getConfiguration().isUseNativeUI() ) {
730                     _jmenubar.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
731                 }
732                 if ( getSpeciesTree() != null ) {
733                     buildAnalysisMenu();
734                 }
735                 buildToolsMenu();
736                 buildViewMenu();
737                 buildFontSizeMenu();
738                 buildOptionsMenu();
739                 buildTypeMenu();
740                 buildHelpMenu();
741                 setJMenuBar( _jmenubar );
742             }
743             final Container contentpane = getContentPane();
744             contentpane.setLayout( new BorderLayout() );
745             contentpane.add( getMainPanel(), BorderLayout.CENTER );
746             addComponentListener( new ComponentAdapter() {
747
748                 @Override
749                 public void componentResized( final ComponentEvent e ) {
750                     if ( getMainPanel().getCurrentTreePanel() != null ) {
751                         getMainPanel().getCurrentTreePanel().calcParametersForPainting( getMainPanel()
752                                                                                                 .getCurrentTreePanel()
753                                                                                                 .getWidth(),
754                                                                                         getMainPanel()
755                                                                                                 .getCurrentTreePanel()
756                                                                                                 .getHeight() );
757                     }
758                 }
759             } );
760             if ( getConfiguration().isUseTabbedDisplay() ) {
761                 try {
762                     AptxUtil.printAppletMessage( NAME, "using tabbed display" );
763                     AptxUtil.addPhylogeniesToTabs( phys,
764                                                    new File( phys_url.getFile() ).getName(),
765                                                    phys_url.toString(),
766                                                    getConfiguration(),
767                                                    getMainPanel() );
768                 }
769                 catch ( final Exception e ) {
770                     ForesterUtil.printErrorMessage( NAME, e.toString() );
771                     e.printStackTrace();
772                 }
773             }
774             else {
775                 AptxUtil.printAppletMessage( NAME, "not using tabbed display" );
776                 if ( getSpeciesTree() != null ) {
777                     AptxUtil.printAppletMessage( NAME,
778                                                  "Warning: gsdi (gene duplication inference) only available tabbed display" );
779                 }
780                 AptxUtil.addPhylogenyToPanel( phys, getConfiguration(), getMainPanel() );
781             }
782             validate();
783             setName( NAME );
784             getMainPanel().getControlPanel().showWholeAll();
785             getMainPanel().getControlPanel().showWhole();
786             /* GUILHEM_BEG */
787             getCurrentTreePanel().getControlPanel().getSequenceRelationTypeBox().removeAllItems();
788             for( final SequenceRelation.SEQUENCE_RELATION_TYPE type : getMainPanel().getCurrentPhylogeny()
789                     .getRelevantSequenceRelationTypes() ) {
790                 getCurrentTreePanel().getControlPanel().getSequenceRelationTypeBox().addItem( type );
791             }
792             final String default_relation = getParameter( AptxConstants.APPLET_PARAM_NAME_FOR_DEFAULT_SEQUENCE_RELATION_TYPE );
793             if ( default_relation != null ) {
794                 getCurrentTreePanel().getControlPanel().getSequenceRelationTypeBox().setSelectedItem( default_relation );
795             }
796             final String default_sequence = getParameter( AptxConstants.APPLET_PARAM_NAME_FOR_DEFAULT_QUERY_SEQUENCE );
797             if ( default_sequence != null ) {
798                 getCurrentTreePanel().getControlPanel().getSequenceRelationBox().setSelectedItem( default_sequence );
799             }
800             /* GUILHEM_END */
801             System.gc();
802             AptxUtil.printAppletMessage( NAME, "successfully initialized" );
803             setVisible( true );
804         }
805         catch ( final Exception e ) {
806             ForesterUtil.printErrorMessage( NAME, e.toString() );
807             e.printStackTrace();
808         }
809     }
810
811     public void showTextFrame( final String s, final String title ) {
812         checkTextFrames();
813         _textframes.addLast( TextFrame.instantiate( s, title, _textframes ) );
814     }
815
816     @Override
817     public void start() {
818         if ( getMainPanel() != null ) {
819             getMainPanel().validate();
820         }
821         requestFocus();
822         requestFocusInWindow();
823         requestFocus();
824         AptxUtil.printAppletMessage( NAME, "started" );
825     }
826
827     private void chooseFont() {
828         final FontChooser fc = new FontChooser();
829         fc.setFont( getMainPanel().getTreeFontSet().getLargeFont() );
830         fc.showDialog( this, "Select the Base Font" );
831         getMainPanel().getTreeFontSet().setBaseFont( fc.getFont() );
832     }
833
834     private void chooseMinimalConfidence() {
835         final String s = ( String ) JOptionPane
836                 .showInputDialog( this,
837                                   "Please the minimum for confidence values to be displayed.\n" + "[current value: "
838                                           + getOptions().getMinConfidenceValue() + "]\n",
839                                   "Minimal Confidence Value",
840                                   JOptionPane.QUESTION_MESSAGE,
841                                   null,
842                                   null,
843                                   getOptions().getMinConfidenceValue() );
844         if ( !ForesterUtil.isEmpty( s ) ) {
845             boolean success = true;
846             double m = 0.0;
847             final String m_str = s.trim();
848             if ( !ForesterUtil.isEmpty( m_str ) ) {
849                 try {
850                     m = Double.parseDouble( m_str );
851                 }
852                 catch ( final Exception ex ) {
853                     success = false;
854                 }
855             }
856             else {
857                 success = false;
858             }
859             if ( success && ( m >= 0.0 ) ) {
860                 getOptions().setMinConfidenceValue( m );
861             }
862         }
863     }
864
865     private void choosePdfWidth() {
866         final String s = ( String ) JOptionPane.showInputDialog( this,
867                                                                  "Please enter the default line width for PDF export.\n"
868                                                                          + "[current value: "
869                                                                          + getOptions().getPrintLineWidth() + "]\n",
870                                                                          "Line Width for PDF Export",
871                                                                          JOptionPane.QUESTION_MESSAGE,
872                                                                          null,
873                                                                          null,
874                                                                          getOptions().getPrintLineWidth() );
875         if ( !ForesterUtil.isEmpty( s ) ) {
876             boolean success = true;
877             float f = 0.0f;
878             final String m_str = s.trim();
879             if ( !ForesterUtil.isEmpty( m_str ) ) {
880                 try {
881                     f = Float.parseFloat( m_str );
882                 }
883                 catch ( final Exception ex ) {
884                     success = false;
885                 }
886             }
887             else {
888                 success = false;
889             }
890             if ( success && ( f > 0.0 ) ) {
891                 getOptions().setPrintLineWidth( f );
892             }
893         }
894     }
895
896     private void customizeRadioButtonMenuItem( final JRadioButtonMenuItem item, final boolean is_selected ) {
897         if ( item != null ) {
898             item.setFont( MainFrame.menu_font );
899             if ( !getConfiguration().isUseNativeUI() ) {
900                 item.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
901                 item.setForeground( getConfiguration().getGuiMenuTextColor() );
902             }
903             item.setSelected( is_selected );
904             item.addActionListener( this );
905         }
906     }
907
908     private Phylogeny getSpeciesTree() {
909         return _species_tree;
910     }
911
912     private boolean isScreenAntialias() {
913         return true;
914     }
915
916     private void removeBranchColors() {
917         if ( getMainPanel().getCurrentPhylogeny() != null ) {
918             AptxUtil.removeBranchColors( getMainPanel().getCurrentPhylogeny() );
919         }
920     }
921
922     private void removeVisualStyles() {
923         if ( getMainPanel().getCurrentPhylogeny() != null ) {
924             AptxUtil.removeVisualStyles( getMainPanel().getCurrentPhylogeny() );
925         }
926     }
927
928     private void setMainPanel( final MainPanelApplets main_panel ) {
929         _mainpanel = main_panel;
930     }
931
932     private void setSpeciesTree( final Phylogeny species_tree ) {
933         _species_tree = species_tree;
934     }
935
936     private void setupUI() {
937         try {
938             if ( getConfiguration().isUseNativeUI() ) {
939                 UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
940             }
941             else {
942                 UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() );
943             }
944         }
945         catch ( final UnsupportedLookAndFeelException e ) {
946             AptxUtil.dieWithSystemError( "UnsupportedLookAndFeelException: " + e.toString() );
947         }
948         catch ( final ClassNotFoundException e ) {
949             AptxUtil.dieWithSystemError( "ClassNotFoundException: " + e.toString() );
950         }
951         catch ( final InstantiationException e ) {
952             AptxUtil.dieWithSystemError( "InstantiationException: " + e.toString() );
953         }
954         catch ( final IllegalAccessException e ) {
955             AptxUtil.dieWithSystemError( "IllegalAccessException: " + e.toString() );
956         }
957         catch ( final Exception e ) {
958             AptxUtil.dieWithSystemError( e.toString() );
959         }
960     }
961
962     void buildAnalysisMenu() {
963         _analysis_menu = MainFrame.createMenu( "Analysis", getConfiguration() );
964         _analysis_menu.add( _gsdi_item = new JMenuItem( "GSDI (Generalized Speciation Duplication Inference)" ) );
965         _analysis_menu.add( _gsdir_item = new JMenuItem( "GSDIR (GSDI with re-rooting)" ) );
966         customizeJMenuItem( _gsdi_item );
967         customizeJMenuItem( _gsdir_item );
968         _analysis_menu.addSeparator();
969         _jmenubar.add( _analysis_menu );
970     }
971
972     void buildFileMenu() {
973         _file_jmenu = MainFrame.createMenu( "File", getConfiguration() );
974         _file_jmenu.add( _save_item = new JMenuItem( "Save Tree As..." ) );
975         _file_jmenu.addSeparator();
976         _file_jmenu.add( _write_to_pdf_item = new JMenuItem( "Export to PDF file ..." ) );
977         if ( AptxUtil.canWriteFormat( "tif" ) || AptxUtil.canWriteFormat( "tiff" ) || AptxUtil.canWriteFormat( "TIF" ) ) {
978             _file_jmenu.add( _write_to_tif_item = new JMenuItem( "Export to TIFF file..." ) );
979         }
980         _file_jmenu.add( _write_to_png_item = new JMenuItem( "Export to PNG file..." ) );
981         _file_jmenu.add( _write_to_jpg_item = new JMenuItem( "Export to JPG file..." ) );
982         if ( AptxUtil.canWriteFormat( "gif" ) ) {
983             _file_jmenu.add( _write_to_gif_item = new JMenuItem( "Export to GIF file..." ) );
984         }
985         if ( AptxUtil.canWriteFormat( "bmp" ) ) {
986             _file_jmenu.add( _write_to_bmp_item = new JMenuItem( "Export to BMP file..." ) );
987         }
988         _file_jmenu.addSeparator();
989         _file_jmenu.add( _print_item = new JMenuItem( "Print..." ) );
990         customizeJMenuItem( _save_item );
991         customizeJMenuItem( _write_to_pdf_item );
992         customizeJMenuItem( _write_to_png_item );
993         customizeJMenuItem( _write_to_jpg_item );
994         customizeJMenuItem( _write_to_gif_item );
995         customizeJMenuItem( _write_to_tif_item );
996         customizeJMenuItem( _write_to_bmp_item );
997         customizeJMenuItem( _print_item );
998         _jmenubar.add( _file_jmenu );
999     }
1000
1001     void buildFontSizeMenu() {
1002         _font_size_menu = MainFrame.createMenu( MainFrame.FONT_SIZE_MENU_LABEL, getConfiguration() );
1003         _font_size_menu.add( _super_tiny_fonts_mi = new JMenuItem( "Super tiny fonts" ) );
1004         _font_size_menu.add( _tiny_fonts_mi = new JMenuItem( "Tiny fonts" ) );
1005         _font_size_menu.add( _small_fonts_mi = new JMenuItem( "Small fonts" ) );
1006         _font_size_menu.add( _medium_fonts_mi = new JMenuItem( "Medium fonts" ) );
1007         _font_size_menu.add( _large_fonts_mi = new JMenuItem( "Large fonts" ) );
1008         customizeJMenuItem( _super_tiny_fonts_mi );
1009         customizeJMenuItem( _tiny_fonts_mi );
1010         customizeJMenuItem( _small_fonts_mi );
1011         customizeJMenuItem( _medium_fonts_mi );
1012         customizeJMenuItem( _large_fonts_mi );
1013         _jmenubar.add( _font_size_menu );
1014     }
1015
1016     void buildHelpMenu() {
1017         _help_jmenu = MainFrame.createMenu( "Help", getConfiguration() );
1018         _help_jmenu.add( _help_item = new JMenuItem( "Documentation" ) );
1019         _help_jmenu.addSeparator();
1020         _help_jmenu.add( _website_item = new JMenuItem( "Archaeopteryx Home" ) );
1021         _aptx_ref_item = new JMenuItem( "Archaeopteryx Reference" );
1022         _help_jmenu.add( _phyloxml_website_item = new JMenuItem( "phyloXML Home" ) );
1023         _help_jmenu.add( _phyloxml_ref_item = new JMenuItem( "phyloXML Reference" ) );
1024         _help_jmenu.addSeparator();
1025         _help_jmenu.add( _about_item = new JMenuItem( "About" ) );
1026         customizeJMenuItem( _help_item );
1027         customizeJMenuItem( _website_item );
1028         customizeJMenuItem( _phyloxml_website_item );
1029         customizeJMenuItem( _aptx_ref_item );
1030         customizeJMenuItem( _phyloxml_ref_item );
1031         customizeJMenuItem( _about_item );
1032         _phyloxml_ref_item.setToolTipText( MainFrame.PHYLOXML_REF_TOOL_TIP );
1033         _aptx_ref_item.setToolTipText( MainFrame.APTX_REF_TOOL_TIP );
1034         _jmenubar.add( _help_jmenu );
1035     }
1036
1037     void buildOptionsMenu() {
1038         _options_jmenu = MainFrame.createMenu( MainFrame.OPTIONS_HEADER, getConfiguration() );
1039         _options_jmenu.addChangeListener( new ChangeListener() {
1040
1041             @Override
1042             public void stateChanged( final ChangeEvent e ) {
1043                 MainFrame.setOvPlacementColorChooseMenuItem( _overview_placment_mi, getOptions() );
1044                 MainFrame.setTextColorChooseMenuItem( _switch_colors_mi, getCurrentTreePanel() );
1045                 MainFrame
1046                         .setTextMinSupportMenuItem( _choose_minimal_confidence_mi, getOptions(), getCurrentTreePanel() );
1047                 MainFrame.setTextForFontChooserMenuItem( _choose_font_mi, MainFrame
1048                         .createCurrentFontDesc( getMainPanel().getTreeFontSet() ) );
1049                 setTextForPdfLineWidthChooserMenuItem( _choose_pdf_width_mi, getOptions() );
1050                 MainFrame.setCycleNodeFillMenuItem( _cycle_node_fill_mi, getOptions() );
1051                 MainFrame.setCycleNodeShapeMenuItem( _cycle_node_shape_mi, getOptions() );
1052                 MainFrame.setTextNodeSizeMenuItem( _choose_node_size_mi, getOptions() );
1053                 try {
1054                     getMainPanel().getControlPanel().setVisibilityOfDomainStrucureCB();
1055                     getMainPanel().getControlPanel().setVisibilityOfX();
1056                 }
1057                 catch ( final Exception ignore ) {
1058                     // do nothing, not important.
1059                 }
1060             }
1061         } );
1062         _options_jmenu.add( MainFrame.customizeMenuItemAsLabel( new JMenuItem( MainFrame.DISPLAY_SUBHEADER ),
1063                                                                 getConfiguration() ) );
1064         _options_jmenu
1065                 .add( _ext_node_dependent_cladogram_rbmi = new JRadioButtonMenuItem( MainFrame.NONUNIFORM_CLADOGRAMS_LABEL ) );
1066         _options_jmenu.add( _uniform_cladograms_rbmi = new JRadioButtonMenuItem( MainFrame.UNIFORM_CLADOGRAMS_LABEL ) );
1067         _options_jmenu
1068                 .add( _non_lined_up_cladograms_rbmi = new JRadioButtonMenuItem( MainFrame.NON_LINED_UP_CLADOGRAMS_LABEL ) );
1069         _radio_group_1 = new ButtonGroup();
1070         _radio_group_1.add( _ext_node_dependent_cladogram_rbmi );
1071         _radio_group_1.add( _uniform_cladograms_rbmi );
1072         _radio_group_1.add( _non_lined_up_cladograms_rbmi );
1073         _options_jmenu.add( _show_overview_cbmi = new JCheckBoxMenuItem( MainFrame.SHOW_OVERVIEW_LABEL ) );
1074         _options_jmenu.add( _show_scale_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_SCALE_LABEL ) );
1075         _options_jmenu
1076                 .add( _show_default_node_shapes_internal_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_INT ) );
1077         _options_jmenu
1078                 .add( _show_default_node_shapes_external_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_EXT ) );
1079         _options_jmenu
1080                 .add( _show_default_node_shapes_for_marked_cbmi = new JCheckBoxMenuItem( MainFrame.DISPLAY_NODE_BOXES_LABEL_MARKED ) );
1081         _options_jmenu.add( _line_up_renderable_data_cbmi = new JCheckBoxMenuItem( MainFrame.LINE_UP_RENDERABLE_DATA ) );
1082         if ( getConfiguration().doDisplayOption( Configuration.show_domain_architectures ) ) {
1083             _options_jmenu.add( _right_line_up_domains_cbmi = new JCheckBoxMenuItem( MainFrame.RIGHT_LINE_UP_DOMAINS ) );
1084             _options_jmenu.add( _show_domain_labels = new JCheckBoxMenuItem( MainFrame.SHOW_DOMAIN_LABELS_LABEL ) );
1085         }
1086         _options_jmenu.add( _show_annotation_ref_source = new JCheckBoxMenuItem( MainFrame.SHOW_ANN_REF_SOURCE_LABEL ) );
1087         _options_jmenu.add( _show_confidence_stddev_cbmi = new JCheckBoxMenuItem( MainFrame.SHOW_CONF_STDDEV_LABEL ) );
1088         _options_jmenu
1089                 .add( _color_by_taxonomic_group_cbmi = new JCheckBoxMenuItem( MainFrame.COLOR_BY_TAXONOMIC_GROUP ) );
1090         _options_jmenu
1091                 .add( _color_labels_same_as_parent_branch = new JCheckBoxMenuItem( MainFrame.COLOR_LABELS_LABEL ) );
1092         _color_labels_same_as_parent_branch.setToolTipText( MainFrame.COLOR_LABELS_TIP );
1093         _options_jmenu.add( _abbreviate_scientific_names = new JCheckBoxMenuItem( MainFrame.ABBREV_SN_LABEL ) );
1094         _options_jmenu.add( _label_direction_cbmi = new JCheckBoxMenuItem( MainFrame.LABEL_DIRECTION_LABEL ) );
1095         _label_direction_cbmi.setToolTipText( MainFrame.LABEL_DIRECTION_TIP );
1096         _options_jmenu.add( _screen_antialias_cbmi = new JCheckBoxMenuItem( MainFrame.SCREEN_ANTIALIAS_LABEL ) );
1097         _options_jmenu.add( _background_gradient_cbmi = new JCheckBoxMenuItem( MainFrame.BG_GRAD_LABEL ) );
1098         _options_jmenu.add( _cycle_node_shape_mi = new JMenuItem( MainFrame.CYCLE_NODE_SHAPE_LABEL ) );
1099         _options_jmenu.add( _cycle_node_fill_mi = new JMenuItem( MainFrame.CYCLE_NODE_FILL_LABEL ) );
1100         _options_jmenu.add( _choose_node_size_mi = new JMenuItem( MainFrame.CHOOSE_NODE_SIZE_LABEL ) );
1101         _options_jmenu.add( _choose_minimal_confidence_mi = new JMenuItem( "" ) );
1102         _options_jmenu.add( _overview_placment_mi = new JMenuItem( "" ) );
1103         _options_jmenu.add( _switch_colors_mi = new JMenuItem( "" ) );
1104         _options_jmenu.add( _choose_font_mi = new JMenuItem( "" ) );
1105         _options_jmenu.addSeparator();
1106         _options_jmenu.add( MainFrame.customizeMenuItemAsLabel( new JMenuItem( MainFrame.SEARCH_SUBHEADER ),
1107                                                                 getConfiguration() ) );
1108         _options_jmenu
1109                 .add( _search_case_senstive_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_CASE_SENSITIVE_LABEL ) );
1110         _options_jmenu.add( _search_whole_words_only_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_TERMS_ONLY_LABEL ) );
1111         _options_jmenu.add( _search_with_regex_cbmi = new JCheckBoxMenuItem( MainFrame.SEARCH_REGEX_LABEL ) );
1112         _search_with_regex_cbmi.setToolTipText( MainFrame.SEARCH_WITH_REGEX_TIP );
1113         _options_jmenu
1114                 .add( _inverse_search_result_cbmi = new JCheckBoxMenuItem( MainFrame.INVERSE_SEARCH_RESULT_LABEL ) );
1115         //
1116         _options_jmenu.addSeparator();
1117         _options_jmenu.add( MainFrame.customizeMenuItemAsLabel( new JMenuItem( "Graphics Export & Printing:" ),
1118                                                                 getConfiguration() ) );
1119         _options_jmenu.add( _antialias_print_cbmi = new JCheckBoxMenuItem( "Antialias" ) );
1120         _options_jmenu.add( _print_black_and_white_cbmi = new JCheckBoxMenuItem( "Export in Black and White" ) );
1121         _options_jmenu
1122                 .add( _graphics_export_visible_only_cbmi = new JCheckBoxMenuItem( "Limit to Visible ('Screenshot') for PNG, JPG, and GIF export" ) );
1123         _options_jmenu.add( _choose_pdf_width_mi = new JMenuItem( "" ) );
1124         //
1125         customizeCheckBoxMenuItem( _antialias_print_cbmi, getOptions().isAntialiasPrint() );
1126         customizeCheckBoxMenuItem( _print_black_and_white_cbmi, getOptions().isPrintBlackAndWhite() );
1127         customizeCheckBoxMenuItem( _graphics_export_visible_only_cbmi, getOptions().isGraphicsExportVisibleOnly() );
1128         customizeJMenuItem( _choose_pdf_width_mi );
1129         //
1130         customizeJMenuItem( _choose_font_mi );
1131         customizeJMenuItem( _choose_minimal_confidence_mi );
1132         customizeJMenuItem( _switch_colors_mi );
1133         customizeJMenuItem( _overview_placment_mi );
1134         customizeCheckBoxMenuItem( _color_by_taxonomic_group_cbmi, getOptions().isColorByTaxonomicGroup() );
1135         customizeCheckBoxMenuItem( _label_direction_cbmi,
1136                                    getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL );
1137         customizeCheckBoxMenuItem( _screen_antialias_cbmi, getOptions().isAntialiasScreen() );
1138         customizeCheckBoxMenuItem( _background_gradient_cbmi, getOptions().isBackgroundColorGradient() );
1139         customizeCheckBoxMenuItem( _show_domain_labels, getOptions().isShowDomainLabels() );
1140         customizeCheckBoxMenuItem( _show_annotation_ref_source, getOptions().isShowAnnotationRefSource() );
1141         customizeCheckBoxMenuItem( _abbreviate_scientific_names, getOptions().isAbbreviateScientificTaxonNames() );
1142         customizeCheckBoxMenuItem( _show_default_node_shapes_external_cbmi, getOptions()
1143                 .isShowDefaultNodeShapesExternal() );
1144         customizeCheckBoxMenuItem( _show_default_node_shapes_internal_cbmi, getOptions()
1145                 .isShowDefaultNodeShapesInternal() );
1146         customizeCheckBoxMenuItem( _show_default_node_shapes_for_marked_cbmi, getOptions()
1147                 .isShowDefaultNodeShapesForMarkedNodes() );
1148         customizeJMenuItem( _cycle_node_shape_mi );
1149         customizeJMenuItem( _cycle_node_fill_mi );
1150         customizeJMenuItem( _choose_node_size_mi );
1151         customizeCheckBoxMenuItem( _color_labels_same_as_parent_branch, getOptions().isColorLabelsSameAsParentBranch() );
1152         customizeCheckBoxMenuItem( _search_case_senstive_cbmi, getOptions().isSearchCaseSensitive() );
1153         customizeCheckBoxMenuItem( _show_scale_cbmi, getOptions().isShowScale() );
1154         customizeRadioButtonMenuItem( _non_lined_up_cladograms_rbmi,
1155                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP );
1156         customizeRadioButtonMenuItem( _uniform_cladograms_rbmi,
1157                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP );
1158         customizeRadioButtonMenuItem( _ext_node_dependent_cladogram_rbmi,
1159                                       getOptions().getCladogramType() == CLADOGRAM_TYPE.EXT_NODE_SUM_DEP );
1160         customizeCheckBoxMenuItem( _show_overview_cbmi, getOptions().isShowOverview() );
1161         customizeCheckBoxMenuItem( _search_with_regex_cbmi, getOptions().isSearchWithRegex() );
1162         customizeCheckBoxMenuItem( _search_whole_words_only_cbmi, getOptions().isMatchWholeTermsOnly() );
1163         customizeCheckBoxMenuItem( _inverse_search_result_cbmi, getOptions().isInverseSearchResult() );
1164         customizeCheckBoxMenuItem( _show_confidence_stddev_cbmi, getOptions().isShowConfidenceStddev() );
1165         customizeCheckBoxMenuItem( _line_up_renderable_data_cbmi, getOptions().isLineUpRendarableNodeData() );
1166         customizeCheckBoxMenuItem( _right_line_up_domains_cbmi, getOptions().isRightLineUpDomains() );
1167         _jmenubar.add( _options_jmenu );
1168     }
1169
1170     void buildToolsMenu() {
1171         _tools_menu = MainFrame.createMenu( "Tools", getConfiguration() );
1172         _tools_menu.add( _confcolor_item = new JMenuItem( "Colorize Branches Depending on Confidence" ) );
1173         customizeJMenuItem( _confcolor_item );
1174         _tools_menu.add( _taxcolor_item = new JMenuItem( "Taxonomy Colorize Branches" ) );
1175         customizeJMenuItem( _taxcolor_item );
1176         _tools_menu.addSeparator();
1177         _tools_menu.add( _remove_visual_styles_item = new JMenuItem( "Delete All Visual Styles From Nodes" ) );
1178         _remove_visual_styles_item
1179                 .setToolTipText( "To remove all node visual styles (fonts, colors) from the current phylogeny." );
1180         customizeJMenuItem( _remove_visual_styles_item );
1181         _tools_menu.add( _remove_branch_color_item = new JMenuItem( "Delete All Colors From Branches" ) );
1182         _remove_branch_color_item.setToolTipText( "To remove all branch color values from the current phylogeny." );
1183         customizeJMenuItem( _remove_branch_color_item );
1184         _tools_menu.addSeparator();
1185         _tools_menu.add( _midpoint_root_item = new JMenuItem( "Midpoint-Root" ) );
1186         customizeJMenuItem( _midpoint_root_item );
1187         _tools_menu.addSeparator();
1188         _tools_menu.add( _collapse_species_specific_subtrees = new JMenuItem( "Collapse Species-Specific Subtrees" ) );
1189         customizeJMenuItem( _collapse_species_specific_subtrees );
1190         _jmenubar.add( _tools_menu );
1191     }
1192
1193     void buildTypeMenu() {
1194         _type_menu = MainFrame.createMenu( MainFrame.TYPE_MENU_HEADER, getConfiguration() );
1195         _type_menu.add( _rectangular_type_cbmi = new JCheckBoxMenuItem( MainFrame.RECTANGULAR_TYPE_CBMI_LABEL ) );
1196         _type_menu.add( _euro_type_cbmi = new JCheckBoxMenuItem( MainFrame.EURO_TYPE_CBMI_LABEL ) );
1197         _type_menu.add( _rounded_type_cbmi = new JCheckBoxMenuItem( MainFrame.ROUNDED_TYPE_CBMI_LABEL ) );
1198         _type_menu.add( _curved_type_cbmi = new JCheckBoxMenuItem( MainFrame.CURVED_TYPE_CBMI_LABEL ) );
1199         _type_menu.add( _triangular_type_cbmi = new JCheckBoxMenuItem( MainFrame.TRIANGULAR_TYPE_CBMI_LABEL ) );
1200         _type_menu.add( _convex_type_cbmi = new JCheckBoxMenuItem( MainFrame.CONVEX_TYPE_CBMI_LABEL ) );
1201         _type_menu.add( _unrooted_type_cbmi = new JCheckBoxMenuItem( MainFrame.UNROOTED_TYPE_CBMI_LABEL ) );
1202         _type_menu.add( _circular_type_cbmi = new JCheckBoxMenuItem( MainFrame.CIRCULAR_TYPE_CBMI_LABEL ) );
1203         customizeCheckBoxMenuItem( _rectangular_type_cbmi, false );
1204         customizeCheckBoxMenuItem( _triangular_type_cbmi, false );
1205         customizeCheckBoxMenuItem( _euro_type_cbmi, false );
1206         customizeCheckBoxMenuItem( _rounded_type_cbmi, false );
1207         customizeCheckBoxMenuItem( _curved_type_cbmi, false );
1208         customizeCheckBoxMenuItem( _convex_type_cbmi, false );
1209         customizeCheckBoxMenuItem( _unrooted_type_cbmi, false );
1210         customizeCheckBoxMenuItem( _circular_type_cbmi, false );
1211         _unrooted_type_cbmi.setToolTipText( MainFrame.USE_MOUSEWHEEL_SHIFT_TO_ROTATE );
1212         _circular_type_cbmi.setToolTipText( MainFrame.USE_MOUSEWHEEL_SHIFT_TO_ROTATE );
1213         initializeTypeMenu( getOptions() );
1214         _jmenubar.add( _type_menu );
1215     }
1216
1217     void buildViewMenu() {
1218         _view_jmenu = MainFrame.createMenu( "View", getConfiguration() );
1219         _view_jmenu
1220                 .add( _display_basic_information_item = new JMenuItem( MainFrame.SHOW_BASIC_TREE_INFORMATION_LABEL ) );
1221         _view_jmenu.addSeparator();
1222         _view_jmenu.add( _view_as_XML_item = new JMenuItem( "as phyloXML" ) );
1223         _view_jmenu.add( _view_as_NH_item = new JMenuItem( "as Newick" ) );
1224         _view_jmenu.add( _view_as_nexus_item = new JMenuItem( "as Nexus" ) );
1225         customizeJMenuItem( _display_basic_information_item );
1226         customizeJMenuItem( _view_as_NH_item );
1227         customizeJMenuItem( _view_as_XML_item );
1228         customizeJMenuItem( _view_as_nexus_item );
1229         _jmenubar.add( _view_jmenu );
1230     }
1231
1232     void checkTextFrames() {
1233         if ( _textframes.size() > 5 ) {
1234             try {
1235                 if ( _textframes.getFirst() != null ) {
1236                     _textframes.getFirst().removeMe();
1237                 }
1238                 else {
1239                     _textframes.removeFirst();
1240                 }
1241             }
1242             catch ( final NoSuchElementException e ) {
1243                 // Ignore.
1244             }
1245         }
1246     }
1247
1248     void clearCurrentExternalNodesDataBuffer() {
1249         getCurrentTreePanel().clearCurrentExternalNodesDataBuffer();
1250     }
1251
1252     void customizeCheckBoxMenuItem( final JCheckBoxMenuItem item, final boolean is_selected ) {
1253         if ( item != null ) {
1254             item.setFont( MainFrame.menu_font );
1255             if ( !getConfiguration().isUseNativeUI() ) {
1256                 item.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
1257                 item.setForeground( getConfiguration().getGuiMenuTextColor() );
1258             }
1259             item.setSelected( is_selected );
1260             item.addActionListener( this );
1261         }
1262     }
1263
1264     void customizeJMenuItem( final JMenuItem jmi ) {
1265         if ( jmi != null ) {
1266             jmi.setFont( MainFrame.menu_font );
1267             if ( !getConfiguration().isUseNativeUI() ) {
1268                 jmi.setBackground( getConfiguration().getGuiMenuBackgroundColor() );
1269                 jmi.setForeground( getConfiguration().getGuiMenuTextColor() );
1270             }
1271             jmi.addActionListener( this );
1272         }
1273     }
1274
1275     void displayBasicInformation() {
1276         if ( ( getMainPanel() != null ) && ( getMainPanel().getCurrentPhylogeny() != null )
1277                 && !getMainPanel().getCurrentPhylogeny().isEmpty() ) {
1278             String title = "Basic Information";
1279             if ( !ForesterUtil.isEmpty( getMainPanel().getCurrentPhylogeny().getName() ) ) {
1280                 title = title + " for \"" + _mainpanel.getCurrentPhylogeny().getName() + "\"";
1281             }
1282             showTextFrame( AptxUtil.createBasicInformation( getMainPanel().getCurrentPhylogeny(), null ), title );
1283         }
1284     }
1285
1286     void executeGSDI() {
1287         if ( !isOKforSDI( false, true ) ) {
1288             return;
1289         }
1290         if ( !_mainpanel.getCurrentPhylogeny().isRooted() ) {
1291             JOptionPane.showMessageDialog( this,
1292                                            "Gene tree is not rooted.",
1293                                            "Cannot execute GSDI",
1294                                            JOptionPane.ERROR_MESSAGE );
1295             return;
1296         }
1297         final Phylogeny gene_tree = _mainpanel.getCurrentPhylogeny().copy();
1298         gene_tree.setAllNodesToNotCollapse();
1299         gene_tree.recalculateNumberOfExternalDescendants( false );
1300         GSDI gsdi = null;
1301         final Phylogeny species_tree = _species_tree.copy();
1302         try {
1303             gsdi = new GSDI( gene_tree, species_tree, false, true, true, true );
1304         }
1305         catch ( final SDIException e ) {
1306             JOptionPane.showMessageDialog( this,
1307                                            e.getLocalizedMessage(),
1308                                            "Error during GSDI",
1309                                            JOptionPane.ERROR_MESSAGE );
1310             return;
1311         }
1312         catch ( final Exception e ) {
1313             AptxUtil.unexpectedException( e );
1314             return;
1315         }
1316         gene_tree.setRerootable( false );
1317         gene_tree.clearHashIdToNodeMap();
1318         gene_tree.recalculateNumberOfExternalDescendants( true );
1319         _mainpanel.addPhylogenyInNewTab( gene_tree, getConfiguration(), "gene tree", null );
1320         getMainPanel().getControlPanel().setShowEvents( true );
1321         showWhole();
1322         final int selected = _mainpanel.getTabbedPane().getSelectedIndex();
1323         _mainpanel.addPhylogenyInNewTab( species_tree, getConfiguration(), "species tree", null );
1324         showWhole();
1325         _mainpanel.getTabbedPane().setSelectedIndex( selected );
1326         showWhole();
1327         _mainpanel.getCurrentTreePanel().setEdited( true );
1328         final int poly = PhylogenyMethods.countNumberOfPolytomies( species_tree );
1329         if ( gsdi.getStrippedExternalGeneTreeNodes().size() > 0 ) {
1330             JOptionPane.showMessageDialog( this,
1331                                            "Duplications: " + gsdi.getDuplicationsSum() + "\n"
1332                                                    + "Potential duplications: "
1333                                                    + gsdi.getSpeciationOrDuplicationEventsSum() + "\n"
1334                                                    + "Speciations: " + gsdi.getSpeciationsSum() + "\n"
1335                                                    + "Stripped gene tree nodes: "
1336                                                    + gsdi.getStrippedExternalGeneTreeNodes().size() + "\n"
1337                                                    + "Taxonomy linkage based on: " + gsdi.getTaxCompBase() + "\n"
1338                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1339                                            "GSDI successfully completed",
1340                                            JOptionPane.WARNING_MESSAGE );
1341         }
1342         else {
1343             JOptionPane.showMessageDialog( this,
1344                                            "Duplications: " + gsdi.getDuplicationsSum() + "\n"
1345                                                    + "Potential duplications: "
1346                                                    + gsdi.getSpeciationOrDuplicationEventsSum() + "\n"
1347                                                    + "Speciations: " + gsdi.getSpeciationsSum() + "\n"
1348                                                    + "Stripped gene tree nodes: "
1349                                                    + gsdi.getStrippedExternalGeneTreeNodes().size() + "\n"
1350                                                    + "Taxonomy linkage based on: " + gsdi.getTaxCompBase() + "\n"
1351                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1352                                            "GSDI successfully completed",
1353                                            JOptionPane.INFORMATION_MESSAGE );
1354         }
1355     }
1356
1357     void executeGSDIR() {
1358         if ( !isOKforSDI( false, false ) ) {
1359             return;
1360         }
1361         final int p = PhylogenyMethods.countNumberOfPolytomies( _mainpanel.getCurrentPhylogeny() );
1362         if ( ( p > 0 )
1363                 && !( ( p == 1 ) && ( _mainpanel.getCurrentPhylogeny().getRoot().getNumberOfDescendants() == 3 ) ) ) {
1364             JOptionPane.showMessageDialog( this,
1365                                            "Gene tree is not completely binary",
1366                                            "Cannot execute GSDI",
1367                                            JOptionPane.ERROR_MESSAGE );
1368             return;
1369         }
1370         final Phylogeny gene_tree = _mainpanel.getCurrentPhylogeny().copy();
1371         gene_tree.setAllNodesToNotCollapse();
1372         gene_tree.recalculateNumberOfExternalDescendants( false );
1373         GSDIR gsdir = null;
1374         final Phylogeny species_tree = _species_tree.copy();
1375         try {
1376             gsdir = new GSDIR( gene_tree, species_tree, true, true, true );
1377         }
1378         catch ( final SDIException e ) {
1379             JOptionPane.showMessageDialog( this,
1380                                            e.getLocalizedMessage(),
1381                                            "Error during GSDIR",
1382                                            JOptionPane.ERROR_MESSAGE );
1383             return;
1384         }
1385         catch ( final Exception e ) {
1386             AptxUtil.unexpectedException( e );
1387             return;
1388         }
1389         final Phylogeny result_gene_tree = gsdir.getMinDuplicationsSumGeneTree();
1390         result_gene_tree.setRerootable( false );
1391         result_gene_tree.clearHashIdToNodeMap();
1392         result_gene_tree.recalculateNumberOfExternalDescendants( true );
1393         PhylogenyMethods.orderAppearance( result_gene_tree.getRoot(), true, true, DESCENDANT_SORT_PRIORITY.NODE_NAME );
1394         _mainpanel.addPhylogenyInNewTab( result_gene_tree, getConfiguration(), "gene tree", null );
1395         getMainPanel().getControlPanel().setShowEvents( true );
1396         showWhole();
1397         final int selected = _mainpanel.getTabbedPane().getSelectedIndex();
1398         _mainpanel.addPhylogenyInNewTab( species_tree, getConfiguration(), "species tree", null );
1399         showWhole();
1400         _mainpanel.getTabbedPane().setSelectedIndex( selected );
1401         showWhole();
1402         _mainpanel.getCurrentTreePanel().setEdited( true );
1403         final int poly = PhylogenyMethods.countNumberOfPolytomies( species_tree );
1404         if ( gsdir.getStrippedExternalGeneTreeNodes().size() > 0 ) {
1405             JOptionPane.showMessageDialog( this,
1406                                            "Minimal duplications: " + gsdir.getMinDuplicationsSum() + "\n"
1407                                                    + "Speciations: " + gsdir.getSpeciationsSum() + "\n"
1408                                                    + "Stripped gene tree nodes: "
1409                                                    + gsdir.getStrippedExternalGeneTreeNodes().size() + "\n"
1410                                                    + "Taxonomy linkage based on: " + gsdir.getTaxCompBase() + "\n"
1411                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1412                                            "GSDIR successfully completed",
1413                                            JOptionPane.WARNING_MESSAGE );
1414         }
1415         else {
1416             JOptionPane.showMessageDialog( this,
1417                                            "Minimal duplications: " + gsdir.getMinDuplicationsSum() + "\n"
1418                                                    + "Speciations: " + gsdir.getSpeciationsSum() + "\n"
1419                                                    + "Stripped gene tree nodes: "
1420                                                    + gsdir.getStrippedExternalGeneTreeNodes().size() + "\n"
1421                                                    + "Taxonomy linkage based on: " + gsdir.getTaxCompBase() + "\n"
1422                                                    + "Number of polytomies in species tree used: " + poly + "\n",
1423                                            "GSDIR successfully completed",
1424                                            JOptionPane.INFORMATION_MESSAGE );
1425         }
1426     }
1427
1428     Configuration getConfiguration() {
1429         return _configuration;
1430     }
1431
1432     File getCurrentDir() {
1433         if ( ( _current_dir == null ) || !_current_dir.canRead() ) {
1434             if ( ForesterUtil.isWindows() ) {
1435                 try {
1436                     _current_dir = new File( WindowsUtils.getCurrentUserDesktopPath() );
1437                 }
1438                 catch ( final Exception e ) {
1439                     _current_dir = null;
1440                 }
1441             }
1442         }
1443         if ( ( _current_dir == null ) || !_current_dir.canRead() ) {
1444             if ( System.getProperty( "user.home" ) != null ) {
1445                 _current_dir = new File( System.getProperty( "user.home" ) );
1446             }
1447             else if ( System.getProperty( "user.dir" ) != null ) {
1448                 _current_dir = new File( System.getProperty( "user.dir" ) );
1449             }
1450         }
1451         return _current_dir;
1452     }
1453
1454     TreePanel getCurrentTreePanel() {
1455         return getMainPanel().getCurrentTreePanel();
1456     }
1457
1458     JCheckBoxMenuItem getlabelDirectionCbmi() {
1459         return _label_direction_cbmi;
1460     }
1461
1462     MainPanel getMainPanel() {
1463         return _mainpanel;
1464     }
1465
1466     Options getOtions() {
1467         return _options;
1468     }
1469
1470     void initializeTypeMenu( final Options options ) {
1471         setTypeMenuToAllUnselected();
1472         try {
1473             switch ( options.getPhylogenyGraphicsType() ) {
1474                 case CONVEX:
1475                     _convex_type_cbmi.setSelected( true );
1476                     break;
1477                 case CURVED:
1478                     _curved_type_cbmi.setSelected( true );
1479                     break;
1480                 case EURO_STYLE:
1481                     _euro_type_cbmi.setSelected( true );
1482                     break;
1483                 case ROUNDED:
1484                     _rounded_type_cbmi.setSelected( true );
1485                     break;
1486                 case TRIANGULAR:
1487                     _triangular_type_cbmi.setSelected( true );
1488                     break;
1489                 case UNROOTED:
1490                     _unrooted_type_cbmi.setSelected( true );
1491                     break;
1492                 case CIRCULAR:
1493                     _circular_type_cbmi.setSelected( true );
1494                     break;
1495                 default:
1496                     _rectangular_type_cbmi.setSelected( true );
1497                     break;
1498             }
1499         }
1500         catch ( final NullPointerException np ) {
1501             // In all likelihood, this is caused by menu-less display.
1502         }
1503     }
1504
1505     boolean isOKforSDI( final boolean species_tree_has_to_binary, final boolean gene_tree_has_to_binary ) {
1506         if ( ( _mainpanel.getCurrentPhylogeny() == null ) || _mainpanel.getCurrentPhylogeny().isEmpty() ) {
1507             return false;
1508         }
1509         else if ( ( _species_tree == null ) || _species_tree.isEmpty() ) {
1510             JOptionPane.showMessageDialog( this,
1511                                            "No species tree loaded",
1512                                            "Cannot execute GSDI",
1513                                            JOptionPane.ERROR_MESSAGE );
1514             return false;
1515         }
1516         else if ( species_tree_has_to_binary && !_species_tree.isCompletelyBinary() ) {
1517             JOptionPane.showMessageDialog( this,
1518                                            "Species tree is not completely binary",
1519                                            "Cannot execute GSDI",
1520                                            JOptionPane.ERROR_MESSAGE );
1521             return false;
1522         }
1523         else if ( gene_tree_has_to_binary && !_mainpanel.getCurrentPhylogeny().isCompletelyBinary() ) {
1524             JOptionPane.showMessageDialog( this,
1525                                            "Gene tree is not completely binary",
1526                                            "Cannot execute GSDI",
1527                                            JOptionPane.ERROR_MESSAGE );
1528             return false;
1529         }
1530         else {
1531             return true;
1532         }
1533     }
1534
1535     boolean isSubtreeDisplayed() {
1536         if ( getCurrentTreePanel() != null ) {
1537             if ( getCurrentTreePanel().isCurrentTreeIsSubtree() ) {
1538                 JOptionPane
1539                         .showMessageDialog( this,
1540                                             "This operation can only be performed on a complete tree, not on the currently displayed sub-tree only.",
1541                                             "Operation can not be exectuted on a sub-tree",
1542                                             JOptionPane.WARNING_MESSAGE );
1543                 return true;
1544             }
1545         }
1546         return false;
1547     }
1548
1549     void removeAllTextFrames() {
1550         for( final TextFrame tf : _textframes ) {
1551             if ( tf != null ) {
1552                 tf.close();
1553             }
1554         }
1555         _textframes.clear();
1556     }
1557
1558     void setConfiguration( final Configuration configuration ) {
1559         _configuration = configuration;
1560     }
1561
1562     void setCurrentDir( final File current_dir ) {
1563         _current_dir = current_dir;
1564     }
1565
1566     void setOptions( final Options options ) {
1567         _options = options;
1568     }
1569
1570     void setSelectedTypeInTypeMenu( final PHYLOGENY_GRAPHICS_TYPE type ) {
1571         setTypeMenuToAllUnselected();
1572         try {
1573             switch ( type ) {
1574                 case CIRCULAR:
1575                     _circular_type_cbmi.setSelected( true );
1576                     break;
1577                 case CONVEX:
1578                     _convex_type_cbmi.setSelected( true );
1579                     break;
1580                 case CURVED:
1581                     _curved_type_cbmi.setSelected( true );
1582                     break;
1583                 case EURO_STYLE:
1584                     _euro_type_cbmi.setSelected( true );
1585                     break;
1586                 case ROUNDED:
1587                     _rounded_type_cbmi.setSelected( true );
1588                     break;
1589                 case RECTANGULAR:
1590                     _rectangular_type_cbmi.setSelected( true );
1591                     break;
1592                 case TRIANGULAR:
1593                     _triangular_type_cbmi.setSelected( true );
1594                     break;
1595                 case UNROOTED:
1596                     _unrooted_type_cbmi.setSelected( true );
1597                     break;
1598                 default:
1599                     throw new IllegalArgumentException( "unknown type: " + type );
1600             }
1601         }
1602         catch ( final NullPointerException np ) {
1603             // In all likelihood, this is caused by menu-less display.
1604         }
1605     }
1606
1607     void setTypeMenuToAllUnselected() {
1608         if ( _convex_type_cbmi != null ) {
1609             _convex_type_cbmi.setSelected( false );
1610         }
1611         if ( _curved_type_cbmi != null ) {
1612             _curved_type_cbmi.setSelected( false );
1613         }
1614         if ( _euro_type_cbmi != null ) {
1615             _euro_type_cbmi.setSelected( false );
1616         }
1617         if ( _rounded_type_cbmi != null ) {
1618             _rounded_type_cbmi.setSelected( false );
1619         }
1620         if ( _triangular_type_cbmi != null ) {
1621             _triangular_type_cbmi.setSelected( false );
1622         }
1623         if ( _rectangular_type_cbmi != null ) {
1624             _rectangular_type_cbmi.setSelected( false );
1625         }
1626         if ( _unrooted_type_cbmi != null ) {
1627             _unrooted_type_cbmi.setSelected( false );
1628         }
1629         if ( _circular_type_cbmi != null ) {
1630             _circular_type_cbmi.setSelected( false );
1631         }
1632     }
1633
1634     void showWhole() {
1635         _mainpanel.getControlPanel().showWhole();
1636     }
1637
1638     void switchColors() {
1639         final TreeColorSet colorset = getMainPanel().getCurrentTreePanel().getTreeColorSet();
1640         final ColorSchemeChooser csc = new ColorSchemeChooser( getMainPanel(), colorset );
1641         csc.setVisible( true );
1642         getMainPanel().setTreeColorSet( colorset );
1643     }
1644
1645     void typeChanged( final Object o ) {
1646         updateTypeCheckboxes( getOptions(), o );
1647         updateOptions( getOptions() );
1648         if ( getCurrentTreePanel() != null ) {
1649             final PHYLOGENY_GRAPHICS_TYPE previous_type = getCurrentTreePanel().getPhylogenyGraphicsType();
1650             final PHYLOGENY_GRAPHICS_TYPE new_type = getOptions().getPhylogenyGraphicsType();
1651             if ( ( ( previous_type == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( new_type != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) )
1652                     || ( ( previous_type == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) && ( new_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) )
1653                     || ( ( previous_type != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( new_type == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) )
1654                     || ( ( previous_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) && ( new_type == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) ) {
1655                 getCurrentTreePanel().getControlPanel().showWhole();
1656             }
1657             if ( getCurrentTreePanel().isPhyHasBranchLengths() && ( new_type != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
1658                 getCurrentTreePanel().getControlPanel().setDrawPhylogramEnabled( true );
1659             }
1660             else {
1661                 getCurrentTreePanel().getControlPanel().setDrawPhylogramEnabled( false );
1662             }
1663             getCurrentTreePanel().setPhylogenyGraphicsType( getOptions().getPhylogenyGraphicsType() );
1664             MainFrame.updateScreenTextAntialias( getMainPanel().getTreePanels() );
1665         }
1666     }
1667
1668     void updateOptions( final Options options ) {
1669         options.setAntialiasScreen( ( _screen_antialias_cbmi != null ) && _screen_antialias_cbmi.isSelected() );
1670         options.setBackgroundColorGradient( ( _background_gradient_cbmi != null )
1671                 && _background_gradient_cbmi.isSelected() );
1672         options.setShowDomainLabels( ( _show_domain_labels != null ) && _show_domain_labels.isSelected() );
1673         options.setShowAnnotationRefSource( ( _show_annotation_ref_source != null )
1674                 && _show_annotation_ref_source.isSelected() );
1675         options.setAbbreviateScientificTaxonNames( ( _abbreviate_scientific_names != null )
1676                 && _abbreviate_scientific_names.isSelected() );
1677         options.setColorLabelsSameAsParentBranch( ( _color_labels_same_as_parent_branch != null )
1678                 && _color_labels_same_as_parent_branch.isSelected() );
1679         options.setShowDefaultNodeShapesInternal( ( _show_default_node_shapes_internal_cbmi != null )
1680                 && _show_default_node_shapes_internal_cbmi.isSelected() );
1681         options.setShowDefaultNodeShapesExternal( ( _show_default_node_shapes_external_cbmi != null )
1682                 && _show_default_node_shapes_external_cbmi.isSelected() );
1683         options.setShowDefaultNodeShapesForMarkedNodes( ( _show_default_node_shapes_for_marked_cbmi != null )
1684                 && _show_default_node_shapes_for_marked_cbmi.isSelected() );
1685         if ( ( _non_lined_up_cladograms_rbmi != null ) && ( _non_lined_up_cladograms_rbmi.isSelected() ) ) {
1686             options.setCladogramType( CLADOGRAM_TYPE.NON_LINED_UP );
1687         }
1688         else if ( ( _uniform_cladograms_rbmi != null ) && ( _uniform_cladograms_rbmi.isSelected() ) ) {
1689             options.setCladogramType( CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP );
1690         }
1691         else if ( ( _ext_node_dependent_cladogram_rbmi != null ) && ( _ext_node_dependent_cladogram_rbmi.isSelected() ) ) {
1692             options.setCladogramType( CLADOGRAM_TYPE.EXT_NODE_SUM_DEP );
1693         }
1694         options.setSearchCaseSensitive( ( _search_case_senstive_cbmi != null )
1695                 && _search_case_senstive_cbmi.isSelected() );
1696         if ( ( _show_scale_cbmi != null ) && _show_scale_cbmi.isEnabled() ) {
1697             options.setShowScale( _show_scale_cbmi.isSelected() );
1698         }
1699         if ( _label_direction_cbmi != null ) {
1700             if ( _label_direction_cbmi.isSelected() ) {
1701                 options.setNodeLabelDirection( NODE_LABEL_DIRECTION.RADIAL );
1702             }
1703             else {
1704                 options.setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL );
1705             }
1706         }
1707         options.setShowOverview( ( _show_overview_cbmi != null ) && _show_overview_cbmi.isSelected() );
1708         options.setShowConfidenceStddev( ( _show_confidence_stddev_cbmi != null )
1709                 && _show_confidence_stddev_cbmi.isSelected() );
1710         options.setMatchWholeTermsOnly( ( _search_whole_words_only_cbmi != null )
1711                 && _search_whole_words_only_cbmi.isSelected() );
1712         options.setSearchWithRegex( ( _search_with_regex_cbmi != null ) && _search_with_regex_cbmi.isSelected() );
1713         options.setInverseSearchResult( ( _inverse_search_result_cbmi != null )
1714                 && _inverse_search_result_cbmi.isSelected() );
1715         options.setAntialiasPrint( ( _antialias_print_cbmi != null ) && _antialias_print_cbmi.isSelected() );
1716         options.setPrintBlackAndWhite( ( _print_black_and_white_cbmi != null )
1717                                        && _print_black_and_white_cbmi.isSelected() );
1718         if ( ( _rectangular_type_cbmi != null ) && _rectangular_type_cbmi.isSelected() ) {
1719             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR );
1720         }
1721         else if ( ( _triangular_type_cbmi != null ) && _triangular_type_cbmi.isSelected() ) {
1722             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.TRIANGULAR );
1723         }
1724         else if ( ( _curved_type_cbmi != null ) && _curved_type_cbmi.isSelected() ) {
1725             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CURVED );
1726         }
1727         else if ( ( _convex_type_cbmi != null ) && _convex_type_cbmi.isSelected() ) {
1728             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CONVEX );
1729         }
1730         else if ( ( _euro_type_cbmi != null ) && _euro_type_cbmi.isSelected() ) {
1731             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE );
1732         }
1733         else if ( ( _rounded_type_cbmi != null ) && _rounded_type_cbmi.isSelected() ) {
1734             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.ROUNDED );
1735         }
1736         else if ( ( _unrooted_type_cbmi != null ) && _unrooted_type_cbmi.isSelected() ) {
1737             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
1738         }
1739         else if ( ( _circular_type_cbmi != null ) && _circular_type_cbmi.isSelected() ) {
1740             options.setPhylogenyGraphicsType( PHYLOGENY_GRAPHICS_TYPE.CIRCULAR );
1741         }
1742         if ( ( _color_by_taxonomic_group_cbmi != null ) && _color_by_taxonomic_group_cbmi.isEnabled() ) {
1743             options.setColorByTaxonomicGroup( _color_by_taxonomic_group_cbmi.isSelected() );
1744         }
1745         if ( ( _right_line_up_domains_cbmi != null ) && _right_line_up_domains_cbmi.isEnabled() ) {
1746             options.setRightLineUpDomains( _right_line_up_domains_cbmi.isSelected() );
1747         }
1748         if ( ( _line_up_renderable_data_cbmi != null ) && _line_up_renderable_data_cbmi.isEnabled() ) {
1749             options.setLineUpRendarableNodeData( _line_up_renderable_data_cbmi.isSelected() );
1750         }
1751         if ( _graphics_export_visible_only_cbmi != null ) {
1752             options.setGraphicsExportVisibleOnly( _graphics_export_visible_only_cbmi.isSelected() );
1753         }
1754     }
1755
1756     void updateTypeCheckboxes( final Options options, final Object o ) {
1757         setTypeMenuToAllUnselected();
1758         ( ( JCheckBoxMenuItem ) o ).setSelected( true );
1759     }
1760
1761     void viewAsNexus() {
1762         if ( ( getMainPanel().getCurrentPhylogeny() != null ) && !getMainPanel().getCurrentPhylogeny().isEmpty() ) {
1763             String title = "Nexus";
1764             if ( !ForesterUtil.isEmpty( getMainPanel().getCurrentPhylogeny().getName() ) ) {
1765                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1766             }
1767             showTextFrame( getMainPanel().getCurrentPhylogeny().toNexus( getOptions()
1768                                    .getNhConversionSupportValueStyle() ),
1769                            title );
1770         }
1771     }
1772
1773     void viewAsNH() {
1774         if ( ( getMainPanel().getCurrentPhylogeny() != null ) && !getMainPanel().getCurrentPhylogeny().isEmpty() ) {
1775             String title = "New Hampshire";
1776             if ( !ForesterUtil.isEmpty( getMainPanel().getCurrentPhylogeny().getName() ) ) {
1777                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1778             }
1779             showTextFrame( getMainPanel().getCurrentPhylogeny().toNewHampshire( getOptions()
1780                                    .getNhConversionSupportValueStyle() ),
1781                            title );
1782         }
1783     }
1784
1785     void viewAsXML() {
1786         if ( ( getMainPanel().getCurrentPhylogeny() != null ) && !getMainPanel().getCurrentPhylogeny().isEmpty() ) {
1787             String title = "phyloXML";
1788             if ( !ForesterUtil.isEmpty( getMainPanel().getCurrentPhylogeny().getName() ) ) {
1789                 title = "\"" + getMainPanel().getCurrentPhylogeny().getName() + "\" in " + title;
1790             }
1791             showTextFrame( getMainPanel().getCurrentPhylogeny().toPhyloXML( 0 ), title );
1792         }
1793     }
1794
1795     static void setTextForPdfLineWidthChooserMenuItem( final JMenuItem mi, final Options o ) {
1796         mi.setText( "Enter Default Line Width for PDF Export... (current: " + o.getPrintLineWidth() + ")" );
1797     }
1798
1799     static void setupScreenTextAntialias( final List<TreePanel> treepanels, final boolean antialias ) {
1800         for( final TreePanel tree_panel : treepanels ) {
1801             tree_panel.setTextAntialias();
1802         }
1803     }
1804 }