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