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