X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Farchaeopteryx%2FTreePanel.java;h=68b63761f3f1760fc498d44eb2d226f1c8124850;hb=fbb463a0dc277aa6efa5231f6db554de3696b194;hp=4c1529f56958c96d649880fb9fc9c195c341bb4d;hpb=790ebe51ea3e7fcafc91057f4842453a1c351b61;p=jalview.git diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanel.java b/forester/java/src/org/forester/archaeopteryx/TreePanel.java index 4c1529f..68b6376 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanel.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanel.java @@ -34,9 +34,9 @@ import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; -import java.awt.Polygon; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; @@ -54,6 +54,7 @@ import java.awt.geom.Arc2D; import java.awt.geom.CubicCurve2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; +import java.awt.geom.Path2D; import java.awt.geom.QuadCurve2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -100,18 +101,20 @@ import org.forester.archaeopteryx.phylogeny.data.RenderableVector; import org.forester.archaeopteryx.tools.Blast; import org.forester.archaeopteryx.tools.ImageLoader; import org.forester.io.parsers.phyloxml.PhyloXmlUtil; +import org.forester.io.writers.SequenceWriter; import org.forester.phylogeny.Phylogeny; import org.forester.phylogeny.PhylogenyMethods; import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY; import org.forester.phylogeny.PhylogenyNode; +import org.forester.phylogeny.data.Accession; import org.forester.phylogeny.data.Annotation; import org.forester.phylogeny.data.BranchColor; import org.forester.phylogeny.data.Confidence; import org.forester.phylogeny.data.Event; import org.forester.phylogeny.data.NodeData.NODE_DATA; -import org.forester.phylogeny.data.NodeVisualization; -import org.forester.phylogeny.data.NodeVisualization.NodeFill; -import org.forester.phylogeny.data.NodeVisualization.NodeShape; +import org.forester.phylogeny.data.NodeVisualData; +import org.forester.phylogeny.data.NodeVisualData.NodeFill; +import org.forester.phylogeny.data.NodeVisualData.NodeShape; import org.forester.phylogeny.data.PhylogenyDataUtil; import org.forester.phylogeny.data.PropertiesMap; import org.forester.phylogeny.data.Property; @@ -125,117 +128,127 @@ import org.forester.util.BasicDescriptiveStatistics; import org.forester.util.DescriptiveStatistics; import org.forester.util.ForesterConstants; import org.forester.util.ForesterUtil; -import org.forester.util.SequenceIdParser; +import org.forester.util.SequenceAccessionTools; +import org.forester.util.TaxonomyUtil; public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable { - private static final float PI = ( float ) ( Math.PI ); - private static final double TWO_PI = 2 * Math.PI; - private static final float ONEHALF_PI = ( float ) ( 1.5 * Math.PI ); - private static final float HALF_PI = ( float ) ( Math.PI / 2.0 ); - private static final float ANGLE_ROTATION_UNIT = ( float ) ( Math.PI / 32 ); - private static final short OV_BORDER = 10; - final static Cursor CUT_CURSOR = Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ); - final static Cursor MOVE_CURSOR = Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR ); - final static Cursor ARROW_CURSOR = Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ); - final static Cursor HAND_CURSOR = Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ); - final static Cursor WAIT_CURSOR = Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ); - private final static long serialVersionUID = -978349745916505029L; - private final static int EURO_D = 10; - private final static String NODE_POPMENU_NODE_CLIENT_PROPERTY = "node"; - private final static int MIN_ROOT_LENGTH = 3; - private final static int MAX_SUBTREES = 100; - private final static int MAX_NODE_FRAMES = 10; - private final static int MOVE = 20; - private final static NumberFormat FORMATTER_CONFIDENCE; - private final static NumberFormat FORMATTER_BRANCH_LENGTH; - private final static int WIGGLE = 2; - private final static int LIMIT_FOR_HQ_RENDERING = 1000; - private final static int CONFIDENCE_LEFT_MARGIN = 4; - private final RenderingHints _rendering_hints = new RenderingHints( RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_DEFAULT ); - private File _treefile = null; - private Configuration _configuration = null; - private final NodeFrame[] _node_frames = new NodeFrame[ TreePanel.MAX_NODE_FRAMES ]; - private int _node_frame_index = 0; - private Phylogeny _phylogeny = null; - private final Phylogeny[] _sub_phylogenies = new Phylogeny[ TreePanel.MAX_SUBTREES ]; - private final PhylogenyNode[] _sub_phylogenies_temp_roots = new PhylogenyNode[ TreePanel.MAX_SUBTREES ]; - private int _subtree_index = 0; - private MainPanel _main_panel = null; - private Set _found_nodes = null; - private PhylogenyNode _highlight_node = null; - private JPopupMenu _node_popup_menu = null; - private JMenuItem _node_popup_menu_items[] = null; - private int _longest_ext_node_info = 0; - private float _x_correction_factor = 0.0f; - private float _ov_x_correction_factor = 0.0f; - private float _x_distance = 0.0f; - private float _y_distance = 0.0f; - private PHYLOGENY_GRAPHICS_TYPE _graphics_type = PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR; - private double _domain_structure_width = Constants.DOMAIN_STRUCTURE_DEFAULT_WIDTH; - private int _domain_structure_e_value_thr_exp = Constants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP; - private float _last_drag_point_x = 0; - private float _last_drag_point_y = 0; - private ControlPanel _control_panel = null; - private int _external_node_index = 0; - private final Polygon _polygon = new Polygon(); - private final StringBuilder _sb = new StringBuilder(); - private JColorChooser _color_chooser = null; - private double _scale_distance = 0.0; - private String _scale_label = null; - private final CubicCurve2D _cubic_curve = new CubicCurve2D.Float(); - private final QuadCurve2D _quad_curve = new QuadCurve2D.Float(); - private final Line2D _line = new Line2D.Float(); - private final Ellipse2D _ellipse = new Ellipse2D.Float(); - private final Rectangle2D _rectangle = new Rectangle2D.Float(); - private Options _options = null; - private float _ov_max_width = 0; - private float _ov_max_height = 0; - private int _ov_x_position = 0; - private int _ov_y_position = 0; - private int _ov_y_start = 0; - private float _ov_y_distance = 0; - private float _ov_x_distance = 0; - private boolean _ov_on = false; - private double _urt_starting_angle = ( float ) ( Math.PI / 2 ); - private float _urt_factor = 1; - private float _urt_factor_ov = 1; - private final boolean _phy_has_branch_lengths; - private final Rectangle2D _ov_rectangle = new Rectangle2D.Float(); - private boolean _in_ov_rect = false; - private boolean _in_ov = false; - private final Rectangle _ov_virtual_rectangle = new Rectangle(); - final private static double _180_OVER_PI = 180.0 / Math.PI; - private static final float ROUNDED_D = 8; - private int _circ_max_depth; - private PhylogenyNode _root; - final private Arc2D _arc = new Arc2D.Double(); - final private HashMap _urt_nodeid_angle_map = new HashMap(); - final private HashMap _urt_nodeid_index_map = new HashMap(); - final private Set _collapsed_external_nodeid_set = new HashSet(); - HashMap _nodeid_dist_to_leaf = new HashMap(); - private AffineTransform _at; - private double _max_distance_to_root = -1; - private int _dynamic_hiding_factor = 0; - private boolean _edited = false; - private Popup _node_desc_popup; - private JTextArea _rollover_popup; - private final StringBuffer _popup_buffer = new StringBuffer(); - final private static Font POPUP_FONT = new Font( Configuration - .getDefaultFontFamilyName(), - Font.PLAIN, - 12 ); - private Sequence _query_sequence = null; - private final FontRenderContext _frc = new FontRenderContext( null, - false, - false ); + final static Cursor ARROW_CURSOR = Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ); + final static Cursor CUT_CURSOR = Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ); + final static Cursor HAND_CURSOR = Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ); + final static Cursor MOVE_CURSOR = Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR ); + final static Cursor WAIT_CURSOR = Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ); + final private static double _180_OVER_PI = 180.0 / Math.PI; + private static final float ANGLE_ROTATION_UNIT = ( float ) ( Math.PI / 32 ); + private final static int CONFIDENCE_LEFT_MARGIN = 4; + private final static int EURO_D = 10; + private final static NumberFormat FORMATTER_BRANCH_LENGTH; + private final static NumberFormat FORMATTER_CONFIDENCE; + private static final float HALF_PI = ( float ) ( Math.PI / 2.0 ); + private final static int LIMIT_FOR_HQ_RENDERING = 2000; + private final static int MAX_NODE_FRAMES = 10; + private final static int MAX_SUBTREES = 100; + private final static int MIN_ROOT_LENGTH = 3; + private final static int MOVE = 20; + private final static String NODE_POPMENU_NODE_CLIENT_PROPERTY = "node"; + private static final float ONEHALF_PI = ( float ) ( 1.5 * Math.PI ); + private static final short OV_BORDER = 10; + private static final float PI = ( float ) ( Math.PI ); + final private static Font POPUP_FONT = new Font( Configuration.getDefaultFontFamilyName(), + Font.PLAIN, + 12 ); + private static final float ROUNDED_D = 8; + private final static long serialVersionUID = -978349745916505029L; + private static final BasicStroke STROKE_005 = new BasicStroke( 0.05f ); + private static final BasicStroke STROKE_01 = new BasicStroke( 0.1f ); + private static final BasicStroke STROKE_025 = new BasicStroke( 0.25f ); + private static final BasicStroke STROKE_05 = new BasicStroke( 0.5f ); + private static final BasicStroke STROKE_075 = new BasicStroke( 0.75f ); + private static final BasicStroke STROKE_1 = new BasicStroke( 1f ); + private static final BasicStroke STROKE_2 = new BasicStroke( 2f ); + private static final double TWO_PI = 2 * Math.PI; + private final static int WIGGLE = 2; + private final static double OVERVIEW_FOUND_NODE_BOX_SIZE = 2; + private final static double OVERVIEW_FOUND_NODE_BOX_SIZE_HALF = 1; + HashMap _nodeid_dist_to_leaf = new HashMap(); + final private Arc2D _arc = new Arc2D.Double(); + private AffineTransform _at; + private int _circ_max_depth; + final private Set _collapsed_external_nodeid_set = new HashSet(); + private JColorChooser _color_chooser = null; + private Configuration _configuration = null; + private ControlPanel _control_panel = null; + private final CubicCurve2D _cubic_curve = new CubicCurve2D.Float(); + private Set _current_external_nodes = null; + private StringBuilder _current_external_nodes_data_buffer = new StringBuilder(); + private int _current_external_nodes_data_buffer_change_counter = 0; + private int _domain_structure_e_value_thr_exp = Constants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP; + private double _domain_structure_width = Constants.DOMAIN_STRUCTURE_DEFAULT_WIDTH; + private int _dynamic_hiding_factor = 0; + private boolean _edited = false; + private final Ellipse2D _ellipse = new Ellipse2D.Float(); + private int _external_node_index = 0; + private Set _found_nodes_0 = null; + private Set _found_nodes_1 = null; + private final FontRenderContext _frc = new FontRenderContext( null, + false, + false ); + private PHYLOGENY_GRAPHICS_TYPE _graphics_type = PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR; + private PhylogenyNode _highlight_node = null; + private boolean _in_ov = false; + private boolean _in_ov_rect = false; + private float _last_drag_point_x = 0; + private float _last_drag_point_y = 0; + private final Line2D _line = new Line2D.Float(); + private int _longest_ext_node_info = 0; + private MainPanel _main_panel = null; + private double _max_distance_to_root = -1; + private Popup _node_desc_popup; + private int _node_frame_index = 0; + private final NodeFrame[] _node_frames = new NodeFrame[ TreePanel.MAX_NODE_FRAMES ]; + private JPopupMenu _node_popup_menu = null; + private JMenuItem _node_popup_menu_items[] = null; + private PhylogenyNode[] _nodes_in_preorder = null; + private Options _options = null; + private float _ov_max_height = 0; + private float _ov_max_width = 0; + private boolean _ov_on = false; + private final Rectangle2D _ov_rectangle = new Rectangle2D.Float(); + private final Rectangle _ov_virtual_rectangle = new Rectangle(); + private float _ov_x_correction_factor = 0.0f; + private float _ov_x_distance = 0; + private int _ov_x_position = 0; + private float _ov_y_distance = 0; + private int _ov_y_position = 0; + private int _ov_y_start = 0; + private final boolean _phy_has_branch_lengths; + private Phylogeny _phylogeny = null; + private final Path2D.Float _polygon = new Path2D.Float(); + private final StringBuffer _popup_buffer = new StringBuffer(); + private final QuadCurve2D _quad_curve = new QuadCurve2D.Float(); + private Sequence _query_sequence = null; + private final Rectangle2D _rectangle = new Rectangle2D.Float(); + private final RenderingHints _rendering_hints = new RenderingHints( RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_DEFAULT ); + private JTextArea _rollover_popup; + private PhylogenyNode _root; + private final StringBuilder _sb = new StringBuilder(); + private double _scale_distance = 0.0; + private String _scale_label = null; // expression values menu: - private DescriptiveStatistics _statistics_for_vector_data; - private PhylogenyNode[] _nodes_in_preorder = null; - private StringBuilder _current_external_nodes_data_buffer = new StringBuilder(); - private int _current_external_nodes_data_buffer_change_counter = 0; - private Set _current_external_nodes = null; + private DescriptiveStatistics _statistics_for_vector_data; + private final Phylogeny[] _sub_phylogenies = new Phylogeny[ TreePanel.MAX_SUBTREES ]; + private final PhylogenyNode[] _sub_phylogenies_temp_roots = new PhylogenyNode[ TreePanel.MAX_SUBTREES ]; + private int _subtree_index = 0; + private File _treefile = null; + private float _urt_factor = 1; + private float _urt_factor_ov = 1; + final private HashMap _urt_nodeid_angle_map = new HashMap(); + final private HashMap _urt_nodeid_index_map = new HashMap(); + private double _urt_starting_angle = ( float ) ( Math.PI / 2 ); + private float _x_correction_factor = 0.0f; + private float _x_distance = 0.0f; + private float _y_distance = 0.0f; // private Image offscreenImage; // private Graphics offscreenGraphics; // private Dimension offscreenDimension; @@ -307,65 +320,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee requestFocusInWindow(); } - public void checkForVectorProperties( final Phylogeny phy ) { - final DescriptiveStatistics stats = new BasicDescriptiveStatistics(); - for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) { - final PhylogenyNode node = iter.next(); - if ( node.getNodeData().getProperties() != null ) { - final PropertiesMap pm = node.getNodeData().getProperties(); - final double[] vector = new double[ pm.getProperties().size() ]; - int counter = 0; - for( final String ref : pm.getProperties().keySet() ) { - if ( ref.startsWith( PhyloXmlUtil.VECTOR_PROPERTY_REF ) ) { - final Property p = pm.getProperty( ref ); - final String value_str = p.getValue(); - final String index_str = ref - .substring( PhyloXmlUtil.VECTOR_PROPERTY_REF.length(), ref.length() ); - double d = -100; - try { - d = Double.parseDouble( value_str ); - } - catch ( final NumberFormatException e ) { - JOptionPane.showMessageDialog( this, "Could not parse \"" + value_str - + "\" into a decimal value", "Problem with Vector Data", JOptionPane.ERROR_MESSAGE ); - return; - } - int i = -1; - try { - i = Integer.parseInt( index_str ); - } - catch ( final NumberFormatException e ) { - JOptionPane.showMessageDialog( this, - "Could not parse \"" + index_str - + "\" into index for vector data", - "Problem with Vector Data", - JOptionPane.ERROR_MESSAGE ); - return; - } - if ( i < 0 ) { - JOptionPane.showMessageDialog( this, - "Attempt to use negative index for vector data", - "Problem with Vector Data", - JOptionPane.ERROR_MESSAGE ); - return; - } - vector[ i ] = d; - ++counter; - stats.addValue( d ); - } - } - final List vector_l = new ArrayList( counter ); - for( int i = 0; i < counter; ++i ) { - vector_l.add( vector[ i ] ); - } - node.getNodeData().setVector( vector_l ); - } - } - if ( stats.getN() > 0 ) { - _statistics_for_vector_data = stats; - } - } - public synchronized Hashtable getImageMap() { return getMainPanel().getImageMap(); } @@ -404,7 +358,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getControlPanel().displayedPhylogenyMightHaveChanged( true ); } else { - getTreeFontSet().decreaseFontSize(); + getTreeFontSet().decreaseFontSize( 1, false ); getControlPanel().displayedPhylogenyMightHaveChanged( true ); } } @@ -499,11 +453,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - public final void setArrowCursor() { - setCursor( ARROW_CURSOR ); - repaint(); - } - public final void setEdited( final boolean edited ) { _edited = edited; } @@ -513,20 +462,60 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } /** + * Set a phylogeny tree. + * + * @param t + * an instance of a Phylogeny + */ + public final void setTree( final Phylogeny t ) { + setNodeInPreorderToNull(); + _phylogeny = t; + } + + public final void setWaitCursor() { + setCursor( WAIT_CURSOR ); + repaint(); + } + + @Override + public void update( final Graphics g ) { + paint( g ); + } + + final void calcMaxDepth() { + if ( _phylogeny != null ) { + _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny ); + } + } + + /** * Set parameters for printing the displayed tree * - * @param x - * @param y */ - public final void setParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) { + final void calcParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) { // updateStyle(); not needed? if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) { initNodeData(); if ( recalc_longest_ext_node_info ) { calculateLongestExtNodeInfo(); - while ( ( getLongestExtNodeInfo() > ( x * 0.67 ) ) && ( getTreeFontSet().getLargeFont().getSize() > 2 ) ) { - getMainPanel().getTreeFontSet().decreaseFontSize(); - calculateLongestExtNodeInfo(); + if ( getOptions().isAllowFontSizeChange() ) { + if ( ( getLongestExtNodeInfo() > ( x * 0.6 ) ) + && ( getTreeFontSet().getLargeFont().getSize() > 2 + TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) { + while ( ( getLongestExtNodeInfo() > ( x * 0.7 ) ) + && ( getTreeFontSet().getLargeFont().getSize() > 2 ) ) { + getMainPanel().getTreeFontSet().decreaseFontSize( getConfiguration().getMinBaseFontSize(), + true ); + calculateLongestExtNodeInfo(); + } + } + else { + while ( ( getLongestExtNodeInfo() < ( x * 0.6 ) ) + && ( getTreeFontSet().getLargeFont().getSize() <= getTreeFontSet().getLargeFontMemory() + .getSize() - TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) { + getMainPanel().getTreeFontSet().increaseFontSize(); + calculateLongestExtNodeInfo(); + } + } } } int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes(); @@ -574,33 +563,27 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } _circ_max_depth = max_depth; setUpUrtFactor(); - } - } - - /** - * Set a phylogeny tree. - * - * @param t - * an instance of a Phylogeny - */ - public final void setTree( final Phylogeny t ) { - setNodeInPreorderToNull(); - _phylogeny = t; - } - - public final void setWaitCursor() { - setCursor( WAIT_CURSOR ); - repaint(); - } - - @Override - public void update( final Graphics g ) { - paint( g ); - } - - final void calcMaxDepth() { - if ( _phylogeny != null ) { - _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny ); + // + if ( getOptions().isAllowFontSizeChange() ) { + if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) + && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) { + // int dynamic_hiding_factor = calcDynamicHidingFactor(); + // if ( dynamic_hiding_factor > 1 ) { + // while ( dynamic_hiding_factor > 1 + // && getTreeFontSet()._fm_large.getHeight() > TreeFontSet.SMALL_FONTS_BASE ) { + // getTreeFontSet().decreaseFontSize( 1, true ); + // dynamic_hiding_factor = calcDynamicHidingFactor(); + // } + // } + // else if ( getTreeFontSet().isDecreasedSizeBySystem() ) { + // while ( dynamic_hiding_factor < 1 && getTreeFontSet()._fm_large.getHeight() < 12 ) { + // getTreeFontSet().increaseFontSize(); + // dynamic_hiding_factor = calcDynamicHidingFactor(); + // } + // } + } + } + // } } @@ -629,18 +612,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .getValue() + " " ); } - if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { + if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + " " ); } - if ( getControlPanel().isShowGeneSymbols() + if ( getControlPanel().isShowSeqSymbols() && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) { sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol() + " " ); } + if ( getControlPanel().isShowGeneNames() + && ( node.getNodeData().getSequence().getGeneName().length() > 0 ) ) { + sum += getTreeFontSet()._fm_large + .stringWidth( node.getNodeData().getSequence().getGeneName() + " " ); + } if ( getControlPanel().isShowAnnotation() && ( node.getNodeData().getSequence().getAnnotations() != null ) && !node.getNodeData().getSequence().getAnnotations().isEmpty() ) { - sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getAnnotation( 0 ) - .asSimpleText() + sum += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node + .getNodeData().getSequence().getAnnotations(), getOptions().isShowAnnotationRefSource() ) + " " ); } if ( getControlPanel().isShowDomainArchitectures() @@ -718,23 +706,107 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final Color calculateTaxonomyBasedColor( final Taxonomy tax ) { - String species = tax.getTaxonomyCode(); - if ( ForesterUtil.isEmpty( species ) ) { - species = tax.getScientificName(); - if ( ForesterUtil.isEmpty( species ) ) { - species = tax.getCommonName(); + if ( getOptions().isColorByTaxonomicGroup() ) { + if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) { + boolean ex = false; + String group = null; + try { + group = TaxonomyUtil.getTaxGroupByTaxCode( tax.getTaxonomyCode() ); + } + catch ( final Exception e ) { + ex = true; + } + if ( !ex && !ForesterUtil.isEmpty( group ) ) { + final Color c = ForesterUtil.obtainColorDependingOnTaxonomyGroup( group ); + if ( c != null ) { + return c; + } + } } - } - if ( ForesterUtil.isEmpty( species ) ) { return getTreeColorSet().getTaxonomyColor(); } - // Look in species hash - Color c = getControlPanel().getSpeciesColors().get( species ); - if ( c == null ) { - c = AptxUtil.calculateColorFromString( species ); - getControlPanel().getSpeciesColors().put( species, c ); + else { + if ( ForesterUtil.isEmpty( tax.getTaxonomyCode() ) && ForesterUtil.isEmpty( tax.getScientificName() ) ) { + return getTreeColorSet().getTaxonomyColor(); + } + Color c = null; + if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) { + c = getControlPanel().getSpeciesColors().get( tax.getTaxonomyCode() ); + } + if ( ( c == null ) && !ForesterUtil.isEmpty( tax.getScientificName() ) ) { + c = getControlPanel().getSpeciesColors().get( tax.getScientificName() ); + } + if ( c == null ) { + if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) { + c = TreePanelUtil.calculateColorFromString( tax.getTaxonomyCode(), true ); + getControlPanel().getSpeciesColors().put( tax.getTaxonomyCode(), c ); + } + else { + c = TreePanelUtil.calculateColorFromString( tax.getScientificName(), true ); + getControlPanel().getSpeciesColors().put( tax.getScientificName(), c ); + } + } + return c; + } + } + + void checkForVectorProperties( final Phylogeny phy ) { + final DescriptiveStatistics stats = new BasicDescriptiveStatistics(); + for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) { + final PhylogenyNode node = iter.next(); + if ( node.getNodeData().getProperties() != null ) { + final PropertiesMap pm = node.getNodeData().getProperties(); + final double[] vector = new double[ pm.getProperties().size() ]; + int counter = 0; + for( final String ref : pm.getProperties().keySet() ) { + if ( ref.startsWith( PhyloXmlUtil.VECTOR_PROPERTY_REF ) ) { + final Property p = pm.getProperty( ref ); + final String value_str = p.getValue(); + final String index_str = ref + .substring( PhyloXmlUtil.VECTOR_PROPERTY_REF.length(), ref.length() ); + double d = -100; + try { + d = Double.parseDouble( value_str ); + } + catch ( final NumberFormatException e ) { + JOptionPane.showMessageDialog( this, "Could not parse \"" + value_str + + "\" into a decimal value", "Problem with Vector Data", JOptionPane.ERROR_MESSAGE ); + return; + } + int i = -1; + try { + i = Integer.parseInt( index_str ); + } + catch ( final NumberFormatException e ) { + JOptionPane.showMessageDialog( this, + "Could not parse \"" + index_str + + "\" into index for vector data", + "Problem with Vector Data", + JOptionPane.ERROR_MESSAGE ); + return; + } + if ( i < 0 ) { + JOptionPane.showMessageDialog( this, + "Attempt to use negative index for vector data", + "Problem with Vector Data", + JOptionPane.ERROR_MESSAGE ); + return; + } + vector[ i ] = d; + ++counter; + stats.addValue( d ); + } + } + final List vector_l = new ArrayList( counter ); + for( int i = 0; i < counter; ++i ) { + vector_l.add( vector[ i ] ); + } + node.getNodeData().setVector( vector_l ); + } + } + if ( stats.getN() > 0 ) { + _statistics_for_vector_data = stats; } - return c; } void clearCurrentExternalNodesDataBuffer() { @@ -757,7 +829,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !node.isExternal() && !node.isRoot() ) { final boolean collapse = !node.isCollapse(); - AptxUtil.collapseSubtree( node, collapse ); + TreePanelUtil.collapseSubtree( node, collapse ); updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); @@ -776,7 +848,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - AptxUtil.collapseSpeciesSpecificSubtrees( _phylogeny ); + TreePanelUtil.collapseSpeciesSpecificSubtrees( _phylogeny ); updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); @@ -794,11 +866,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } setWaitCursor(); AptxUtil.removeBranchColors( _phylogeny ); - final int colorizations = AptxUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this ); + final int colorizations = TreePanelUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this ); if ( colorizations > 0 ) { _control_panel.setColorBranches( true ); - if ( _control_panel.getColorBranchesCb() != null ) { - _control_panel.getColorBranchesCb().setSelected( true ); + if ( _control_panel.getUseVisualStylesCb() != null ) { + _control_panel.getUseVisualStylesCb().setSelected( true ); } if ( _control_panel.getColorAccSpeciesCb() != null ) { _control_panel.getColorAccSpeciesCb().setSelected( false ); @@ -816,6 +888,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { msg += "colorized one subtree"; } + setEdited( true ); JOptionPane.showMessageDialog( this, msg, "Taxonomy Colorization Completed (" + rank + ")", @@ -839,10 +912,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } setWaitCursor(); AptxUtil.removeBranchColors( _phylogeny ); - AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); + TreePanelUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); _control_panel.setColorBranches( true ); - if ( _control_panel.getColorBranchesCb() != null ) { - _control_panel.getColorBranchesCb().setSelected( true ); + if ( _control_panel.getUseVisualStylesCb() != null ) { + _control_panel.getUseVisualStylesCb().setSelected( true ); } setArrowCursor(); repaint(); @@ -899,12 +972,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return _domain_structure_e_value_thr_exp; } - final Set getFoundNodes() { - return _found_nodes; + final Set getFoundNodes0() { + return _found_nodes_0; + } + + final Set getFoundNodes1() { + return _found_nodes_1; } final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) { - if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { + if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { return ( PhylogenyMethods.getBranchColorValue( node ) ); } else { @@ -1114,6 +1191,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee PhylogenyMethods.midpointRoot( _phylogeny ); resetNodeIdToDistToLeafMap(); setArrowCursor(); + setEdited( true ); repaint(); } @@ -1154,10 +1232,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee // Check if shift key is down if ( ( e.getModifiers() & InputEvent.SHIFT_MASK ) != 0 ) { // Yes, so add to _found_nodes - if ( getFoundNodes() == null ) { - setFoundNodes( new HashSet() ); + if ( getFoundNodes0() == null ) { + setFoundNodes0( new HashSet() ); } - getFoundNodes().add( node.getId() ); + getFoundNodes0().add( node.getId() ); // Check if control key is down } else if ( ( e.getModifiers() & InputEvent.CTRL_MASK ) != 0 ) { @@ -1355,10 +1433,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee root_x + ( Math.cos( angle ) * parent_radius ), root_y + ( Math.sin( angle ) * parent_radius ), g ); - paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file, isInFoundNodes( c ) - || isInCurrentExternalNodes( c ) ); + paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file ); if ( c.isExternal() ) { - final boolean is_in_found_nodes = isInFoundNodes( c ) || isInCurrentExternalNodes( c ); + final boolean is_in_found_nodes = isInFoundNodes0( c ) || isInFoundNodes1( c ) + || isInCurrentExternalNodes( c ); if ( ( _dynamic_hiding_factor > 1 ) && !is_in_found_nodes && ( ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor ) != 1 ) ) { return; @@ -1386,8 +1464,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee root_y + ( Math.sin( angle ) * parent_radius ), g ); if ( isInFoundNodes( c ) || isInCurrentExternalNodes( c ) ) { - g.setColor( getTreeColorSet().getFoundColor() ); - drawRectFilled( c.getXSecondary() - 1, c.getYSecondary() - 1, 3, 3, g ); + g.setColor( getColorForFoundNode( c ) ); + drawRectFilled( c.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, c.getYSecondary() + - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, OVERVIEW_FOUND_NODE_BOX_SIZE, OVERVIEW_FOUND_NODE_BOX_SIZE, g ); } } @@ -1422,7 +1501,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, g, to_pdf, to_graphics_file ); - paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) ); + paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file ); } final void paintCircularLite( final Phylogeny phy, @@ -1490,7 +1569,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height ); } } - g.setStroke( new BasicStroke( 1 ) ); + setupStroke( g ); } else { g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) ); @@ -1512,7 +1591,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee // Position starting Y of tree _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() ) + ( TreePanel.MOVE / 2.0f ) ); - final int dynamic_hiding_factor = ( int ) ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) ); + final int dynamic_hiding_factor = calcDynamicHidingFactor(); if ( getControlPanel().isDynamicallyHideData() ) { if ( dynamic_hiding_factor > 1 ) { getControlPanel().setDynamicHidingIsOn( true ); @@ -1700,6 +1779,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setNodeInPreorderToNull(); resetPreferredSize(); getMainPanel().adjustJScrollPane(); + setEdited( true ); repaint(); if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) { getControlPanel().showWhole(); @@ -1707,7 +1787,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final void resetNodeIdToDistToLeafMap() { - _nodeid_dist_to_leaf = new HashMap(); + _nodeid_dist_to_leaf = new HashMap(); } final void resetPreferredSize() { @@ -1742,25 +1822,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final void selectNode( final PhylogenyNode node ) { - if ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) ) { - getFoundNodes().remove( node.getId() ); - getControlPanel().setSearchFoundCountsOnLabel( getFoundNodes().size() ); - if ( getFoundNodes().size() < 1 ) { - getControlPanel().searchReset(); + if ( ( getFoundNodes0() != null ) && getFoundNodes0().contains( node.getId() ) ) { + getFoundNodes0().remove( node.getId() ); + getControlPanel().setSearchFoundCountsOnLabel0( getFoundNodes0().size() ); + if ( getFoundNodes0().size() < 1 ) { + getControlPanel().searchReset0(); } } else { - getControlPanel().getSearchFoundCountsLabel().setVisible( true ); - getControlPanel().getSearchResetButton().setEnabled( true ); - getControlPanel().getSearchResetButton().setVisible( true ); - if ( getFoundNodes() == null ) { - setFoundNodes( new HashSet() ); + getControlPanel().getSearchFoundCountsLabel0().setVisible( true ); + getControlPanel().getSearchResetButton0().setEnabled( true ); + getControlPanel().getSearchResetButton0().setVisible( true ); + if ( getFoundNodes0() == null ) { + setFoundNodes0( new HashSet() ); } - getFoundNodes().add( node.getId() ); - getControlPanel().setSearchFoundCountsOnLabel( getFoundNodes().size() ); + getFoundNodes0().add( node.getId() ); + getControlPanel().setSearchFoundCountsOnLabel0( getFoundNodes0().size() ); } } + final void setArrowCursor() { + setCursor( ARROW_CURSOR ); + repaint(); + } + final void setControlPanel( final ControlPanel atv_control ) { _control_panel = atv_control; } @@ -1770,8 +1855,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _current_external_nodes_data_buffer = sb; } - final void setFoundNodes( final Set found_nodes ) { - _found_nodes = found_nodes; + final void setFoundNodes0( final Set found_nodes ) { + _found_nodes_0 = found_nodes; + } + + final void setFoundNodes1( final Set found_nodes ) { + _found_nodes_1 = found_nodes; } final void setInOvRect( final boolean in_ov_rect ) { @@ -1837,22 +1926,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( getMainPanel().getOptions().isAntialiasScreen() ) { - if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) - && !getMainPanel().getOptions().isShowDefaultNodeShapesInternal() - && !getMainPanel().getOptions().isShowDefaultNodeShapesExternal() - && ( ( getControlPanel() != null ) && !getControlPanel().isShowDomainArchitectures() ) ) { - _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF ); - } - else { - _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); - } - try { - _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB ); - } - catch ( final Throwable e ) { - _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON ); - } + _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); + // try { + _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB ); + // } + // catch ( final Throwable e ) { + // _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON ); + //} } else { _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF ); @@ -1885,8 +1965,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.TAXONOMY; if ( ( !getControlPanel().isShowTaxonomyScientificNames() && !getControlPanel().isShowTaxonomyCode() && !getControlPanel() .isShowTaxonomyCommonNames() ) ) { - if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowGeneNames() || getControlPanel() - .isShowGeneSymbols() ) ) { + if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowSeqNames() || getControlPanel() + .isShowSeqSymbols() ) ) { pri = DESCENDANT_SORT_PRIORITY.SEQUENCE; } else if ( getControlPanel().isShowNodeNames() ) { @@ -1931,7 +2011,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sub_phylogenies[ _subtree_index ] = _phylogeny; _sub_phylogenies_temp_roots[ _subtree_index ] = node; ++_subtree_index; - _phylogeny = subTree( node, _phylogeny ); + _phylogeny = TreePanelUtil.subTree( node, _phylogeny ); updateSubSuperTreeButton(); } else if ( node.isRoot() && isCurrentTreeIsSubtree() ) { @@ -1981,11 +2061,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); + TreePanelUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); _control_panel.setColorBranches( true ); - if ( _control_panel.getColorBranchesCb() != null ) { - _control_panel.getColorBranchesCb().setSelected( true ); + if ( _control_panel.getUseVisualStylesCb() != null ) { + _control_panel.getUseVisualStylesCb().setSelected( true ); } + setEdited( true ); setArrowCursor(); repaint(); } @@ -2158,9 +2239,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } - final private void addToCurrentExternalNodes( final int i ) { + final private void addToCurrentExternalNodes( final long i ) { if ( _current_external_nodes == null ) { - _current_external_nodes = new HashSet(); + _current_external_nodes = new HashSet(); } _current_external_nodes.add( i ); } @@ -2180,9 +2261,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee && ( getCopiedAndPastedNodes() != null ) && !to_pdf && !to_graphics_file && getCopiedAndPastedNodes().contains( node.getId() ) ) { - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getTreeColorSet().getFoundColor0() ); } - else if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { + else if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { g.setColor( PhylogenyMethods.getBranchColorValue( node ) ); } else if ( to_pdf ) { @@ -2226,7 +2307,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( type == '?' ) { - if ( SequenceIdParser.isProtein( query ) ) { + if ( SequenceAccessionTools.isProteinDbQuery( query ) ) { type = 'p'; } else { @@ -2257,6 +2338,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + private final int calcDynamicHidingFactor() { + return ( int ) ( 0.5 + ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) ) ); + } + /** * Calculate the length of the distance between the given node and its * parent. @@ -2286,13 +2371,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getControlPanel().isColorAccordingToAnnotation() && ( getControlPanel().getAnnotationColors() != null ) ) { final StringBuilder sb = new StringBuilder(); for( final Annotation a : ann ) { - sb.append( !ForesterUtil.isEmpty( a.getRef() ) ? a.getRef() : a.getDesc() ); + sb.append( !ForesterUtil.isEmpty( a.getRefValue() ) ? a.getRefValue() : a.getDesc() ); } final String ann_str = sb.toString(); if ( !ForesterUtil.isEmpty( ann_str ) ) { c = getControlPanel().getAnnotationColors().get( ann_str ); if ( c == null ) { - c = AptxUtil.calculateColorFromString( ann_str ); + c = TreePanelUtil.calculateColorFromString( ann_str, false ); getControlPanel().getAnnotationColors().put( ann_str, c ); } if ( c == null ) { @@ -2325,7 +2410,52 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.WARNING_MESSAGE ); } - final private void colorizeSubtree( final Color c, final PhylogenyNode node ) { + final private void colorizeSubtree( final Color c, + final PhylogenyNode node, + final List additional_nodes ) { + _control_panel.setColorBranches( true ); + if ( _control_panel.getUseVisualStylesCb() != null ) { + _control_panel.getUseVisualStylesCb().setSelected( true ); + } + if ( node != null ) { + for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) { + it.next().getBranchData().setBranchColor( new BranchColor( c ) ); + } + } + if ( additional_nodes != null ) { + for( final PhylogenyNode n : additional_nodes ) { + n.getBranchData().setBranchColor( new BranchColor( c ) ); + } + } + repaint(); + } + + final private void colorizeNodes( final Color c, + final PhylogenyNode node, + final List additional_nodes ) { + _control_panel.setColorBranches( true ); + if ( _control_panel.getUseVisualStylesCb() != null ) { + _control_panel.getUseVisualStylesCb().setSelected( true ); + } + if ( node != null ) { + colorizeNodesHelper( c, node ); + } + if ( additional_nodes != null ) { + for( final PhylogenyNode n : additional_nodes ) { + colorizeNodesHelper( c, n ); + } + } + repaint(); + } + + private final static void colorizeNodesHelper( final Color c, final PhylogenyNode node ) { + if ( node.getNodeData().getNodeVisualData() == null ) { + node.getNodeData().setNodeVisualData( new NodeVisualData() ); + } + node.getNodeData().getNodeVisualData().setFontColor( new Color( c.getRed(), c.getGreen(), c.getBlue() ) ); + } + + final private void colorSubtree( final PhylogenyNode node ) { if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { JOptionPane.showMessageDialog( this, "Cannot colorize subtree in unrooted display type", @@ -2333,37 +2463,77 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.WARNING_MESSAGE ); return; } - _control_panel.setColorBranches( true ); - if ( _control_panel.getColorBranchesCb() != null ) { - _control_panel.getColorBranchesCb().setSelected( true ); + _color_chooser.setPreviewPanel( new JPanel() ); + SubtreeColorizationActionListener al; + if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) { + final List additional_nodes = getFoundNodesAsListOfPhylogenyNodes(); + al = new SubtreeColorizationActionListener( _color_chooser, node, additional_nodes ); } - for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) { - it.next().getBranchData().setBranchColor( new BranchColor( c ) ); + else { + al = new SubtreeColorizationActionListener( _color_chooser, node ); } - repaint(); + final JDialog dialog = JColorChooser + .createDialog( this, "Subtree colorization", true, _color_chooser, al, null ); + dialog.setVisible( true ); } - final private void colorSubtree( final PhylogenyNode node ) { - Color intitial_color = null; - if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) - && ( ( ( !node.isRoot() && ( node.getParent().getNumberOfDescendants() < 3 ) ) ) || ( node.isRoot() ) ) ) { - intitial_color = PhylogenyMethods.getBranchColorValue( node ); + private void colorNodeFont( final PhylogenyNode node ) { + _color_chooser.setPreviewPanel( new JPanel() ); + NodeColorizationActionListener al; + if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) { + final List additional_nodes = getFoundNodesAsListOfPhylogenyNodes(); + al = new NodeColorizationActionListener( _color_chooser, node, additional_nodes ); } else { - intitial_color = getTreeColorSet().getBranchColor(); + al = new NodeColorizationActionListener( _color_chooser, node ); } - _color_chooser.setColor( intitial_color ); - _color_chooser.setPreviewPanel( new JPanel() ); - final JDialog dialog = JColorChooser - .createDialog( this, - "Subtree colorization", - true, - _color_chooser, - new SubtreeColorizationActionListener( _color_chooser, node ), - null ); + final JDialog dialog = JColorChooser.createDialog( this, "Node colorization", true, _color_chooser, al, null ); dialog.setVisible( true ); } + private void changeNodeFont( final PhylogenyNode node ) { + final FontChooser fc = new FontChooser(); + Font f = null; + if ( ( node.getNodeData().getNodeVisualData() != null ) && !node.getNodeData().getNodeVisualData().isEmpty() ) { + f = node.getNodeData().getNodeVisualData().getFont(); + } + if ( f != null ) { + fc.setFont( f ); + } + else { + fc.setFont( getMainPanel().getTreeFontSet().getLargeFont() ); + } + fc.showDialog( this, "Select Font" ); + if ( ( fc.getFont() != null ) && !ForesterUtil.isEmpty( fc.getFont().getFamily().trim() ) ) { + List nodes = new ArrayList(); + if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) { + nodes = getFoundNodesAsListOfPhylogenyNodes(); + } + nodes.add( node ); + for( final PhylogenyNode n : nodes ) { + if ( n.getNodeData().getNodeVisualData() == null ) { + n.getNodeData().setNodeVisualData( new NodeVisualData() ); + } + final NodeVisualData vd = n.getNodeData().getNodeVisualData(); + final Font ff = fc.getFont(); + vd.setFontName( ff.getFamily().trim() ); + int s = ff.getSize(); + if ( s < 0 ) { + s = 0; + } + if ( s > Byte.MAX_VALUE ) { + s = Byte.MAX_VALUE; + } + vd.setFontSize( s ); + vd.setFontStyle( ff.getStyle() ); + } + if ( _control_panel.getUseVisualStylesCb() != null ) { + getControlPanel().getUseVisualStylesCb().setSelected( true ); + } + } + repaint(); + } + final private void copySubtree( final PhylogenyNode node ) { if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { errorMessageNoCutCopyPasteInUnrootedDisplay(); @@ -2372,7 +2542,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setNodeInPreorderToNull(); setCutOrCopiedTree( _phylogeny.copy( node ) ); final List nodes = PhylogenyMethods.getAllDescendants( node ); - final Set node_ids = new HashSet( nodes.size() ); + final Set node_ids = new HashSet( nodes.size() ); for( final PhylogenyNode n : nodes ) { node_ids.add( n.getId() ); } @@ -2381,22 +2551,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } - private String createAnnotationString( final SortedSet ann ) { - final StringBuilder sb = new StringBuilder(); - boolean first = true; - for( final Annotation a : ann ) { - if ( !first ) { - sb.append( "|" ); - } - else { - first = false; - } - sb.append( a.asSimpleText() ); - } - final String ann_str = sb.toString(); - return ann_str; - } - final private String createASimpleTextRepresentationOfANode( final PhylogenyNode node ) { final String tax = PhylogenyMethods.getSpecies( node ); String label = node.getName(); @@ -2665,11 +2819,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.ERROR_MESSAGE ); } - final private Set getCopiedAndPastedNodes() { + private final Color getColorForFoundNode( final PhylogenyNode n ) { + if ( isInCurrentExternalNodes( n ) ) { + return getTreeColorSet().getFoundColor0(); + } + else if ( isInFoundNodes0( n ) && !isInFoundNodes1( n ) ) { + return getTreeColorSet().getFoundColor0(); + } + else if ( !isInFoundNodes0( n ) && isInFoundNodes1( n ) ) { + return getTreeColorSet().getFoundColor1(); + } + else { + return getTreeColorSet().getFoundColor0and1(); + } + } + + final private Set getCopiedAndPastedNodes() { return getMainPanel().getCopiedAndPastedNodes(); } - final private Set getCurrentExternalNodes() { + final private Set getCurrentExternalNodes() { return _current_external_nodes; } @@ -2677,6 +2846,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return getMainPanel().getCutOrCopiedTree(); } + private List getFoundNodesAsListOfPhylogenyNodes() { + final List additional_nodes = new ArrayList(); + if ( getFoundNodes0() != null ) { + for( final Long id : getFoundNodes0() ) { + additional_nodes.add( _phylogeny.getNode( id ) ); + } + } + if ( getFoundNodes1() != null ) { + for( final Long id : getFoundNodes1() ) { + if ( ( getFoundNodes0() == null ) || !getFoundNodes0().contains( id ) ) { + additional_nodes.add( _phylogeny.getNode( id ) ); + } + } + } + return additional_nodes; + } + final private float getLastDragPointX() { return _last_drag_point_x; } @@ -2735,6 +2921,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return _ov_y_start; } + final private List getPdbAccs( final PhylogenyNode node ) { + final List pdb_ids = new ArrayList(); + if ( node.getNodeData().isHasSequence() ) { + final Sequence seq = node.getNodeData().getSequence(); + if ( !ForesterUtil.isEmpty( seq.getCrossReferences() ) ) { + final SortedSet cross_refs = seq.getCrossReferences(); + for( final Accession acc : cross_refs ) { + if ( acc.getSource().equalsIgnoreCase( "pdb" ) ) { + pdb_ids.add( acc ); + } + } + } + } + return pdb_ids; + } + final private double getScaleDistance() { return _scale_distance; } @@ -2775,6 +2977,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee case COLOR_SUBTREE: colorSubtree( node ); break; + case COLOR_NODE_FONT: + colorNodeFont( node ); + break; + case CHANGE_NODE_FONT: + changeNodeFont( node ); + break; case OPEN_SEQ_WEB: openSeqWeb( node ); break; @@ -2784,6 +2992,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee case OPEN_TAX_WEB: openTaxWeb( node ); break; + case OPEN_PDB_WEB: + openPdbWeb( node ); + break; case CUT_SUBTREE: cutSubtree( node ); break; @@ -2868,30 +3079,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return Blast.isContainsQueryForBlast( node ); } - final private boolean isCanOpenSeqWeb( final PhylogenyNode node ) { - if ( node.getNodeData().isHasSequence() - && ( node.getNodeData().getSequence().getAccession() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getSource() ) - && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getValue() ) - && getConfiguration().isHasWebLink( node.getNodeData().getSequence().getAccession().getSource() - .toLowerCase() ) ) { - return true; + final private String isCanOpenSeqWeb( final PhylogenyNode node ) { + final Accession a = SequenceAccessionTools.obtainAccessorFromDataFields( node ); + if ( a != null ) { + return a.getValue(); } - return false; + return null; } final private boolean isCanOpenTaxWeb( final PhylogenyNode node ) { if ( node.getNodeData().isHasTaxonomy() - && ( ( ( node.getNodeData().getTaxonomy().getIdentifier() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getProvider() ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && getConfiguration() - .isHasWebLink( node.getNodeData().getTaxonomy().getIdentifier().getProvider().toLowerCase() ) ) - || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) + && ( ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) || ( ( node - .getNodeData().getTaxonomy().getIdentifier() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && node - .getNodeData().getTaxonomy().getIdentifier().getValue().startsWith( "http://" ) ) ) ) { + .getNodeData().getTaxonomy().getIdentifier() != null ) && !ForesterUtil.isEmpty( node + .getNodeData().getTaxonomy().getIdentifier().getValue() ) ) ) ) { return true; } else { @@ -2903,8 +3105,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return ( ( getCurrentExternalNodes() != null ) && getCurrentExternalNodes().contains( node.getId() ) ); } - final private boolean isInFoundNodes( final PhylogenyNode node ) { - return ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) ); + private boolean isInFoundNodes( final PhylogenyNode n ) { + return isInFoundNodes0( n ) || isInFoundNodes1( n ); + } + + final private boolean isInFoundNodes0( final PhylogenyNode node ) { + return ( ( getFoundNodes0() != null ) && getFoundNodes0().contains( node.getId() ) ); + } + + final private boolean isInFoundNodes1( final PhylogenyNode node ) { + return ( ( getFoundNodes1() != null ) && getFoundNodes1().contains( node.getId() ) ); } final private boolean isInOv() { @@ -2954,7 +3164,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); } else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) { - getMainPanel().getTreeFontSet().decreaseFontSize(); + getMainPanel().getTreeFontSet().decreaseFontSize( 1, false ); getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); } else if ( plusPressed( e.getKeyCode() ) ) { @@ -3111,7 +3321,49 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final String title = clickto_names.get( i ); _node_popup_menu_items[ i ] = new JMenuItem( title ); if ( title.equals( Configuration.clickto_options[ Configuration.open_seq_web ][ 0 ] ) ) { - _node_popup_menu_items[ i ].setEnabled( isCanOpenSeqWeb( node ) ); + final String id = isCanOpenSeqWeb( node ); + if ( !ForesterUtil.isEmpty( id ) ) { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + id + "]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + else { + _node_popup_menu_items[ i ].setEnabled( false ); + } + } + else if ( title.equals( Configuration.clickto_options[ Configuration.open_pdb_web ][ 0 ] ) ) { + final List accs = getPdbAccs( node ); + _node_popup_menu_items[ i ] = new JMenuItem( title ); + if ( !ForesterUtil.isEmpty( accs ) ) { + if ( accs.size() == 1 ) { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + + TreePanelUtil.pdbAccToString( accs, 0 ) + "]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + else if ( accs.size() == 2 ) { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + + TreePanelUtil.pdbAccToString( accs, 0 ) + ", " + + TreePanelUtil.pdbAccToString( accs, 1 ) + "]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + else if ( accs.size() == 3 ) { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + + TreePanelUtil.pdbAccToString( accs, 0 ) + ", " + + TreePanelUtil.pdbAccToString( accs, 1 ) + ", " + + TreePanelUtil.pdbAccToString( accs, 2 ) + "]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + else { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + + TreePanelUtil.pdbAccToString( accs, 0 ) + ", " + + TreePanelUtil.pdbAccToString( accs, 1 ) + ", " + + TreePanelUtil.pdbAccToString( accs, 2 ) + ", + " + ( accs.size() - 3 ) + " more]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + } + else { + _node_popup_menu_items[ i ].setEnabled( false ); + } + // } else if ( title.equals( Configuration.clickto_options[ Configuration.open_tax_web ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( isCanOpenTaxWeb( node ) ); @@ -3180,18 +3432,24 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee switch ( getOptions().getExtDescNodeDataToReturn() ) { case NODE_NAME: return "Node Names"; + case GENE_NAME: + return "Gene Names"; case SEQUENCE_NAME: return "Sequence Names"; case SEQUENCE_SYMBOL: return "Sequence Symbols"; case SEQUENCE_MOL_SEQ: return "Molecular Sequences"; + case SEQUENCE_MOL_SEQ_FASTA: + return "Molecular Sequences (Fasta)"; case SEQUENCE_ACC: return "Sequence Accessors"; case TAXONOMY_SCIENTIFIC_NAME: return "Scientific Names"; case TAXONOMY_CODE: return "Taxonomy Codes"; + case TAXONOMY_COMM0N_NAME: + return "Taxonomy Common Names"; case UNKNOWN: return "User Selected Data"; default: @@ -3200,36 +3458,48 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final private void openSeqWeb( final PhylogenyNode node ) { - if ( !isCanOpenSeqWeb( node ) ) { - cannotOpenBrowserWarningMessage( "sequence" ); + final private void openPdbWeb( final PhylogenyNode node ) { + final List pdb_ids = getPdbAccs( node ); + if ( ForesterUtil.isEmpty( pdb_ids ) ) { + cannotOpenBrowserWarningMessage( "PDB" ); return; } - String uri_str = null; - final Sequence seq = node.getNodeData().getSequence(); - final String source = seq.getAccession().getSource().toLowerCase(); - String url; - if ( source.toLowerCase().equals( "ncbi" ) ) { - url = Constants.NCBI_ALL_DATABASE_SEARCH; + final List uri_strs = TreePanelUtil.createUrisForPdbWeb( node, pdb_ids, getConfiguration(), this ); + if ( !ForesterUtil.isEmpty( uri_strs ) ) { + for( final String uri_str : uri_strs ) { + try { + AptxUtil.launchWebBrowser( new URI( uri_str ), + isApplet(), + isApplet() ? obtainApplet() : null, + "_aptx_seq" ); + } + catch ( final IOException e ) { + AptxUtil.showErrorMessage( this, e.toString() ); + e.printStackTrace(); + } + catch ( final URISyntaxException e ) { + AptxUtil.showErrorMessage( this, e.toString() ); + e.printStackTrace(); + } + } } else { - final WebLink weblink = getConfiguration().getWebLink( source ); - url = weblink.getUrl().toString(); - } - try { - uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 ); + cannotOpenBrowserWarningMessage( "PDB" ); } - catch ( final UnsupportedEncodingException e ) { - AptxUtil.showErrorMessage( this, e.toString() ); - e.printStackTrace(); + } + + final private void openSeqWeb( final PhylogenyNode node ) { + if ( ForesterUtil.isEmpty( isCanOpenSeqWeb( node ) ) ) { + cannotOpenBrowserWarningMessage( "sequence" ); + return; } + final String uri_str = TreePanelUtil.createUriForSeqWeb( node, getConfiguration(), this ); if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - JApplet applet = null; - if ( isApplet() ) { - applet = obtainApplet(); - } - AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), + isApplet(), + isApplet() ? obtainApplet() : null, + "_aptx_seq" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -3252,32 +3522,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } String uri_str = null; final Taxonomy tax = node.getNodeData().getTaxonomy(); - if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) - && getConfiguration().isHasWebLink( tax.getIdentifier().getProvider().toLowerCase() ) ) { - final String type = tax.getIdentifier().getProvider().toLowerCase(); - final WebLink weblink = getConfiguration().getWebLink( type ); + if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) + && tax.getIdentifier().getValue().startsWith( "http://" ) ) { try { - uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 ); + uri_str = new URI( tax.getIdentifier().getValue() ).toString(); } - catch ( final UnsupportedEncodingException e ) { + catch ( final URISyntaxException e ) { AptxUtil.showErrorMessage( this, e.toString() ); + uri_str = null; e.printStackTrace(); } } - else if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) - && tax.getIdentifier().getValue().startsWith( "http://" ) ) { + else if ( ( tax.getIdentifier() != null ) + && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) + && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) + && ( tax.getIdentifier().getProvider().equalsIgnoreCase( "ncbi" ) || tax.getIdentifier().getProvider() + .equalsIgnoreCase( "uniprot" ) ) ) { try { - uri_str = new URI( tax.getIdentifier().getValue() ).toString(); + uri_str = "http://www.uniprot.org/taxonomy/" + + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 ); } - catch ( final URISyntaxException e ) { + catch ( final UnsupportedEncodingException e ) { AptxUtil.showErrorMessage( this, e.toString() ); - uri_str = null; e.printStackTrace(); } } else if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) { try { - uri_str = "http://www.eol.org/search?q=" + uri_str = "http://www.uniprot.org/taxonomy/?query=" + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { @@ -3297,7 +3569,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else if ( !ForesterUtil.isEmpty( tax.getCommonName() ) ) { try { - uri_str = "http://www.eol.org/search?q=" + uri_str = "http://www.uniprot.org/taxonomy/?query=" + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { @@ -3307,11 +3579,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - JApplet applet = null; - if ( isApplet() ) { - applet = obtainApplet(); - } - AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), + isApplet(), + isApplet() ? obtainApplet() : null, + "_aptx_tax" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -3516,8 +3787,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( node.isExternal() ) { - paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) - || isInCurrentExternalNodes( node ) ); + paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file ); } } @@ -3602,12 +3872,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee c = Color.BLACK; } else if ( is_in_found_nodes ) { - c = getTreeColorSet().getFoundColor(); + c = getColorForFoundNode( node ); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { c = getTaxonomyBasedColor( node ); } - else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches() + else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { c = PhylogenyMethods.getBranchColorValue( node ); } @@ -3621,30 +3891,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { d = ( Math.log10( d ) * _y_distance ) / 2.5; } - final int box_size = getOptions().getDefaultNodeShapeSize(); + final int box_size = getOptions().getDefaultNodeShapeSize() + 1; if ( d < box_size ) { d = box_size; } + final float xx = node.getXcoord() - ( 2 * box_size ); + final float xxx = xx > node.getParent().getXcoord() + 1 ? xx : node.getParent().getXcoord() + 1; _polygon.reset(); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ), - ForesterUtil.roundToInt( node.getYcoord() ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), - ForesterUtil.roundToInt( node.getYcoord() - d ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), - ForesterUtil.roundToInt( node.getYcoord() + d ) ); - if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { + _polygon.moveTo( xxx, node.getYcoord() ); + _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() - d ); + _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() + d ); + _polygon.closePath(); + if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) { g.setColor( c ); - g.fillPolygon( _polygon ); + g.fill( _polygon ); } - else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) { + else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.NONE ) { g.setColor( getBackground() ); - g.fillPolygon( _polygon ); + g.fill( _polygon ); g.setColor( c ); - g.drawPolygon( _polygon ); + g.draw( _polygon ); } else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { - g.setPaint( new GradientPaint( node.getXcoord() - box_size, node.getYcoord(), getBackground(), ( node - .getXcoord() + box_size ), ( float ) ( node.getYcoord() - d ), c, false ) ); + g.setPaint( new GradientPaint( xxx, node.getYcoord(), getBackground(), node.getXcoord(), ( float ) ( node + .getYcoord() - d ), c, false ) ); g.fill( _polygon ); g.setPaint( c ); g.draw( _polygon ); @@ -3657,24 +3927,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_pdf, final boolean to_graphics_file ) { final List confidences = node.getBranchData().getConfidences(); - // if ( confidences.size() == 1 ) { - // final double value = node.getBranchData().getConfidence( 0 ).getValue(); - // if ( ( value == Confidence.CONFIDENCE_DEFAULT_VALUE ) || ( value < getOptions().getMinConfidenceValue() ) ) { - // return; - // } - // conf_str = FORMATTER_CONFIDENCE.format( value ); - // } - // else if ( confidences.size() > 1 ) { - boolean one_ok = false; boolean not_first = false; Collections.sort( confidences ); final StringBuilder sb = new StringBuilder(); - String conf_str = ""; for( final Confidence confidence : confidences ) { final double value = confidence.getValue(); if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) { - if ( value >= getOptions().getMinConfidenceValue() ) { - one_ok = true; + if ( value < getOptions().getMinConfidenceValue() ) { + return; } if ( not_first ) { sb.append( "/" ); @@ -3694,12 +3954,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } } - //} - if ( one_ok ) { - conf_str = sb.toString(); - } } - if ( conf_str.length() > 0 ) { + if ( sb.length() > 0 ) { final double parent_x = node.getParent().getXcoord(); double x = node.getXcoord(); g.setFont( getTreeFontSet().getSmallFont() ); @@ -3715,6 +3971,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getConfidenceColor() ); } + final String conf_str = sb.toString(); TreePanel .drawString( conf_str, parent_x @@ -3724,13 +3981,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final private void paintFoundNode( final int x, final int y, final Graphics2D g ) { - final int box_size = getOptions().getDefaultNodeShapeSize(); - final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2; - g.setColor( getTreeColorSet().getFoundColor() ); - g.fillRect( x - half_box_size, y - half_box_size, box_size, box_size ); - } - final private void paintGainedAndLostCharacters( final Graphics2D g, final PhylogenyNode node, final String gained, @@ -3769,27 +4019,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final PhylogenyNode node, final Graphics2D g, final boolean to_pdf, - final boolean to_graphics_file, - final boolean is_in_found_nodes ) { + final boolean to_graphics_file ) { if ( node.isCollapse() ) { return; } // if this node should be highlighted, do so if ( ( _highlight_node == node ) && !to_pdf && !to_graphics_file ) { - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getTreeColorSet().getFoundColor0() ); drawOval( x - 8, y - 8, 16, 16, g ); drawOval( x - 9, y - 8, 17, 17, g ); drawOval( x - 9, y - 9, 18, 18, g ); } - if ( is_in_found_nodes ) { - paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g ); - } - else { + if ( ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) + || ( getOptions().isShowDefaultNodeShapesExternal() && node.isExternal() ) + || ( getOptions().isShowDefaultNodeShapesInternal() && node.isInternal() ) + || ( getControlPanel().isEvents() && node.isHasAssignedEvent() && ( node.getNodeData().getEvent() + .isDuplication() + || node.getNodeData().getEvent().isSpeciation() || node.getNodeData().getEvent() + .isSpeciationOrDuplication() ) ) ) { + final double box_size = getOptions().getDefaultNodeShapeSize(); + final double half_box_size = box_size / 2.0; Color outline_color = null; if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { outline_color = Color.BLACK; } - else if ( getControlPanel().isEvents() && AptxUtil.isHasAssignedEvent( node ) ) { + else if ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) { + outline_color = getColorForFoundNode( node ); + } + else if ( getControlPanel().isEvents() && TreePanelUtil.isHasAssignedEvent( node ) ) { final Event event = node.getNodeData().getEvent(); if ( event.isDuplication() ) { outline_color = getTreeColorSet().getDuplicationBoxColor(); @@ -3801,79 +4058,58 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee outline_color = getTreeColorSet().getDuplicationOrSpeciationColor(); } } - else if ( getOptions().isTaxonomyColorizeNodeShapes() ) { - outline_color = getTaxonomyBasedColor( node ); - } else { outline_color = getGraphicsForNodeBoxWithColorForParentBranch( node ); if ( to_pdf && ( outline_color == getTreeColorSet().getBranchColor() ) ) { outline_color = getTreeColorSet().getBranchColorForPdf(); } } - final int box_size = getOptions().getDefaultNodeShapeSize(); - final int half_box_size = box_size / 2; - if ( ( getOptions().isShowDefaultNodeShapesExternal() && node.isExternal() ) - || ( getOptions().isShowDefaultNodeShapesInternal() && node.isInternal() ) - || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) { - if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) { - if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { - drawOvalGradient( x - half_box_size, - y - half_box_size, - box_size, - box_size, - g, - to_pdf ? Color.WHITE : outline_color, - to_pdf ? outline_color : getBackground(), - outline_color ); - } - else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) { - Color background = getBackground(); - if ( to_pdf ) { - background = Color.WHITE; - } - drawOvalGradient( x - half_box_size, - y - half_box_size, - box_size, - box_size, - g, - background, - background, - outline_color ); - } - else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { - g.setColor( outline_color ); - drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); - } + if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) { + if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { + drawOvalGradient( x - half_box_size, y - half_box_size, box_size, box_size, g, to_pdf ? Color.WHITE + : outline_color, to_pdf ? outline_color : getBackground(), outline_color ); } - else if ( getOptions().getDefaultNodeShape() == NodeVisualization.NodeShape.RECTANGLE ) { - if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.GRADIENT ) { - drawRectGradient( x - half_box_size, - y - half_box_size, - box_size, - box_size, - g, - to_pdf ? Color.WHITE : outline_color, - to_pdf ? outline_color : getBackground(), - outline_color ); - } - else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) { - Color background = getBackground(); - if ( to_pdf ) { - background = Color.WHITE; - } - drawRectGradient( x - half_box_size, - y - half_box_size, - box_size, - box_size, - g, - background, - background, - outline_color ); + else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) { + Color background = getBackground(); + if ( to_pdf ) { + background = Color.WHITE; } - else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { - g.setColor( outline_color ); - drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); + drawOvalGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + background, + background, + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) { + g.setColor( outline_color ); + drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); + } + } + else if ( getOptions().getDefaultNodeShape() == NodeVisualData.NodeShape.RECTANGLE ) { + if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.GRADIENT ) { + drawRectGradient( x - half_box_size, y - half_box_size, box_size, box_size, g, to_pdf ? Color.WHITE + : outline_color, to_pdf ? outline_color : getBackground(), outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.NONE ) { + Color background = getBackground(); + if ( to_pdf ) { + background = Color.WHITE; } + drawRectGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + background, + background, + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) { + g.setColor( outline_color ); + drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); } } } @@ -3896,6 +4132,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) { return; } + _sb.setLength( 0 ); int x = 0; final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2; if ( getControlPanel().isShowTaxonomyImages() @@ -3914,7 +4151,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( Color.BLACK ); } else if ( is_in_found_nodes ) { - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getColorForFoundNode( node ) ); + } + else if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null ) + && ( node.getNodeData().getNodeVisualData().getFontColor() != null ) ) { + g.setColor( node.getNodeData().getNodeVisualData().getFontColor() ); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { g.setColor( getTaxonomyBasedColor( node ) ); @@ -3924,7 +4165,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) { g.setColor( calculateColorForAnnotation( node.getNodeData().getSequence().getAnnotations() ) ); } - else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches() + else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { g.setColor( PhylogenyMethods.getBranchColorValue( node ) ); } @@ -3934,11 +4175,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getSequenceColor() ); } - _sb.setLength( 0 ); if ( node.isCollapse() && ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) ) { - _sb.append( " [" ); - _sb.append( node.getAllExternalDescendants().size() ); - _sb.append( "]" ); + if ( _sb.length() > 0 ) { + _sb.setLength( 0 ); + _sb.append( "(" ); + _sb.append( node.getAllExternalDescendants().size() ); + _sb.append( ")" ); + } + } + else { + _sb.setLength( 0 ); } if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) { if ( _sb.length() > 0 ) { @@ -3947,13 +4193,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sb.append( node.getName() ); } if ( node.getNodeData().isHasSequence() ) { - if ( getControlPanel().isShowGeneSymbols() && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) { + if ( getControlPanel().isShowSeqSymbols() && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) { if ( _sb.length() > 0 ) { _sb.append( " " ); } _sb.append( node.getNodeData().getSequence().getSymbol() ); } - if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { + if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getGeneName().length() > 0 ) ) { + if ( _sb.length() > 0 ) { + _sb.append( " " ); + } + _sb.append( node.getNodeData().getSequence().getGeneName() ); + } + if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { if ( _sb.length() > 0 ) { _sb.append( " " ); } @@ -3976,7 +4228,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } _sb.append( propertiesToString( node ) ); } - g.setFont( getTreeFontSet().getLargeFont() ); + if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null ) ) { + final Font f = node.getNodeData().getNodeVisualData().getFont(); + g.setFont( f != null ? f : getTreeFontSet().getLargeFont() ); + } + else { + g.setFont( getTreeFontSet().getLargeFont() ); + } if ( is_in_found_nodes ) { g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) ); } @@ -4066,7 +4324,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getControlPanel().isColorAccordingToAnnotation() ) { g.setColor( calculateColorForAnnotation( ann ) ); } - final String ann_str = createAnnotationString( ann ); + final String ann_str = TreePanelUtil.createAnnotationString( ann, getOptions().isShowAnnotationRefSource() ); TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g ); _sb.setLength( 0 ); @@ -4122,7 +4380,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( Color.BLACK ); } else if ( is_in_found_nodes ) { - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getColorForFoundNode( node ) ); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { g.setColor( getTaxonomyBasedColor( node ) ); @@ -4197,7 +4455,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } _sb.append( node.getNodeData().getSequence().getAccession().getValue() ); } - if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { + if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { if ( _sb.length() > 0 ) { _sb.append( " " ); } @@ -4248,14 +4506,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private void paintNodeLite( final Graphics2D g, final PhylogenyNode node ) { if ( node.isCollapse() ) { - if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) { + if ( !node.isRoot() && !node.getParent().isCollapse() ) { paintCollapsedNode( g, node, false, false, false ); } return; } if ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) { - g.setColor( getTreeColorSet().getFoundColor() ); - drawRectFilled( node.getXSecondary() - 1, node.getYSecondary() - 1, 3, 3, g ); + g.setColor( getColorForFoundNode( node ) ); + drawRectFilled( node.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, node.getYSecondary() + - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, OVERVIEW_FOUND_NODE_BOX_SIZE, OVERVIEW_FOUND_NODE_BOX_SIZE, g ); } float new_x = 0; if ( !node.isExternal() && !node.isCollapse() ) { @@ -4302,7 +4561,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_graphics_file ) { final boolean is_in_found_nodes = isInFoundNodes( node ) || isInCurrentExternalNodes( node ); if ( node.isCollapse() ) { - if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) { + if ( ( !node.isRoot() && !node.getParent().isCollapse() ) ) { paintCollapsedNode( g, node, to_graphics_file, to_pdf, is_in_found_nodes ); } return; @@ -4382,8 +4641,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee child_node.setYcoord( y2 ); y2 += _y_distance * child_node.getNumberOfExternalNodes(); } - paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) - || isInCurrentExternalNodes( node ) ); + paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file ); } if ( dynamically_hide && !is_in_found_nodes @@ -4440,22 +4698,35 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( node.getNodeData().isHasSequence() ) { - if ( getControlPanel().isShowGeneNames() + if ( getControlPanel().isShowSeqNames() && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) ) { x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + " " ); } - if ( getControlPanel().isShowGeneSymbols() + if ( getControlPanel().isShowSeqSymbols() && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) ) { x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol() + " " ); } + if ( getControlPanel().isShowGeneNames() + && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) ) { + x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getGeneName() + + " " ); + } if ( getControlPanel().isShowSequenceAcc() && ( node.getNodeData().getSequence().getAccession() != null ) ) { x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence() .getAccession().toString() + " " ); } + if ( getControlPanel().isShowAnnotation() + && ( node.getNodeData().getSequence().getAnnotations() != null ) + && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) { + x += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node + .getNodeData().getSequence().getAnnotations(), getOptions() + .isShowAnnotationRefSource() ) + + " " ); + } } if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) { x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " ); @@ -4489,16 +4760,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void paintOvRectangle( final Graphics2D g ) { - final float w_ratio = ( float ) getWidth() / getVisibleRect().width; - final float h_ratio = ( float ) getHeight() / getVisibleRect().height; - final float x_ratio = ( float ) getWidth() / getVisibleRect().x; - final float y_ratio = ( float ) getHeight() / getVisibleRect().y; + final float w_ratio = ( ( float ) getWidth() ) / getVisibleRect().width; + final float h_ratio = ( ( float ) getHeight() ) / getVisibleRect().height; + final float x_ratio = ( ( float ) getWidth() ) / getVisibleRect().x; + final float y_ratio = ( ( float ) getHeight() ) / getVisibleRect().y; final float width = getOvMaxWidth() / w_ratio; final float height = getOvMaxHeight() / h_ratio; final float x = getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / x_ratio ); final float y = getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / y_ratio ); - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getTreeColorSet().getFoundColor0() ); getOvRectangle().setRect( x, y, width, height ); + final Stroke s = g.getStroke(); + g.setStroke( STROKE_1 ); if ( ( width < 6 ) && ( height < 6 ) ) { drawRectFilled( x, y, 6, 6, g ); getOvVirtualRectangle().setRect( x, y, 6, 6 ); @@ -4518,6 +4791,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } getOvVirtualRectangle().setRect( x, y, width, height ); } + g.setStroke( s ); } final private void paintPhylogenyLite( final Graphics2D g ) { @@ -4526,9 +4800,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .setXSecondary( ( float ) ( getVisibleRect().x + getOvXPosition() + ( MOVE / ( getVisibleRect().width / getOvRectangle() .getWidth() ) ) ) ); _phylogeny.getRoot().setYSecondary( ( getVisibleRect().y + getOvYStart() ) ); + final Stroke s = g.getStroke(); + g.setStroke( STROKE_05 ); for( final PhylogenyNode element : _nodes_in_preorder ) { paintNodeLite( g, element ); } + g.setStroke( s ); paintOvRectangle( g ); } @@ -4560,7 +4837,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final double w = PhylogenyMethods.getBranchWidthValue( root ); drawRectFilled( x1 - d, root.getYcoord() - ( w / 2 ), d, w, g ); } - paintNodeBox( x1, root.getYcoord(), root, g, to_pdf, to_graphics_file, isInFoundNodes( root ) ); + paintNodeBox( x1, root.getYcoord(), root, g, to_pdf, to_graphics_file ); } final private void paintScale( final Graphics2D g, @@ -4580,12 +4857,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getBranchLengthColor() ); } + final Stroke s = g.getStroke(); + g.setStroke( STROKE_1 ); drawLine( x1, y1, x1, y2, g ); drawLine( x2, y1, x2, y2, g ); drawLine( x1, y3, x2, y3, g ); if ( getScaleLabel() != null ) { g.drawString( getScaleLabel(), ( x1 + 2 ), y3 - 2 ); } + g.setStroke( s ); } final private int paintTaxonomy( final Graphics2D g, @@ -4601,12 +4881,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else if ( is_in_found_nodes ) { g.setFont( getTreeFontSet().getLargeItalicFont().deriveFont( TreeFontSet.BOLD_AND_ITALIC ) ); - g.setColor( getTreeColorSet().getFoundColor() ); + g.setColor( getColorForFoundNode( node ) ); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { g.setColor( getTaxonomyBasedColor( node ) ); } - else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches() + else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { g.setColor( PhylogenyMethods.getBranchColorValue( node ) ); } @@ -4759,11 +5039,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee current_angle += arc_size; assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file ); drawLine( x, y, new_x, new_y, g ); - paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) - || isInCurrentExternalNodes( desc ) ); + paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file ); } if ( n.isRoot() ) { - paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) ); + paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file ); } } @@ -4807,8 +5086,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee desc.setXSecondary( new_x ); desc.setYSecondary( new_y ); if ( isInFoundNodes( desc ) || isInCurrentExternalNodes( desc ) ) { - g.setColor( getTreeColorSet().getFoundColor() ); - drawRectFilled( desc.getXSecondary() - 1, desc.getYSecondary() - 1, 3, 3, g ); + g.setColor( getColorForFoundNode( desc ) ); + drawRectFilled( desc.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, + desc.getYSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, + OVERVIEW_FOUND_NODE_BOX_SIZE, + OVERVIEW_FOUND_NODE_BOX_SIZE, + g ); g.setColor( getTreeColorSet().getOvColor() ); } paintUnrootedLite( desc, current_angle, current_angle + arc_size, g, urt_ov_factor ); @@ -4871,10 +5154,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( getCopiedAndPastedNodes() == null ) { - setCopiedAndPastedNodes( new HashSet() ); + setCopiedAndPastedNodes( new HashSet() ); } final List nodes = PhylogenyMethods.obtainAllNodesAsList( buffer_phy ); - final Set node_ids = new HashSet( nodes.size() ); + final Set node_ids = new HashSet( nodes.size() ); for( final PhylogenyNode n : nodes ) { node_ids.add( n.getId() ); } @@ -4904,17 +5187,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee sb.append( " " ); } final Property p = properties.getProperty( ref ); - sb.append( getPartAfterColon( p.getRef() ) ); + sb.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); sb.append( "=" ); sb.append( p.getValue() ); if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - sb.append( getPartAfterColon( p.getUnit() ) ); + sb.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); } } return sb; } - final private void setCopiedAndPastedNodes( final Set nodeIds ) { + final private void setCopiedAndPastedNodes( final Set nodeIds ) { getMainPanel().setCopiedAndPastedNodes( nodeIds ); } @@ -4966,6 +5249,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _scale_label = scale_label; } + private final void setupStroke( final Graphics2D g ) { + if ( getYdistance() < 0.001 ) { + g.setStroke( STROKE_005 ); + } + else if ( getYdistance() < 0.01 ) { + g.setStroke( STROKE_01 ); + } + else if ( getYdistance() < 0.5 ) { + g.setStroke( STROKE_025 ); + } + else if ( getYdistance() < 1 ) { + g.setStroke( STROKE_05 ); + } + else if ( getYdistance() < 2 ) { + g.setStroke( STROKE_075 ); + } + else if ( getYdistance() < 20 ) { + g.setStroke( STROKE_1 ); + } + else { + g.setStroke( STROKE_2 ); + } + } + final private void setUpUrtFactor() { final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width : getVisibleRect().height; @@ -4994,7 +5301,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private void showExtDescNodeData( final PhylogenyNode node ) { final List data = new ArrayList(); - for( final PhylogenyNode n : node.getAllExternalDescendants() ) { + final List nodes = node.getAllExternalDescendants(); + if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) { + for( final PhylogenyNode n : getFoundNodesAsListOfPhylogenyNodes() ) { + if ( !nodes.contains( n ) ) { + nodes.add( n ); + } + } + } + for( final PhylogenyNode n : nodes ) { switch ( getOptions().getExtDescNodeDataToReturn() ) { case NODE_NAME: if ( !ForesterUtil.isEmpty( n.getName() ) ) { @@ -5007,6 +5322,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee data.add( n.getNodeData().getSequence().getName() ); } break; + case GENE_NAME: + if ( n.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) { + data.add( n.getNodeData().getSequence().getGeneName() ); + } + break; case SEQUENCE_SYMBOL: if ( n.getNodeData().isHasSequence() && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { @@ -5019,6 +5340,59 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee data.add( n.getNodeData().getSequence().getMolecularSequence() ); } break; + case SEQUENCE_MOL_SEQ_FASTA: + final StringBuilder sb = new StringBuilder(); + if ( n.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) { + final StringBuilder ann = new StringBuilder(); + if ( !ForesterUtil.isEmpty( n.getName() ) ) { + ann.append( n.getName() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { + ann.append( "SYM=" ); + ann.append( n.getNodeData().getSequence().getSymbol() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) { + ann.append( "NAME=" ); + ann.append( n.getNodeData().getSequence().getName() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) { + ann.append( "GN=" ); + ann.append( n.getNodeData().getSequence().getGeneName() ); + ann.append( "|" ); + } + if ( n.getNodeData().getSequence().getAccession() != null ) { + ann.append( "ACC=" ); + ann.append( n.getNodeData().getSequence().getAccession().asText() ); + ann.append( "|" ); + } + if ( n.getNodeData().isHasTaxonomy() ) { + if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + ann.append( "TAXID=" ); + ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { + ann.append( "SN=" ); + ann.append( n.getNodeData().getTaxonomy().getScientificName() ); + ann.append( "|" ); + } + } + String ann_str; + if ( ann.charAt( ann.length() - 1 ) == '|' ) { + ann_str = ann.substring( 0, ann.length() - 1 ); + } + else { + ann_str = ann.toString(); + } + sb.append( SequenceWriter.toFasta( ann_str, n.getNodeData().getSequence() + .getMolecularSequence(), 60 ) ); + data.add( sb.toString() ); + } + break; case SEQUENCE_ACC: if ( n.getNodeData().isHasSequence() && ( n.getNodeData().getSequence().getAccession() != null ) && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getAccession().toString() ) ) { @@ -5031,6 +5405,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee data.add( n.getNodeData().getTaxonomy().getScientificName() ); } break; + case TAXONOMY_COMM0N_NAME: + if ( n.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) { + data.add( n.getNodeData().getTaxonomy().getCommonName() ); + } + break; case TAXONOMY_CODE: if ( n.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { @@ -5038,24 +5418,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } break; case UNKNOWN: - AptxUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data ); + TreePanelUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data ); break; default: throw new IllegalArgumentException( "unknown data element: " + getOptions().getExtDescNodeDataToReturn() ); } } // for loop + final StringBuilder sb = new StringBuilder(); + final int size = TreePanelUtil.makeSB( data, getOptions(), sb ); if ( ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) || ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.BUFFER_ONLY ) ) { - final StringBuilder sb = new StringBuilder(); - for( final String d : data ) { - if ( !ForesterUtil.isEmpty( d ) ) { - if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) { - System.out.println( d ); - } - sb.append( d ); - sb.append( ForesterUtil.LINE_SEPARATOR ); - } + if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) { + System.out.println( sb ); } if ( sb.length() < 1 ) { clearCurrentExternalNodesDataBuffer(); @@ -5065,25 +5440,33 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) { - final StringBuilder sb = new StringBuilder(); - for( final String d : data ) { - if ( !ForesterUtil.isEmpty( d ) ) { - sb.append( d ); - sb.append( ForesterUtil.LINE_SEPARATOR ); - } - } if ( sb.length() < 1 ) { - AptxUtil.showInformationMessage( this, - "No Appropriate Data (" + obtainTitleForExtDescNodeData() + ")", - "Descendants of selected node do not contain selected data" ); + TreePanelUtil.showInformationMessage( this, "No Appropriate Data (" + obtainTitleForExtDescNodeData() + + ")", "Descendants of selected node do not contain selected data" ); clearCurrentExternalNodesDataBuffer(); } else { setCurrentExternalNodesDataBuffer( sb ); - final String title = "External Descendants " - + ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" - : obtainTitleForExtDescNodeData() ) + " (" + data.size() + "/" - + node.getNumberOfExternalNodes() + ") For Node " + node; + String title; + if ( ( getFoundNodes0() != null ) && !getFoundNodes0().isEmpty() ) { + title = ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" + : obtainTitleForExtDescNodeData() ) + + " for " + + data.size() + + " nodes, unique entries: " + + size; + } + else { + title = ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" + : obtainTitleForExtDescNodeData() ) + + " for " + + data.size() + + "/" + + node.getNumberOfExternalNodes() + + " external descendats of node " + + node + + ", unique entries: " + size; + } final String s = sb.toString().trim(); if ( getMainPanel().getMainFrame() == null ) { // Must be "E" applet version. @@ -5100,17 +5483,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) { try { if ( ( node.getName().length() > 0 ) - || ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) - || ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) ) - || ( node.getNodeData().isHasDate() ) || ( node.getNodeData().isHasDistribution() ) - || node.getBranchData().isHasConfidences() ) { + || ( node.getNodeData().isHasTaxonomy() && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData() + .getTaxonomy() ) ) + || ( node.getNodeData().isHasSequence() && !TreePanelUtil.isSequenceEmpty( node.getNodeData() + .getSequence() ) ) || ( node.getNodeData().isHasDate() ) + || ( node.getNodeData().isHasDistribution() ) || node.getBranchData().isHasConfidences() ) { _popup_buffer.setLength( 0 ); short lines = 0; if ( node.getName().length() > 0 ) { lines++; _popup_buffer.append( node.getName() ); } - if ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) { + if ( node.getNodeData().isHasTaxonomy() + && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) { lines++; boolean enc_data = false; final Taxonomy tax = node.getNodeData().getTaxonomy(); @@ -5192,7 +5577,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } } - if ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) ) { + if ( node.getNodeData().isHasSequence() + && !TreePanelUtil.isSequenceEmpty( node.getNodeData().getSequence() ) ) { lines++; boolean enc_data = false; if ( _popup_buffer.length() > 0 ) { @@ -5220,6 +5606,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _popup_buffer.append( "]" ); enc_data = true; } + if ( !ForesterUtil.isEmpty( seq.getGeneName() ) ) { + if ( enc_data ) { + _popup_buffer.append( " [" ); + } + else { + _popup_buffer.append( "[" ); + } + _popup_buffer.append( seq.getGeneName() ); + _popup_buffer.append( "]" ); + enc_data = true; + } if ( !ForesterUtil.isEmpty( seq.getName() ) ) { if ( enc_data ) { _popup_buffer.append( " " ); @@ -5271,11 +5668,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee for( final String ref : properties.getPropertyRefs() ) { _popup_buffer.append( "\n" ); final Property p = properties.getProperty( ref ); - _popup_buffer.append( getPartAfterColon( p.getRef() ) ); + _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); _popup_buffer.append( "=" ); _popup_buffer.append( p.getValue() ); if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - _popup_buffer.append( getPartAfterColon( p.getUnit() ) ); + _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); } } } @@ -5284,8 +5681,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _rollover_popup .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) ); _rollover_popup.setBackground( getTreeColorSet().getBackgroundColor() ); - if ( isInFoundNodes( node ) ) { - _rollover_popup.setForeground( getTreeColorSet().getFoundColor() ); + if ( isInFoundNodes0( node ) && !isInFoundNodes1( node ) ) { + _rollover_popup.setForeground( getTreeColorSet().getFoundColor0() ); + } + else if ( !isInFoundNodes0( node ) && isInFoundNodes1( node ) ) { + _rollover_popup.setForeground( getTreeColorSet().getFoundColor1() ); + } + else if ( isInFoundNodes0( node ) && isInFoundNodes1( node ) ) { + _rollover_popup.setForeground( getTreeColorSet().getFoundColor0and1() ); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { _rollover_popup.setForeground( getTaxonomyBasedColor( node ) ); @@ -5395,70 +5798,67 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final private static void drawString( final int i, final double x, final double y, final Graphics2D g ) { - g.drawString( String.valueOf( i ), ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) ); - } - final private static void drawString( final String str, final double x, final double y, final Graphics2D g ) { g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) ); } - final private static String getPartAfterColon( final String s ) { - final int i = s.indexOf( ':' ); - if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) { - return s; - } - return s.substring( i + 1, s.length() ); - } - - final private static boolean isSequenceEmpty( final Sequence seq ) { - return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() ) - && ForesterUtil.isEmpty( seq.getSymbol() ); - } - - final private static boolean isTaxonomyEmpty( final Taxonomy tax ) { - return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() ) - && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) && tax - .getSynonyms().isEmpty() ); - } - final private static boolean plusPressed( final int key_code ) { return ( ( key_code == KeyEvent.VK_ADD ) || ( key_code == KeyEvent.VK_PLUS ) || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) || ( key_code == KeyEvent.VK_1 ) ); } - final private static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) { - final Phylogeny new_phy = new Phylogeny(); - new_phy.setRooted( true ); - new_phy.setName( source_phy.getName() ); - new_phy.setDescription( source_phy.getDescription() ); - new_phy.setType( source_phy.getType() ); - new_phy.setDistanceUnit( source_phy.getDistanceUnit() ); - new_phy.setConfidence( source_phy.getConfidence() ); - new_phy.setIdentifier( source_phy.getIdentifier() ); - new_phy.setRoot( new_root.copyNodeDataShallow() ); - int i = 0; - for( final PhylogenyNode n : new_root.getDescendants() ) { - new_phy.getRoot().setChildNode( i++, n ); + final private class SubtreeColorizationActionListener implements ActionListener { + + List _additional_nodes = null; + JColorChooser _chooser = null; + PhylogenyNode _node = null; + + SubtreeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) { + _chooser = chooser; + _node = node; + } + + SubtreeColorizationActionListener( final JColorChooser chooser, + final PhylogenyNode node, + final List additional_nodes ) { + _chooser = chooser; + _node = node; + _additional_nodes = additional_nodes; + } + + @Override + public void actionPerformed( final ActionEvent e ) { + final Color c = _chooser.getColor(); + if ( c != null ) { + colorizeSubtree( c, _node, _additional_nodes ); + } } - return new_phy; } - final private class SubtreeColorizationActionListener implements ActionListener { + final private class NodeColorizationActionListener implements ActionListener { - JColorChooser _chooser; - PhylogenyNode _node; + List _additional_nodes = null; + JColorChooser _chooser = null; + PhylogenyNode _node = null; - SubtreeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) { + NodeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) { + _chooser = chooser; + _node = node; + } + + NodeColorizationActionListener( final JColorChooser chooser, + final PhylogenyNode node, + final List additional_nodes ) { _chooser = chooser; _node = node; + _additional_nodes = additional_nodes; } @Override public void actionPerformed( final ActionEvent e ) { final Color c = _chooser.getColor(); if ( c != null ) { - colorizeSubtree( c, _node ); + colorizeNodes( c, _node, _additional_nodes ); } } }