X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Farchaeopteryx%2FTreePanel.java;h=3b3977da6a90ea0cc802dc4c2998626e4726b206;hb=886c0c0a7a7cef72503df9f21762db1dab594362;hp=a20689dafe381bb11136b71dfb88c78e65d9a8ff;hpb=803a2b32992b5944b73c6dfcb80ceb58c09b81c1;p=jalview.git diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanel.java b/forester/java/src/org/forester/archaeopteryx/TreePanel.java index a20689d..3b3977d 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanel.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanel.java @@ -49,6 +49,7 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.font.FontRenderContext; +import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; @@ -68,6 +69,7 @@ import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.text.AttributedString; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; @@ -76,12 +78,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.SortedSet; import javax.swing.BorderFactory; -import javax.swing.JApplet; import javax.swing.JColorChooser; import javax.swing.JDialog; import javax.swing.JMenuItem; @@ -119,8 +122,6 @@ 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; import org.forester.phylogeny.data.ProteinDomain; import org.forester.phylogeny.data.Sequence; import org.forester.phylogeny.data.SequenceRelation; @@ -128,7 +129,6 @@ import org.forester.phylogeny.data.Taxonomy; import org.forester.phylogeny.data.Uri; import org.forester.phylogeny.iterators.PhylogenyNodeIterator; import org.forester.phylogeny.iterators.PreorderTreeIterator; -import org.forester.util.BasicDescriptiveStatistics; import org.forester.util.DescriptiveStatistics; import org.forester.util.ForesterConstants; import org.forester.util.ForesterUtil; @@ -192,127 +192,166 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } } - public final static boolean SPECIAL_DOMAIN_COLORING = true; - 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 final static double OVERVIEW_FOUND_NODE_BOX_SIZE = 2; - private final static double OVERVIEW_FOUND_NODE_BOX_SIZE_HALF = 1; - 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_0025 = new BasicStroke( 0.025f ); - 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 static final String SHOW_ONLY_THIS_CONF_TYPE = null; //TODO remove me - 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 = AptxConstants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP; - private double _domain_structure_width = AptxConstants.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 PhylogenyNode _ext_node_with_longest_txt_info = null; - 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; - 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 int _length_of_longest_text; - private int _longest_domain; + public final static boolean SPECIAL_DOMAIN_COLORING = true; + 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 final static double OVERVIEW_FOUND_NODE_BOX_SIZE = 2; + private final static double OVERVIEW_FOUND_NODE_BOX_SIZE_HALF = 1; + 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_0025 = new BasicStroke( 0.025f ); + 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 BasicStroke STROKE_01_DASHED = new BasicStroke( 0.1f, + BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_ROUND, + 0, + new float[] { + 2.0f }, + 0f ); + private static final BasicStroke STROKE_005_DASHED = new BasicStroke( 0.05f, + BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_ROUND, + 0, + new float[] { + 2.0f }, + 0f ); + private static final BasicStroke STROKE_001_DASHED = new BasicStroke( 0.01f, + BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_ROUND, + 0, + new float[] { + 2.0f }, + 0f ); + private static final double TWO_PI = 2 * Math.PI; + private final static int WIGGLE = 3; + private static final String SHOW_ONLY_THIS_CONF_TYPE = null; //TODO remove me + HashMap _nodeid_dist_to_leaf = new HashMap(); + final private Arc2D _arc = new Arc2D.Double(); + private AffineTransform _at; + private int _clicked_x; + 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 = AptxConstants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP; + private double _domain_structure_width = AptxConstants.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 float _furthest_node_x; + 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 PhylogenyNode _ext_node_with_longest_txt_info = null; + 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 boolean _partition_tree = false; + 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 float _root_x; + private final StringBuilder _sb = new StringBuilder(); + private double _scale_distance = 0.0; + private String _scale_label = 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 int _length_of_longest_text; + private int _longest_domain; + private Map _attributed_string_map = null; + private int _depth_collapse_level = -1; + private int _rank_collapse_level = -1; + + + static { final DecimalFormatSymbols dfs = new DecimalFormatSymbols(); dfs.setDecimalSeparator( '.' ); @@ -348,7 +387,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee init(); // if ( !_phylogeny.isEmpty() ) { _phylogeny.recalculateNumberOfExternalDescendants( true ); - checkForVectorProperties( _phylogeny ); // } setBackground( getTreeColorSet().getBackgroundColor() ); final MouseListener mouse_listener = new MouseListener( this ); @@ -357,8 +395,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee addMouseWheelListener( this ); calculateScaleDistance(); FORMATTER_CONFIDENCE.setMaximumFractionDigits( configuration.getNumberOfDigitsAfterCommaForConfidenceValues() ); - FORMATTER_BRANCH_LENGTH.setMaximumFractionDigits( configuration - .getNumberOfDigitsAfterCommaForBranchLengthValues() ); + FORMATTER_BRANCH_LENGTH + .setMaximumFractionDigits( configuration.getNumberOfDigitsAfterCommaForBranchLengthValues() ); } @Override @@ -417,7 +455,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } } - if ( e.isControlDown() ) { + if ( e.isControlDown() && e.isShiftDown() ) { if ( notches < 0 ) { getTreeFontSet().increaseFontSize(); } @@ -429,6 +467,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee updateOvSizes(); repaint(); } + else if ( e.isShiftDown() && e.isAltDown() ) { + if ( notches < 0 ) { + for( int i = 0; i < ( -notches ); ++i ) { + getControlPanel().zoomInX( AptxConstants.WHEEL_ZOOM_IN_FACTOR, AptxConstants.WHEEL_ZOOM_IN_FACTOR ); + getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + } + else { + for( int i = 0; i < notches; ++i ) { + getControlPanel().zoomOutX( AptxConstants.WHEEL_ZOOM_OUT_FACTOR, + AptxConstants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR ); + getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + } + } else if ( e.isShiftDown() ) { if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) { @@ -488,20 +541,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee @Override final public void paintComponent( final Graphics g ) { - // Dimension currentSize = getSize(); - // if ( offscreenImage == null || !currentSize.equals( offscreenDimension ) ) { - // call the 'java.awt.Component.createImage(...)' method to get an - // image - // offscreenImage = createImage( currentSize.width, currentSize.height ); - // offscreenGraphics = offscreenImage.getGraphics(); - // offscreenDimension = currentSize; - // } - // super.paintComponent( g ); //why? - //final Graphics2D g2d = ( Graphics2D ) offscreenGraphics; final Graphics2D g2d = ( Graphics2D ) g; g2d.setRenderingHints( _rendering_hints ); paintPhylogeny( g2d, false, false, 0, 0, 0, 0 ); - //g.drawImage( offscreenImage, 0, 0, this ); } @Override @@ -632,11 +674,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( Color.BLACK ); } else if ( ( ( action == NodeClickAction.COPY_SUBTREE ) || ( action == NodeClickAction.CUT_SUBTREE ) - || ( action == NodeClickAction.DELETE_NODE_OR_SUBTREE ) || ( action == NodeClickAction.PASTE_SUBTREE ) || ( action == NodeClickAction.ADD_NEW_NODE ) ) - && ( getCutOrCopiedTree() != null ) - && ( getCopiedAndPastedNodes() != null ) - && !to_pdf - && !to_graphics_file && getCopiedAndPastedNodes().contains( node.getId() ) ) { + || ( action == NodeClickAction.DELETE_NODE_OR_SUBTREE ) || ( action == NodeClickAction.PASTE_SUBTREE ) + || ( action == NodeClickAction.ADD_NEW_NODE ) ) && ( getCutOrCopiedTree() != null ) + && ( getCopiedAndPastedNodes() != null ) && !to_pdf && !to_graphics_file + && getCopiedAndPastedNodes().contains( node.getId() ) ) { g.setColor( getTreeColorSet().getFoundColor0() ); } else if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { @@ -674,7 +715,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) { - if ( ForesterUtil.seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() ) ) { + if ( ForesterUtil + .seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() ) ) { type = 'p'; } else { @@ -690,12 +732,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee type = 'n'; } } - JApplet applet = null; - if ( isApplet() ) { - applet = obtainApplet(); - } try { - Blast.openNcbiBlastWeb( query, type == 'n', applet, this ); + Blast.openNcbiBlastWeb( query, type == 'n', this ); } catch ( final Exception e ) { e.printStackTrace(); @@ -716,7 +754,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee nodeTaxonomyDataAsSB( _ext_node_with_longest_txt_info.getNodeData().getTaxonomy(), sb ); } } - return getFontMetricsForLargeDefaultFont().stringWidth( sb.toString() ); } @@ -927,8 +964,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { al = new SubtreeColorizationActionListener( _color_chooser, node ); } - final JDialog dialog = JColorChooser - .createDialog( this, "Subtree colorization", true, _color_chooser, al, null ); + final JDialog dialog = JColorChooser.createDialog( this, + "Subtree colorization", + true, + _color_chooser, + al, + null ); setEdited( true ); dialog.setVisible( true ); } @@ -1076,7 +1117,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.draw( _arc ); } - final private void drawLine( final double x1, final double y1, final double x2, final double y2, final Graphics2D g ) { + final private void drawLine( final double x1, + final double y1, + final double x2, + final double y2, + final Graphics2D g ) { if ( ( x1 == x2 ) && ( y1 == y2 ) ) { return; } @@ -1119,7 +1164,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final private void drawRect( final float x, final float y, final float width, final float heigth, final Graphics2D g ) { + final private void drawRect( final float x, + final float y, + final float width, + final float heigth, + final Graphics2D g ) { _rectangle.setFrame( x, y, width, heigth ); g.draw( _rectangle ); } @@ -1245,17 +1294,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return _last_drag_point_y; } - final private short getMaxBranchesToLeaf( final PhylogenyNode node ) { - if ( !_nodeid_dist_to_leaf.containsKey( node.getId() ) ) { - final short m = PhylogenyMethods.calculateMaxBranchesToLeaf( node ); - _nodeid_dist_to_leaf.put( node.getId(), m ); - return m; - } - else { - return _nodeid_dist_to_leaf.get( node.getId() ); - } - } - final private double getMaxDistanceToRoot() { if ( _max_distance_to_root < 0 ) { recalculateMaxDistanceToRoot(); @@ -1394,7 +1432,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee sortDescendants( node ); break; case GET_EXT_DESC_DATA: - showExtDescNodeData( node ); + showExtDescNodeData( node, '_' ); + break; + case UNCOLLAPSE_ALL: + uncollapseAll( node ); + break; + case ORDER_SUBTREE: + orderSubtree( node ); break; default: throw new IllegalArgumentException( "unknown action: " + action ); @@ -1406,7 +1450,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void increaseOvSize() { - if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) ) + if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() + / 2 ) ) && ( getOvMaxHeight() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect() .getHeight() / 2 ) ) ) { setOvMaxWidth( getOvMaxWidth() + 5 ); @@ -1425,6 +1470,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setTreeFile( null ); setEdited( false ); initializeOvSettings(); + resetDepthCollapseDepthValue(); + resetRankCollapseRankValue(); setStartingAngle( ( TWO_PI * 3 ) / 4 ); final ImageLoader il = new ImageLoader( this ); new Thread( il ).start(); @@ -1438,8 +1485,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private boolean inOvVirtualRectangle( final int x, final int y ) { return ( ( x >= ( getOvVirtualRectangle().x - 1 ) ) && ( x <= ( getOvVirtualRectangle().x + getOvVirtualRectangle().width + 1 ) ) - && ( y >= ( getOvVirtualRectangle().y - 1 ) ) && ( y <= ( getOvVirtualRectangle().y - + getOvVirtualRectangle().height + 1 ) ) ); + && ( y >= ( getOvVirtualRectangle().y - 1 ) ) + && ( y <= ( getOvVirtualRectangle().y + getOvVirtualRectangle().height + 1 ) ) ); } final private boolean inOvVirtualRectangle( final MouseEvent e ) { @@ -1462,12 +1509,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private boolean isCanOpenTaxWeb( final PhylogenyNode node ) { - if ( node.getNodeData().isHasTaxonomy() - && ( ( !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() ) ) ) ) { + if ( node.getNodeData().isHasTaxonomy() && ( ( !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() ) ) ) ) { return true; } else { @@ -1501,25 +1548,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee y_dist = 40 + ( int ) getYdistance(); } return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - y_dist ) ) - || ( node.getYcoord() > ( getVisibleRect().getMaxY() + y_dist ) ) || ( ( node.getParent() != null ) && ( node - .getParent().getXcoord() > getVisibleRect().getMaxX() ) ) ); + || ( node.getYcoord() > ( getVisibleRect().getMaxY() + y_dist ) ) + || ( ( node.getParent() != null ) && ( node.getParent().getXcoord() > getVisibleRect().getMaxX() ) ) ); } final private boolean isNodeDataInvisibleUnrootedCirc( final PhylogenyNode node ) { return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - 20 ) ) || ( node.getYcoord() > ( getVisibleRect().getMaxY() + 20 ) ) - || ( node.getXcoord() < ( getVisibleRect().getMinX() - 20 ) ) || ( node.getXcoord() > ( getVisibleRect() - .getMaxX() + 20 ) ) ); + || ( node.getXcoord() < ( getVisibleRect().getMinX() - 20 ) ) + || ( node.getXcoord() > ( getVisibleRect().getMaxX() + 20 ) ) ); } final private boolean isNonLinedUpCladogram() { return getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP; } - final private boolean isUniformBranchLengthsForCladogram() { - return getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP; - } - final private void keyPressedCalls( final KeyEvent e ) { if ( isOvOn() && ( getMousePosition() != null ) && ( getMousePosition().getLocation() != null ) ) { if ( inOvVirtualRectangle( getMousePosition().x, getMousePosition().y ) ) { @@ -1531,89 +1574,47 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setInOvRect( false ); } } - if ( e.getModifiersEx() == InputEvent.CTRL_DOWN_MASK ) { + if ( e.isAltDown() ) { if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME ) - || ( e.getKeyCode() == KeyEvent.VK_F ) ) { - getMainPanel().getTreeFontSet().mediumFonts(); - getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); + || ( e.getKeyCode() == KeyEvent.VK_C ) || ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE ) ) { + getControlPanel().showWhole(); } - else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) { + else if ( e.isShiftDown() + && ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) ) { getMainPanel().getTreeFontSet().decreaseFontSize( 1, false ); getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); } - else if ( plusPressed( e.getKeyCode() ) ) { + else if ( e.isShiftDown() && plusPressed( e.getKeyCode() ) ) { getMainPanel().getTreeFontSet().increaseFontSize(); getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); } - } - else { - if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME ) - || ( e.getKeyCode() == KeyEvent.VK_F ) ) { - getControlPanel().showWhole(); + else if ( e.getKeyCode() == KeyEvent.VK_O ) { + getControlPanel().orderPressed( this ); } - else if ( ( e.getKeyCode() == KeyEvent.VK_UP ) || ( e.getKeyCode() == KeyEvent.VK_DOWN ) - || ( e.getKeyCode() == KeyEvent.VK_LEFT ) || ( e.getKeyCode() == KeyEvent.VK_RIGHT ) ) { - if ( e.getModifiersEx() == InputEvent.SHIFT_DOWN_MASK ) { - if ( e.getKeyCode() == KeyEvent.VK_UP ) { - getMainPanel().getControlPanel().zoomInY( AptxConstants.WHEEL_ZOOM_IN_FACTOR ); - getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); - } - else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) { - getMainPanel().getControlPanel().zoomOutY( AptxConstants.WHEEL_ZOOM_OUT_FACTOR ); - getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); - } - else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) { - getMainPanel().getControlPanel().zoomOutX( AptxConstants.WHEEL_ZOOM_OUT_FACTOR, - AptxConstants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR ); - getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); - } - else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) { - getMainPanel().getControlPanel().zoomInX( AptxConstants.WHEEL_ZOOM_IN_FACTOR, - AptxConstants.WHEEL_ZOOM_IN_FACTOR ); - getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); - } - } - else { - final int d = 80; - int dx = 0; - int dy = -d; - if ( e.getKeyCode() == KeyEvent.VK_DOWN ) { - dy = d; - } - else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) { - dx = -d; - dy = 0; - } - else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) { - dx = d; - dy = 0; - } - final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition(); - scroll_position.x = scroll_position.x + dx; - scroll_position.y = scroll_position.y + dy; - if ( scroll_position.x <= 0 ) { - scroll_position.x = 0; - } - else { - final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum() - - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount(); - if ( scroll_position.x >= max_x ) { - scroll_position.x = max_x; - } - } - if ( scroll_position.y <= 0 ) { - scroll_position.y = 0; - } - else { - final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum() - - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount(); - if ( scroll_position.y >= max_y ) { - scroll_position.y = max_y; - } - } - repaint(); - getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position ); - } + else if ( e.getKeyCode() == KeyEvent.VK_R ) { + getControlPanel().returnedToSuperTreePressed(); + } + else if ( e.getKeyCode() == KeyEvent.VK_U ) { + getControlPanel().uncollapseAll( this ); + getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + else if ( e.getKeyCode() == KeyEvent.VK_UP ) { + getMainPanel().getControlPanel().zoomInY( AptxConstants.WHEEL_ZOOM_IN_FACTOR ); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) { + getMainPanel().getControlPanel().zoomOutY( AptxConstants.WHEEL_ZOOM_OUT_FACTOR ); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) { + getMainPanel().getControlPanel().zoomOutX( AptxConstants.WHEEL_ZOOM_OUT_FACTOR, + AptxConstants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR ); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); + } + else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) { + getMainPanel().getControlPanel().zoomInX( AptxConstants.WHEEL_ZOOM_IN_FACTOR, + AptxConstants.WHEEL_ZOOM_IN_FACTOR ); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); } else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) { getMainPanel().getControlPanel().zoomOutY( AptxConstants.WHEEL_ZOOM_OUT_FACTOR ); @@ -1627,6 +1628,50 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getMainPanel().getControlPanel().zoomInY( AptxConstants.WHEEL_ZOOM_IN_FACTOR ); getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false ); } + } + else { + if ( ( e.getKeyCode() == KeyEvent.VK_UP ) || ( e.getKeyCode() == KeyEvent.VK_DOWN ) + || ( e.getKeyCode() == KeyEvent.VK_LEFT ) || ( e.getKeyCode() == KeyEvent.VK_RIGHT ) ) { + final int d = 80; + int dx = 0; + int dy = -d; + if ( e.getKeyCode() == KeyEvent.VK_DOWN ) { + dy = d; + } + else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) { + dx = -d; + dy = 0; + } + else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) { + dx = d; + dy = 0; + } + final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition(); + scroll_position.x = scroll_position.x + dx; + scroll_position.y = scroll_position.y + dy; + if ( scroll_position.x <= 0 ) { + scroll_position.x = 0; + } + else { + final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum() + - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount(); + if ( scroll_position.x >= max_x ) { + scroll_position.x = max_x; + } + } + if ( scroll_position.y <= 0 ) { + scroll_position.y = 0; + } + else { + final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum() + - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount(); + if ( scroll_position.y >= max_y ) { + scroll_position.y = max_y; + } + } + repaint(); + getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position ); + } else if ( e.getKeyCode() == KeyEvent.VK_S ) { if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) { @@ -1653,16 +1698,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL ); } - if ( getMainPanel().getMainFrame() == null ) { - // Must be "E" applet version. - final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet(); - if ( ae.getlabelDirectionCbmi() != null ) { - ae.getlabelDirectionCbmi().setSelected( selected ); - } - } - else { - getMainPanel().getMainFrame().getlabelDirectionCbmi().setSelected( selected ); - } + getMainPanel().getMainFrame().getlabelDirectionCbmi().setSelected( selected ); repaint(); } else if ( e.getKeyCode() == KeyEvent.VK_X ) { @@ -1683,8 +1719,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_U ) ) { decreaseOvSize(); } - e.consume(); } + if ( e.getKeyCode() == KeyEvent.VK_HOME || e.getKeyCode() == KeyEvent.VK_ESCAPE ) { + getControlPanel().showWhole(); + } + else if ( e.getKeyCode() == KeyEvent.VK_PAGE_UP ) { + getMainPanel().getTreeFontSet().increaseFontSize(); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); + } + else if ( e.getKeyCode() == KeyEvent.VK_PAGE_DOWN ) { + getMainPanel().getTreeFontSet().decreaseFontSize( 1, false ); + getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true ); + } + e.consume(); } final private void makePopupMenus( final PhylogenyNode node ) { @@ -1801,6 +1848,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( title.equals( Configuration.clickto_options[ Configuration.sort_descendents ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() > 1 ); } + else if ( title.equals( Configuration.clickto_options[ Configuration.uncollapse_all ][ 0 ] ) ) { + _node_popup_menu_items[ i ].setEnabled( isCanUncollapseAll( node ) ); + } _node_popup_menu_items[ i ].addActionListener( this ); _node_popup_menu.add( _node_popup_menu_items[ i ] ); } @@ -1829,7 +1879,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } sb.append( node.getNodeData().getSequence().getGeneName() ); } - if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { + if ( getControlPanel().isShowSeqNames() + && ( node.getNodeData().getSequence().getName().length() > 0 ) ) { if ( sb.length() > 0 ) { sb.append( " " ); } @@ -1857,6 +1908,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } private final void nodeTaxonomyDataAsSB( final Taxonomy taxonomy, final StringBuilder sb ) { + if ( _control_panel.isShowTaxonomyRank() && !ForesterUtil.isEmpty( taxonomy.getRank() ) ) { + sb.append( "[" ); + sb.append( taxonomy.getRank() ); + sb.append( "] " ); + } if ( _control_panel.isShowTaxonomyCode() && !ForesterUtil.isEmpty( taxonomy.getTaxonomyCode() ) ) { sb.append( taxonomy.getTaxonomyCode() ); sb.append( " " ); @@ -1924,10 +1980,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee 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" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), "_aptx_seq" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -1952,10 +2005,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final String uri_str = TreePanelUtil.createUriForSeqWeb( node, getConfiguration(), this ); if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - AptxUtil.launchWebBrowser( new URI( uri_str ), - isApplet(), - isApplet() ? obtainApplet() : null, - "_aptx_seq" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), "_aptx_seq" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -1989,11 +2039,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee e.printStackTrace(); } } - else if ( ( tax.getIdentifier() != null ) - && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) + 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" ) ) ) { + && ( tax.getIdentifier().getProvider().equalsIgnoreCase( "ncbi" ) + || tax.getIdentifier().getProvider().equalsIgnoreCase( "uniprot" ) ) ) { try { uri_str = "http://www.uniprot.org/taxonomy/" + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF_8 ); @@ -2035,10 +2084,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - AptxUtil.launchWebBrowser( new URI( uri_str ), - isApplet(), - isApplet() ? obtainApplet() : null, - "_aptx_tax" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), "_aptx_tax" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -2059,7 +2105,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_pdf, final boolean to_graphics_file ) { g.setFont( getTreeFontSet().getSmallFont() ); - if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { + if ( to_pdf || ( to_graphics_file && getOptions().isPrintBlackAndWhite() ) ) { g.setColor( Color.BLACK ); } else { @@ -2067,21 +2113,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !node.isRoot() ) { if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { - TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), node.getParent() - .getXcoord() + EURO_D, node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), g ); + TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), + node.getParent().getXcoord() + EURO_D, + node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), + g ); } else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { - TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), node.getParent() - .getXcoord() + ROUNDED_D, node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), g ); + TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), + node.getParent().getXcoord() + ROUNDED_D, + node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), + g ); } else { - TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), node.getParent() - .getXcoord() + 3, node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), g ); + TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), + node.getParent().getXcoord() + 3, + node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), + g ); } } else { - TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), 3, node.getYcoord() - - getTreeFontSet().getSmallMaxDescent(), g ); + TreePanel.drawString( FORMATTER_BRANCH_LENGTH.format( node.getDistanceToParent() ), + 3, + node.getYcoord() - getTreeFontSet().getSmallMaxDescent(), + g ); } } @@ -2102,8 +2156,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CURVED ) { final float dx = x2 - x1; final float dy = y2 - y1; - _cubic_curve.setCurve( x1, y1, x1 + ( dx * 0.4f ), y1 + ( dy * 0.2f ), x1 + ( dx * 0.6f ), y1 - + ( dy * 0.8f ), x2, y2 ); + _cubic_curve.setCurve( x1, + y1, + x1 + ( dx * 0.4f ), + y1 + ( dy * 0.2f ), + x1 + ( dx * 0.6f ), + y1 + ( dy * 0.8f ), + x2, + y2 ); ( g ).draw( _cubic_curve ); } else { @@ -2141,8 +2201,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CURVED ) { final float dx = x2 - x1; final float dy = y2 - y1; - _cubic_curve.setCurve( x1, y1, x1 + ( dx * 0.4f ), y1 + ( dy * 0.2f ), x1 + ( dx * 0.6f ), y1 - + ( dy * 0.8f ), x2, y2 ); + _cubic_curve.setCurve( x1, + y1, + x1 + ( dx * 0.4f ), + y1 + ( dy * 0.2f ), + x1 + ( dx * 0.6f ), + y1 + ( dy * 0.8f ), + x2, + y2 ); g.draw( _cubic_curve ); } else { @@ -2152,10 +2218,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( node.isFirstChildNode() || node.isLastChildNode() || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) { - if ( !to_graphics_file - && !to_pdf - && ( ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) && ( y1 < ( getVisibleRect().getMinY() - 20 ) ) ) || ( ( y2 > ( getVisibleRect() - .getMaxY() + 20 ) ) && ( y1 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) ) { + if ( !to_graphics_file && !to_pdf + && ( ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) + && ( y1 < ( getVisibleRect().getMinY() - 20 ) ) ) + || ( ( y2 > ( getVisibleRect().getMaxY() + 20 ) ) + && ( y1 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) ) { // Do nothing. } else { @@ -2188,8 +2255,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } // draw the horizontal line - if ( !to_graphics_file && !to_pdf - && ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) || ( y2 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) { + if ( !to_graphics_file && !to_pdf && ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) + || ( y2 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) { return; } float x1_r = 0; @@ -2323,44 +2390,82 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_graphics_file, final boolean to_pdf, final boolean is_in_found_nodes ) { + //// + //// TODO + //// Color c = null; + int res[] = null; + if ( _found_nodes_0 != null || _found_nodes_1 != null ) { + res = calcFoundNodesInSubtree( node ); + } if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { c = Color.BLACK; } - else if ( is_in_found_nodes ) { - c = getColorForFoundNode( node ); - } - else if ( getControlPanel().isColorAccordingToSequence() ) { - c = getSequenceBasedColor( node ); - } - else if ( getControlPanel().isColorAccordingToTaxonomy() ) { - c = getTaxonomyBasedColor( node ); - } + //TODO + //FIXME + // else if ( is_in_found_nodes ) { + // c = getColorForFoundNode( node ); + // } + // else if ( getControlPanel().isColorAccordingToSequence() ) { + // c = getSequenceBasedColor( node ); + // } + // else if ( getControlPanel().isColorAccordingToTaxonomy() ) { + // c = getTaxonomyBasedColor( node ); + // } else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { c = PhylogenyMethods.getBranchColorValue( node ); } + else if ( to_pdf ) { + g.setColor( getTreeColorSet().getBranchColorForPdf() ); + } else { c = getTreeColorSet().getCollapseFillColor(); } double d = node.getAllExternalDescendants().size(); - if ( d > 1000 ) { - d = ( 3 * _y_distance ) / 3; + float xxx; + double s = 0; + if ( getControlPanel().isDrawPhylogram() ) { + if ( d > 1000 ) { + d = 0.75 * _y_distance; + } + else { + d = 0.25 * Math.log10( d ) * _y_distance; + } + final float half_box_size = 0.5f * getOptions().getDefaultNodeShapeSize(); + if ( d < half_box_size ) { + d = half_box_size; + } + _polygon.reset(); + final float xx = node.getXcoord() - ( getOptions().getDefaultNodeShapeSize() ); + xxx = xx > ( node.getParent().getXcoord() + 1 ) ? xx : node.getParent().getXcoord() + 1; + _polygon.moveTo( xxx, node.getYcoord() + 0.5 ); + _polygon.lineTo( xxx, node.getYcoord() - 0.5 ); + s = _options.isCollapsedWithAverageHeigh() + ? PhylogenyMethods.calculateAverageTreeHeight( node ) * _x_correction_factor : 1; + _polygon.lineTo( node.getXcoord() + s, node.getYcoord() - d ); + _polygon.lineTo( node.getXcoord() + s, node.getYcoord() + d ); + _polygon.closePath(); } else { - d = ( Math.log10( d ) * _y_distance ) / 2.5; - } - 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.moveTo( xxx, node.getYcoord() ); - _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() - d ); - _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() + d ); - _polygon.closePath(); + if ( d > 1000 ) { + d = _y_distance; + } + else { + d = ( Math.log10( d ) * _y_distance ) / 2.5; + } + final int box_size = getOptions().getDefaultNodeShapeSize() + 1; + if ( d < box_size ) { + d = box_size; + } + final float xx = node.getXcoord() - ( 2 * box_size ); + xxx = xx > ( node.getParent().getXcoord() + 1 ) ? xx : node.getParent().getXcoord() + 1; + _polygon.reset(); + _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.fill( _polygon ); @@ -2372,13 +2477,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.draw( _polygon ); } else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { - g.setPaint( new GradientPaint( xxx, node.getYcoord(), getBackground(), node.getXcoord(), ( 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 ); } - paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes ); + paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes, s ); } final private void paintConfidenceValues( final Graphics2D g, @@ -2390,9 +2500,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee Collections.sort( confidences ); final StringBuilder sb = new StringBuilder(); for( final Confidence confidence : confidences ) { - if ( ForesterUtil.isEmpty( SHOW_ONLY_THIS_CONF_TYPE ) - || ( !ForesterUtil.isEmpty( confidence.getType() ) && confidence.getType() - .equalsIgnoreCase( SHOW_ONLY_THIS_CONF_TYPE ) ) ) { + if ( ForesterUtil.isEmpty( SHOW_ONLY_THIS_CONF_TYPE ) || ( !ForesterUtil.isEmpty( confidence.getType() ) + && confidence.getType().equalsIgnoreCase( SHOW_ONLY_THIS_CONF_TYPE ) ) ) { final double value = confidence.getValue(); if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) { if ( value < getOptions().getMinConfidenceValue() ) { @@ -2404,14 +2513,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { not_first = true; } - sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( value, getOptions() - .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); + sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil + .round( value, getOptions().getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); if ( getOptions().isShowConfidenceStddev() ) { if ( confidence.getStandardDeviation() != Confidence.CONFIDENCE_DEFAULT_VALUE ) { sb.append( "(" ); - sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence - .getStandardDeviation(), getOptions() - .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); + sb.append( FORMATTER_CONFIDENCE + .format( ForesterUtil.round( confidence.getStandardDeviation(), + getOptions() + .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); sb.append( ")" ); } } @@ -2428,7 +2538,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { x += ROUNDED_D; } - if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { + if ( to_pdf || ( to_graphics_file && getOptions().isPrintBlackAndWhite() ) ) { g.setColor( Color.BLACK ); } else { @@ -2436,11 +2546,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final String conf_str = sb.toString(); TreePanel.drawString( conf_str, - parent_x - + ( ( x - parent_x - getTreeFontSet().getFontMetricsSmall() - .stringWidth( conf_str ) ) / 2 ), - ( node.getYcoord() + getTreeFontSet().getSmallMaxAscent() ) - 1, - g ); + parent_x + ( ( x - parent_x + - getTreeFontSet().getFontMetricsSmall().stringWidth( conf_str ) ) / 2 ), + ( node.getYcoord() + getTreeFontSet().getSmallMaxAscent() ) - 1, + g ); } } @@ -2456,25 +2565,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( AptxConstants.SPECIAL_CUSTOM ) { g.setColor( Color.BLUE ); } - TreePanel - .drawString( gained, - parent_x - + ( ( x - parent_x - getFontMetricsForLargeDefaultFont().stringWidth( gained ) ) / 2 ), - ( node.getYcoord() - getFontMetricsForLargeDefaultFont().getMaxDescent() ), - g ); + TreePanel.drawString( gained, + parent_x + ( ( x - parent_x + - getFontMetricsForLargeDefaultFont().stringWidth( gained ) ) / 2 ), + ( node.getYcoord() - getFontMetricsForLargeDefaultFont().getMaxDescent() ), + g ); g.setColor( getTreeColorSet().getLostCharactersColor() ); TreePanel - .drawString( lost, - parent_x - + ( ( x - parent_x - getFontMetricsForLargeDefaultFont().stringWidth( lost ) ) / 2 ), - ( node.getYcoord() + getFontMetricsForLargeDefaultFont().getMaxAscent() ), - g ); + .drawString( lost, + parent_x + ( ( x - parent_x - getFontMetricsForLargeDefaultFont().stringWidth( lost ) ) + / 2 ), + ( node.getYcoord() + getFontMetricsForLargeDefaultFont().getMaxAscent() ), + g ); } } private void paintMolecularSequences( final Graphics2D g, final PhylogenyNode node, final boolean to_pdf ) { - final RenderableMsaSequence rs = RenderableMsaSequence.createInstance( node.getNodeData().getSequence() - .getMolecularSequence(), node.getNodeData().getSequence().getType(), getConfiguration() ); + final RenderableMsaSequence rs = RenderableMsaSequence + .createInstance( node.getNodeData().getSequence().getMolecularSequence(), + node.getNodeData().getSequence().getType(), + getConfiguration() ); if ( rs != null ) { final int default_height = 8; final float y = getYdistance(); @@ -2525,17 +2635,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee || ( getOptions().isShowDefaultNodeShapesExternal() && node.isExternal() ) || ( getOptions().isShowDefaultNodeShapesInternal() && node.isInternal() ) || ( getOptions().isShowDefaultNodeShapesForMarkedNodes() - && ( node.getNodeData().getNodeVisualData() != null ) && ( !node.getNodeData() - .getNodeVisualData().isEmpty() ) ) - || ( getControlPanel().isUseVisualStyles() && ( ( node.getNodeData().getNodeVisualData() != null ) && ( ( node - .getNodeData().getNodeVisualData().getNodeColor() != null ) - || ( node.getNodeData().getNodeVisualData().getSize() != NodeVisualData.DEFAULT_SIZE ) - || ( node.getNodeData().getNodeVisualData().getFillType() != NodeFill.DEFAULT ) || ( node - .getNodeData().getNodeVisualData().getShape() != NodeShape.DEFAULT ) ) ) ) - || ( getControlPanel().isEvents() && node.isHasAssignedEvent() && ( node.getNodeData().getEvent() - .isDuplication() - || node.getNodeData().getEvent().isSpeciation() || node.getNodeData().getEvent() - .isSpeciationOrDuplication() ) ) ) { + && ( node.getNodeData().getNodeVisualData() != null ) + && ( !node.getNodeData().getNodeVisualData().isEmpty() ) ) + || ( getControlPanel().isUseVisualStyles() && ( ( node.getNodeData().getNodeVisualData() != null ) + && ( ( node.getNodeData().getNodeVisualData().getNodeColor() != null ) + || ( node.getNodeData().getNodeVisualData().getSize() != NodeVisualData.DEFAULT_SIZE ) + || ( node.getNodeData().getNodeVisualData().getFillType() != NodeFill.DEFAULT ) + || ( node.getNodeData().getNodeVisualData().getShape() != NodeShape.DEFAULT ) ) ) ) + || ( getControlPanel().isEvents() && node.isHasAssignedEvent() + && ( node.getNodeData().getEvent().isDuplication() + || node.getNodeData().getEvent().isSpeciation() + || node.getNodeData().getEvent().isSpeciationOrDuplication() ) ) ) { NodeVisualData vis = null; if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null ) && ( !node.getNodeData().getNodeVisualData().isEmpty() ) ) { @@ -2625,8 +2735,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( shape == NodeShape.CIRCLE ) { if ( fill == 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 ); + 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 ( fill == NodeFill.NONE ) { Color background = getBackground(); @@ -2654,8 +2770,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else if ( shape == NodeVisualData.NodeShape.RECTANGLE ) { if ( fill == 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 ); + 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 ( fill == NodeVisualData.NodeFill.NONE ) { Color background = getBackground(); @@ -2688,53 +2810,123 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final PhylogenyNode node, final boolean to_graphics_file, final boolean to_pdf, - final boolean is_in_found_nodes ) { + final boolean is_in_found_nodes, + final double add ) { if ( isNodeDataInvisible( node ) && !to_graphics_file && !to_pdf ) { return 0; } if ( getControlPanel().isWriteBranchLengthValues() && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) - || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) ) - && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) { + || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) + || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) ) + && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) { paintBranchLength( g, node, to_pdf, to_graphics_file ); } if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) { return 0; } + if ( !getControlPanel().isShowExternalData() && ( node.isExternal() || node.isCollapse() ) ) { + return 0; + } _sb.setLength( 0 ); int x = 0; + if ( add > 0 ) { + x += add; + } final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2; - if ( getControlPanel().isShowTaxonomyImages() - && ( getImageMap() != null ) - && !getImageMap().isEmpty() - && node.getNodeData().isHasTaxonomy() - && ( ( node.getNodeData().getTaxonomy().getUris() != null ) && !node.getNodeData().getTaxonomy() - .getUris().isEmpty() ) ) { + if ( getControlPanel().isShowTaxonomyImages() && ( getImageMap() != null ) && !getImageMap().isEmpty() + && node.getNodeData().isHasTaxonomy() && ( ( node.getNodeData().getTaxonomy().getUris() != null ) + && !node.getNodeData().getTaxonomy().getUris().isEmpty() ) ) { x += drawTaxonomyImage( node.getXcoord() + 2 + half_box_size, node.getYcoord(), node, g ); } - if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel() - .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) { + if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() + || getControlPanel().isShowTaxonomyCommonNames() || getControlPanel().isShowTaxonomyRank() ) + && node.getNodeData().isHasTaxonomy() ) { x += paintTaxonomy( g, node, is_in_found_nodes, to_pdf, to_graphics_file, x ); } setColor( g, node, to_graphics_file, to_pdf, is_in_found_nodes, getTreeColorSet().getSequenceColor() ); + final boolean saw_species = _sb.length() > 0; + _sb.setLength( 0 ); + nodeDataAsSB( node, _sb ); if ( node.isCollapse() && ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) ) { - if ( _sb.length() > 0 ) { - _sb.setLength( 0 ); - _sb.append( " (" ); + if ( ( _sb.length() == 0 ) && !saw_species ) { + if ( getOptions().isShowAbbreviatedLabelsForCollapsedNodes() + && ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() + || getControlPanel().isShowSeqNames() || getControlPanel().isShowNodeNames() ) ) { + final PhylogenyNode first = PhylogenyMethods.getFirstExternalNode( node ); + final PhylogenyNode last = PhylogenyMethods.getLastExternalNode( node ); + if ( getControlPanel().isShowTaxonomyCode() && first.getNodeData().isHasTaxonomy() + && last.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( first.getNodeData().getTaxonomy().getTaxonomyCode() ) + && !ForesterUtil.isEmpty( last.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + addLabelForCollapsed( first.getNodeData().getTaxonomy().getTaxonomyCode(), + last.getNodeData().getTaxonomy().getTaxonomyCode(), + node.getAllExternalDescendants().size(), + node ); + } + else if ( getControlPanel().isShowTaxonomyScientificNames() && first.getNodeData().isHasTaxonomy() + && last.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( first.getNodeData().getTaxonomy().getScientificName() ) + && !ForesterUtil.isEmpty( last.getNodeData().getTaxonomy().getScientificName() ) ) { + addLabelForCollapsed( first.getNodeData().getTaxonomy().getScientificName(), + last.getNodeData().getTaxonomy().getScientificName(), + node.getAllExternalDescendants().size(), + node ); + } + else if ( getControlPanel().isShowSeqNames() && first.getNodeData().isHasSequence() + && last.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( first.getNodeData().getSequence().getName() ) + && !ForesterUtil.isEmpty( last.getNodeData().getSequence().getName() ) ) { + addLabelForCollapsed( first.getNodeData().getSequence().getName(), + last.getNodeData().getSequence().getName(), + node.getAllExternalDescendants().size(), + node ); + } + else if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( first.getName() ) + && !ForesterUtil.isEmpty( last.getName() ) ) { + addLabelForCollapsed( first.getName(), + last.getName(), + node.getAllExternalDescendants().size(), + node ); + } + } + } + else if ( ( _sb.length() > 0 ) || saw_species ) { + // _sb.setLength( 0 ); + _sb.append( " [" ); _sb.append( node.getAllExternalDescendants().size() ); - _sb.append( ")" ); + _sb.append( "]" ); + if ( _found_nodes_0 != null || _found_nodes_1 != null ) { + int[] res = calcFoundNodesInSubtree( node ); + if ( res[ 0 ] > 0 ) { + _sb.append( " [" ); + _sb.append( res[ 0 ] ); + _sb.append( "/" ); + _sb.append( res[ 1 ] ); + _sb.append( "]" ); + } + } } } else { - _sb.setLength( 0 ); + // _sb.setLength( 0 ); } - nodeDataAsSB( node, _sb ); + // nodeDataAsSB( node, _sb ); final boolean using_visual_font = setFont( g, node, is_in_found_nodes ); float down_shift_factor = 3.0f; if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) { down_shift_factor = 1; } - final float pos_x = node.getXcoord() + x + 2 + half_box_size; + float pos_x; + if ( getControlPanel().getTreeDisplayType() == Options.PHYLOGENY_DISPLAY_TYPE.ALIGNED_PHYLOGRAM + && ( node.isExternal() || node.isCollapse() ) ) { + pos_x = ( float ) ( ( getMaxDistanceToRoot() * getXcorrectionFactor() ) + + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x + ( 2 * TreePanel.MOVE ) + getXdistance() + + 3 ); + } + else { + pos_x = node.getXcoord() + x + 2 + half_box_size; + } float pos_y; if ( !using_visual_font ) { pos_y = ( node.getYcoord() + ( getFontMetricsForLargeDefaultFont().getAscent() / down_shift_factor ) ); @@ -2742,66 +2934,28 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { pos_y = ( node.getYcoord() + ( getFontMetrics( g.getFont() ).getAscent() / down_shift_factor ) ); } + if ( getControlPanel().getTreeDisplayType() == Options.PHYLOGENY_DISPLAY_TYPE.ALIGNED_PHYLOGRAM + && ( node.isExternal() || node.isCollapse() ) ) { + drawConnection( node.getXcoord(), pos_x - x, node.getYcoord(), 5, 20, g, to_pdf ); + if ( node.isCollapse() ) { + pos_x -= add; + } + } final String sb_str = _sb.toString(); // GUILHEM_BEG ______________ if ( _control_panel.isShowSequenceRelations() && node.getNodeData().isHasSequence() && ( _query_sequence != null ) ) { - int nodeTextBoundsWidth = 0; - if ( sb_str.length() > 0 ) { - final Rectangle2D node_text_bounds = new TextLayout( sb_str, g.getFont(), _frc ).getBounds(); //would like to remove this 'new', but how... - nodeTextBoundsWidth = ( int ) node_text_bounds.getWidth(); - } - if ( node.getNodeData().getSequence().equals( _query_sequence ) ) { - if ( nodeTextBoundsWidth > 0 ) { // invert font color and background color to show that this is the query sequence - g.fillRect( ( int ) pos_x - 1, ( int ) pos_y - 8, nodeTextBoundsWidth + 5, 11 ); - g.setColor( getTreeColorSet().getBackgroundColor() ); - } + x = paintSequenceRelation( g, node, x, half_box_size, pos_x, pos_y, sb_str ); + } + // GUILHEM_END _____________ + if ( sb_str.length() > 0 ) { + if ( !isAllowAttributedStrings() ) { + TreePanel.drawString( sb_str, pos_x, pos_y, g ); } else { - final List seqRelations = node.getNodeData().getSequence().getSequenceRelations(); - for( final SequenceRelation seqRelation : seqRelations ) { - final boolean fGotRelationWithQuery = ( seqRelation.getRef0().isEqual( _query_sequence ) || seqRelation - .getRef1().isEqual( _query_sequence ) ) - && seqRelation.getType().equals( getControlPanel().getSequenceRelationTypeBox() - .getSelectedItem() ); - if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query - final double linePosX = node.getXcoord() + 2 + half_box_size; - final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation - .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue() - + ")"; - if ( sConfidence != null ) { - float confidenceX = pos_x; - if ( sb_str.length() > 0 ) { - confidenceX += new TextLayout( sb_str, g.getFont(), _frc ).getBounds().getWidth() - + CONFIDENCE_LEFT_MARGIN; - } - if ( confidenceX > linePosX ) { // let's only display confidence value if we are already displaying at least one of Prot/Gene Name and Taxonomy Code - final int confidenceWidth = ( int ) new TextLayout( sConfidence, g.getFont(), _frc ) - .getBounds().getWidth(); - TreePanel.drawString( sConfidence, confidenceX, pos_y, g ); - x += CONFIDENCE_LEFT_MARGIN + confidenceWidth; - } - } - if ( ( x + nodeTextBoundsWidth ) > 0 ) /* we only underline if there is something displayed */ - { - if ( nodeTextBoundsWidth == 0 ) { - nodeTextBoundsWidth -= 3; /* the gap between taxonomy code and node name should not be underlined if nothing comes after it */ - } - else { - nodeTextBoundsWidth += 2; - } - g.drawLine( ( int ) linePosX + 1, 3 + ( int ) pos_y, ( int ) linePosX + x - + nodeTextBoundsWidth, 3 + ( int ) pos_y ); - break; - } - } - } + drawStringX( sb_str, pos_x, pos_y, g ); } } - if ( sb_str.length() > 0 ) { - TreePanel.drawString( sb_str, pos_x, pos_y, g ); - } - // GUILHEM_END _____________ if ( _sb.length() > 0 ) { if ( !using_visual_font && !is_in_found_nodes ) { x += getFontMetricsForLargeDefaultFont().stringWidth( _sb.toString() ) + 5; @@ -2820,9 +2974,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getControlPanel().isColorAccordingToAnnotation() ) { g.setColor( calculateColorForAnnotation( ann ) ); } - final String ann_str = TreePanelUtil.createAnnotationString( ann, getOptions().isShowAnnotationRefSource() ); - TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord() - + ( getFontMetricsForLargeDefaultFont().getAscent() / down_shift_factor ), g ); + final String ann_str = TreePanelUtil.createAnnotationString( ann, + getOptions().isShowAnnotationRefSource() ); + TreePanel.drawString( ann_str, + node.getXcoord() + x + 3 + half_box_size, + node.getYcoord() + + ( getFontMetricsForLargeDefaultFont().getAscent() / down_shift_factor ), + g ); _sb.setLength( 0 ); _sb.append( ann_str ); if ( _sb.length() > 0 ) { @@ -2847,28 +3005,184 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( getControlPanel().isShowBinaryCharacters() ) { TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer() - .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord() - + ( getFontMetricsForLargeDefaultFont().getAscent() / down_shift_factor ), g ); - paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters() - .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters() - .getLostCharactersAsStringBuffer().toString() ); + .toString(), + node.getXcoord() + x + 1 + half_box_size, + node.getYcoord() + ( getFontMetricsForLargeDefaultFont().getAscent() + / down_shift_factor ), + g ); + paintGainedAndLostCharacters( g, + node, + node.getNodeData().getBinaryCharacters() + .getGainedCharactersAsStringBuffer().toString(), + node.getNodeData().getBinaryCharacters() + .getLostCharactersAsStringBuffer().toString() ); } else { - TreePanel - .drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(), - node.getXcoord() + x + 4 + half_box_size, - node.getYcoord() - + ( getFontMetricsForLargeDefaultFont().getAscent() / down_shift_factor ), - g ); - paintGainedAndLostCharacters( g, node, "+" - + node.getNodeData().getBinaryCharacters().getGainedCount(), "-" - + node.getNodeData().getBinaryCharacters().getLostCount() ); + TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(), + node.getXcoord() + x + 4 + half_box_size, + node.getYcoord() + ( getFontMetricsForLargeDefaultFont().getAscent() + / down_shift_factor ), + g ); + paintGainedAndLostCharacters( g, + node, + "+" + node.getNodeData().getBinaryCharacters().getGainedCount(), + "-" + node.getNodeData().getBinaryCharacters().getLostCount() ); } } } return x; } + private final int paintSequenceRelation( final Graphics2D g, + final PhylogenyNode node, + int x, + final int half_box_size, + final float pos_x, + final float pos_y, + final String sb_str ) { + int nodeTextBoundsWidth = 0; + if ( sb_str.length() > 0 ) { + final Rectangle2D node_text_bounds = new TextLayout( sb_str, g.getFont(), _frc ).getBounds(); //would like to remove this 'new', but how... + nodeTextBoundsWidth = ( int ) node_text_bounds.getWidth(); + } + if ( node.getNodeData().getSequence().equals( _query_sequence ) ) { + if ( nodeTextBoundsWidth > 0 ) { // invert font color and background color to show that this is the query sequence + g.fillRect( ( int ) pos_x - 1, ( int ) pos_y - 8, nodeTextBoundsWidth + 5, 11 ); + g.setColor( getTreeColorSet().getBackgroundColor() ); + } + } + else { + final List seqRelations = node.getNodeData().getSequence().getSequenceRelations(); + for( final SequenceRelation seqRelation : seqRelations ) { + final boolean fGotRelationWithQuery = ( seqRelation.getRef0().isEqual( _query_sequence ) + || seqRelation.getRef1().isEqual( _query_sequence ) ) + && seqRelation.getType() + .equals( getControlPanel().getSequenceRelationTypeBox().getSelectedItem() ); + if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query + final double linePosX = node.getXcoord() + 2 + half_box_size; + final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() + || ( seqRelation.getConfidence() == null ) ) ? null + : " (" + seqRelation.getConfidence().getValue() + ")"; + if ( sConfidence != null ) { + float confidenceX = pos_x; + if ( sb_str.length() > 0 ) { + confidenceX += new TextLayout( sb_str, g.getFont(), _frc ).getBounds().getWidth() + + CONFIDENCE_LEFT_MARGIN; + } + if ( confidenceX > linePosX ) { // let's only display confidence value if we are already displaying at least one of Prot/Gene Name and Taxonomy Code + final int confidenceWidth = ( int ) new TextLayout( sConfidence, g.getFont(), _frc ) + .getBounds().getWidth(); + TreePanel.drawString( sConfidence, confidenceX, pos_y, g ); + x += CONFIDENCE_LEFT_MARGIN + confidenceWidth; + } + } + if ( ( x + nodeTextBoundsWidth ) > 0 ) /* we only underline if there is something displayed */ + { + if ( nodeTextBoundsWidth == 0 ) { + nodeTextBoundsWidth -= 3; /* the gap between taxonomy code and node name should not be underlined if nothing comes after it */ + } + else { + nodeTextBoundsWidth += 2; + } + g.drawLine( ( int ) linePosX + 1, + 3 + ( int ) pos_y, + ( int ) linePosX + x + nodeTextBoundsWidth, + 3 + ( int ) pos_y ); + break; + } + } + } + } + return x; + } + + private final void drawConnection( final float x1, + final float x2, + final float y, + final int dist_left, + final int dist_right, + final Graphics2D g, + final boolean pdf ) { + if ( ( ( x1 + dist_left ) < ( x2 - dist_right ) ) ) { + final Stroke strok = g.getStroke(); + Color col = null; + if ( strok == STROKE_005 ) { + g.setStroke( STROKE_001_DASHED ); + } + else if ( strok == STROKE_01 ) { + g.setStroke( STROKE_005_DASHED ); + } + else { + g.setStroke( STROKE_01_DASHED ); + } + if ( pdf ) { + col = g.getColor(); + g.setColor( lighter( col ) ); + } + drawLine( x1 + dist_left, y, x2 - dist_right, y, g ); + g.setStroke( strok ); + if ( pdf ) { + g.setColor( col ); + } + } + } + + public static Color lighter( final Color color ) { + if ( ( color.getRed() == 0 ) && ( color.getGreen() == 0 ) && ( color.getBlue() == 0 ) ) { + return new Color( 200, 200, 200 ); + } + else { + return color; + } + } + + private final void addLabelForCollapsed( final String first, + final String last, + final int size, + final PhylogenyNode node ) { + _sb.append( first.length() < AptxConstants.MAX_LENGTH_FOR_COLLAPSED_NAME ? first + : first.substring( 0, AptxConstants.MAX_LENGTH_FOR_COLLAPSED_NAME - 1 ) ); + _sb.append( " ... " ); + _sb.append( last.length() < AptxConstants.MAX_LENGTH_FOR_COLLAPSED_NAME ? last + : last.substring( 0, AptxConstants.MAX_LENGTH_FOR_COLLAPSED_NAME - 1 ) ); + _sb.append( " (" + size + ")" ); + if ( _found_nodes_0 != null || _found_nodes_1 != null ) { + ///// + ///// + int[] res = calcFoundNodesInSubtree( node ); + if ( res[ 0 ] > 0 ) { + _sb.append( " [" ); + _sb.append( res[ 0 ] ); + _sb.append( "/" ); + _sb.append( res[ 1 ] ); + _sb.append( "]" ); + } + } + } + + private final int[] calcFoundNodesInSubtree( final PhylogenyNode node ) { + final List all_descs = PhylogenyMethods.getAllDescendants( node ); + int res[] = new int[ 2 ]; + int found = 0; + int total = 0; + for( final PhylogenyNode desc : all_descs ) { + if ( desc.isHasNodeData() ) { + if ( ( _found_nodes_0 != null && _found_nodes_0.contains( desc.getId() ) ) + || ( _found_nodes_1 != null && _found_nodes_1.contains( desc.getId() ) ) ) { + ++found; + } + ++total; + } + } + res[ 0 ] = found; + res[ 1 ] = total; + return res; + } + + private final boolean isAllowAttributedStrings() { + return false; + } + final private void paintNodeDataUnrootedCirc( final Graphics2D g, final PhylogenyNode node, final boolean to_pdf, @@ -2882,8 +3196,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sb.setLength( 0 ); _sb.append( " " ); if ( node.getNodeData().isHasTaxonomy() - && ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel() - .isShowTaxonomyCommonNames() ) ) { + && ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() + || getControlPanel().isShowTaxonomyCommonNames() ) ) { final Taxonomy taxonomy = node.getNodeData().getTaxonomy(); if ( _control_panel.isShowTaxonomyCode() && !ForesterUtil.isEmpty( taxonomy.getTaxonomyCode() ) ) { _sb.append( taxonomy.getTaxonomyCode() ); @@ -2931,7 +3245,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sb.append( node.getName() ); } if ( node.getNodeData().isHasSequence() ) { - if ( getControlPanel().isShowSequenceAcc() && ( node.getNodeData().getSequence().getAccession() != null ) ) { + if ( getControlPanel().isShowSequenceAcc() + && ( node.getNodeData().getSequence().getAccession() != null ) ) { if ( _sb.length() > 0 ) { _sb.append( " " ); } @@ -3011,35 +3326,28 @@ 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() ) { - paintCollapsedNode( g, node, false, false, false ); - } return; } if ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) { 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 ); + 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() ) { boolean first_child = true; float y2 = 0.0f; - final int parent_max_branch_to_leaf = getMaxBranchesToLeaf( node ); + //final int parent_max_branch_to_leaf = getMaxBranchesToLeaf( node ); for( int i = 0; i < node.getNumberOfDescendants(); ++i ) { final PhylogenyNode child_node = node.getChildNode( i ); - int factor_x; - if ( !isUniformBranchLengthsForCladogram() ) { - factor_x = node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes(); - } - else { - factor_x = parent_max_branch_to_leaf - getMaxBranchesToLeaf( child_node ); - } + final int factor_x = node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes(); if ( first_child ) { first_child = false; - y2 = node.getYSecondary() - - ( getOvYDistance() * ( node.getNumberOfExternalNodes() - child_node - .getNumberOfExternalNodes() ) ); + y2 = node.getYSecondary() - ( getOvYDistance() + * ( node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes() ) ); } else { y2 += getOvYDistance() * child_node.getNumberOfExternalNodes(); @@ -3076,12 +3384,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee ++_external_node_index; } // Confidence values - if ( getControlPanel().isShowConfidenceValues() - && !node.isExternal() - && !node.isRoot() + if ( getControlPanel().isShowConfidenceValues() && !node.isExternal() && !node.isRoot() && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) - || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) ) - && node.getBranchData().isHasConfidences() ) { + || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) + || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) ) + && node.getBranchData().isHasConfidences() ) { paintConfidenceValues( g, node, to_pdf, to_graphics_file ); } // Draw a line to root: @@ -3105,20 +3412,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( !node.isExternal() && !node.isCollapse() ) { boolean first_child = true; float y2 = 0.0f; - final int parent_max_branch_to_leaf = getMaxBranchesToLeaf( node ); for( int i = 0; i < node.getNumberOfDescendants(); ++i ) { final PhylogenyNode child_node = node.getChildNode( i ); - int factor_x; - if ( !isUniformBranchLengthsForCladogram() ) { - factor_x = node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes(); - } - else { - factor_x = parent_max_branch_to_leaf - getMaxBranchesToLeaf( child_node ); - } + final int factor_x = node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes(); if ( first_child ) { first_child = false; - y2 = node.getYcoord() - - ( _y_distance * ( node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes() ) ); + y2 = node.getYcoord() - ( _y_distance + * ( node.getNumberOfExternalNodes() - child_node.getNumberOfExternalNodes() ) ); } else { y2 += _y_distance * child_node.getNumberOfExternalNodes(); @@ -3152,14 +3452,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) ) { paintMolecularSequences( g, node, to_pdf ); } - if ( dynamically_hide - && !is_in_found_nodes - && ( ( node.isExternal() && ( ( _external_node_index % dynamic_hiding_factor ) != 1 ) ) || ( !node - .isExternal() && ( ( new_x_min < 20 ) || ( ( _y_distance * node.getNumberOfExternalNodes() ) < getFontMetricsForLargeDefaultFont() + if ( dynamically_hide && ( ( node.isExternal() && ( ( _external_node_index % dynamic_hiding_factor ) != 1 ) ) + || ( !node.isExternal() && ( ( new_x_min < 20 ) + || ( ( _y_distance * node.getNumberOfExternalNodes() ) < getFontMetricsForLargeDefaultFont() .getHeight() ) ) ) ) ) { return; } - final int x = paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes ); + final int x = paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes, 0 ); paintNodeWithRenderableData( x, g, node, to_graphics_file, to_pdf ); } @@ -3174,9 +3473,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( ( !getControlPanel().isShowInternalData() && !node.isExternal() ) ) { return; } + if ( ( !getControlPanel().isShowExternalData() && node.isExternal() ) ) { + return; + } if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence() - && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) - && ( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) { + && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) && ( node.getNodeData() + .getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) { RenderableDomainArchitecture rds = null; try { rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture(); @@ -3196,11 +3498,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getOptions().isLineUpRendarableNodeData() ) { if ( getOptions().isRightLineUpDomains() ) { rds.render( ( float ) ( ( getMaxDistanceToRoot() * getXcorrectionFactor() ) - + _length_of_longest_text + ( ( _longest_domain - rds.getTotalLength() ) * rds - .getRenderingFactorWidth() ) ), node.getYcoord() - ( h / 2.0f ), g, this, to_pdf ); + + _length_of_longest_text + 50 //TODO why plus 50? + + ( ( _longest_domain - rds.getTotalLength() ) * rds.getRenderingFactorWidth() ) ), + node.getYcoord() - ( h / 2.0f ), + g, + this, + to_pdf ); } else { - rds.render( ( float ) ( ( getMaxDistanceToRoot() * getXcorrectionFactor() ) + _length_of_longest_text ), + rds.render( ( float ) ( ( getMaxDistanceToRoot() * getXcorrectionFactor() ) + + _length_of_longest_text + 50 ), node.getYcoord() - ( h / 2.0f ), g, this, @@ -3213,13 +3520,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else { if ( getOptions().isRightLineUpDomains() ) { - rds.render( ( ( getPhylogeny().getFirstExternalNode().getXcoord() + _length_of_longest_text ) - 20 ) - + ( ( _longest_domain - rds.getTotalLength() ) * rds - .getRenderingFactorWidth() ), - node.getYcoord() - ( h / 2.0f ), - g, - this, - to_pdf ); + rds.render( ( ( getPhylogeny().getFirstExternalNode().getXcoord() + _length_of_longest_text ) + - 20 ) + ( ( _longest_domain - rds.getTotalLength() ) * rds.getRenderingFactorWidth() ), + node.getYcoord() - ( h / 2.0f ), + g, + this, + to_pdf ); } else { rds.render( getPhylogeny().getFirstExternalNode().getXcoord() + _length_of_longest_text, @@ -3246,18 +3552,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee rv.render( ( float ) ( node.getXcoord() + x + domain_add ), node.getYcoord() - 3, g, this, to_pdf ); } else { - rv.render( ( float ) ( getPhylogeny().getFirstExternalNode().getXcoord() + _length_of_longest_text + domain_add ), - node.getYcoord() - 3, - g, - this, - to_pdf ); + rv.render( ( float ) ( getPhylogeny().getFirstExternalNode().getXcoord() + _length_of_longest_text + + domain_add ), node.getYcoord() - 3, g, this, to_pdf ); } } } //if ( getControlPanel().isShowMolSequences() && ( node.getNodeData().isHasSequence() ) // && ( node.getNodeData().getSequence().isMolecularSequenceAligned() ) // && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) ) { - // paintMolecularSequences( g, node, to_pdf ); + // paintMolecularSequences( g, node, to_pdf ); //} } @@ -3297,10 +3600,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void paintPhylogenyLite( final Graphics2D g ) { - _phylogeny - .getRoot() - .setXSecondary( ( float ) ( getVisibleRect().x + getOvXPosition() + ( MOVE / ( getVisibleRect().width / getOvRectangle() - .getWidth() ) ) ) ); + _phylogeny.getRoot().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 ); @@ -3379,12 +3680,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final Taxonomy taxonomy = node.getNodeData().getTaxonomy(); final boolean using_visual_font = setFont( g, node, is_in_found_nodes ); setColor( g, node, to_graphics_file, to_pdf, is_in_found_nodes, getTreeColorSet().getTaxonomyColor() ); - final float start_x = node.getXcoord() + 3 + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift; + float start_x = node.getXcoord() + 3 + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift; + if ( getControlPanel().getTreeDisplayType() == Options.PHYLOGENY_DISPLAY_TYPE.ALIGNED_PHYLOGRAM + && node.isExternal() ) { + start_x = ( float ) ( ( getMaxDistanceToRoot() * getXcorrectionFactor() ) + + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift + ( 2 * TreePanel.MOVE ) + getXdistance() + + 3 ); + } float start_y; if ( !using_visual_font ) { - start_y = node.getYcoord() - + ( getFontMetricsForLargeDefaultFont().getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 - : 3.0f ) ); + start_y = node.getYcoord() + ( getFontMetricsForLargeDefaultFont().getAscent() + / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0f ) ); } else { start_y = node.getYcoord() @@ -3395,12 +3701,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final String label = _sb.toString(); /* GUILHEM_BEG */ if ( _control_panel.isShowSequenceRelations() && ( label.length() > 0 ) - && ( node.getNodeData().isHasSequence() ) && node.getNodeData().getSequence().equals( _query_sequence ) ) { + && ( node.getNodeData().isHasSequence() ) + && node.getNodeData().getSequence().equals( _query_sequence ) ) { // invert font color and background color to show that this is the query sequence - final Rectangle2D nodeTextBounds = new TextLayout( label, g.getFont(), new FontRenderContext( null, - false, - false ) ) - .getBounds(); + final Rectangle2D nodeTextBounds = new TextLayout( label, + g.getFont(), + new FontRenderContext( null, false, false ) ) + .getBounds(); g.fillRect( ( int ) start_x - 1, ( int ) start_y - 8, ( int ) nodeTextBounds.getWidth() + 4, 11 ); g.setColor( getTreeColorSet().getBackgroundColor() ); } @@ -3615,25 +3922,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } private final StringBuffer propertiesToString( final PhylogenyNode node ) { - final PropertiesMap properties = node.getNodeData().getProperties(); - final StringBuffer sb = new StringBuffer(); - boolean first = true; - for( final String ref : properties.getPropertyRefs() ) { - if ( first ) { - first = false; - } - else { - sb.append( " " ); - } - final Property p = properties.getProperty( ref ); - sb.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); - sb.append( "=" ); - sb.append( p.getValue() ); - if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - sb.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); - } - } - return sb; + return node.getNodeData().getProperties().asText(); } private void setColor( final Graphics2D g, @@ -3659,8 +3948,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( getTaxonomyBasedColor( node ) ); } else if ( getControlPanel().isColorAccordingToAnnotation() - && ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getAnnotations() != null ) && ( !node - .getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) { + && ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getAnnotations() != null ) + && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) { g.setColor( calculateColorForAnnotation( node.getNodeData().getSequence().getAnnotations() ) ); } else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles() @@ -3795,7 +4084,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _urt_factor_ov = urt_factor_ov; } - private void showExtDescNodeData( final PhylogenyNode node ) { + private void showExtDescNodeData( final PhylogenyNode node, final char separator ) { final List data = new ArrayList(); final List nodes = node.getAllExternalDescendants(); if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) { @@ -3835,51 +4124,58 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( n.getNodeData().isHasSequence() && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) { final StringBuilder ann = new StringBuilder(); - if ( !ForesterUtil.isEmpty( n.getName() ) ) { + if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( n.getName() ) ) { ann.append( n.getName() ); - ann.append( "|" ); + ann.append( separator ); } - if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { - ann.append( "SYM=" ); + if ( n.getNodeData().isHasTaxonomy() ) { + if ( getControlPanel().isShowTaxonomyCode() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() ); + ann.append( separator ); + } + if ( getControlPanel().isShowTaxonomyScientificNames() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { + ann.append( n.getNodeData().getTaxonomy().getScientificName() ); + ann.append( separator ); + } + if ( getControlPanel().isShowTaxonomyCommonNames() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) { + ann.append( n.getNodeData().getTaxonomy().getCommonName() ); + ann.append( separator ); + } + } + if ( getControlPanel().isShowSeqSymbols() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { ann.append( n.getNodeData().getSequence().getSymbol() ); - ann.append( "|" ); + ann.append( separator ); } - if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) { - ann.append( "NAME=" ); + if ( getControlPanel().isShowSeqNames() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) { ann.append( n.getNodeData().getSequence().getName() ); - ann.append( "|" ); + ann.append( separator ); } - if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) { - ann.append( "GN=" ); + if ( getControlPanel().isShowGeneNames() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) { ann.append( n.getNodeData().getSequence().getGeneName() ); - ann.append( "|" ); + ann.append( separator ); } - if ( n.getNodeData().getSequence().getAccession() != null ) { - ann.append( "ACC=" ); + if ( getControlPanel().isShowSequenceAcc() + && n.getNodeData().getSequence().getAccession() != null ) { 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( "|" ); - } + ann.append( separator ); } - String ann_str; - if ( ann.charAt( ann.length() - 1 ) == '|' ) { + + final String ann_str; + if ( ann.length() > 0 && ann.charAt( ann.length() - 1 ) == separator ) { ann_str = ann.substring( 0, ann.length() - 1 ); } else { ann_str = ann.toString(); } - sb.append( SequenceWriter.toFasta( ann_str, n.getNodeData().getSequence() - .getMolecularSequence(), 60 ) ); + sb.append( SequenceWriter.toFasta( ann_str, + n.getNodeData().getSequence().getMolecularSequence(), + 60 ) ); data.add( sb.toString() ); } break; @@ -3913,7 +4209,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final String name = d.getName(); if ( !( s.contains( name ) ) ) { data.add( name ); - if ( getOptions().getExtDescNodeDataToReturn() == NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN ) { + if ( getOptions() + .getExtDescNodeDataToReturn() == NodeDataField.DOMAINS_COLLAPSED_PER_PROTEIN ) { s.add( name ); } } @@ -3971,8 +4268,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) { if ( sb.length() < 1 ) { - TreePanelUtil.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 { @@ -3980,32 +4278,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee String title; if ( ( getFoundNodes0() != null ) && !getFoundNodes0().isEmpty() ) { title = ( getOptions().getExtDescNodeDataToReturn() == NodeDataField.UNKNOWN ? "Data" - : obtainTitleForExtDescNodeData() ) - + " for " - + data.size() - + " nodes, unique entries: " + : obtainTitleForExtDescNodeData() ) + " for " + data.size() + " nodes, unique entries: " + size; } else { title = ( getOptions().getExtDescNodeDataToReturn() == NodeDataField.UNKNOWN ? "Data" - : obtainTitleForExtDescNodeData() ) - + " for " - + data.size() - + "/" - + node.getNumberOfExternalNodes() - + " external descendats of node " - + node + : 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. - final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet(); - ae.showTextFrame( s, title ); - } - else { - getMainPanel().getMainFrame().showTextFrame( s, title ); - } + getMainPanel().getMainFrame().showTextFrame( s, title ); } } } @@ -4013,11 +4296,12 @@ 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() && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData() - .getTaxonomy() ) ) - || ( node.getNodeData().isHasSequence() && !TreePanelUtil.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 ) { @@ -4097,7 +4381,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _popup_buffer.append( "]" ); } if ( !enc_data ) { - if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) ) { + if ( ( tax.getIdentifier() != null ) + && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) ) { if ( !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) ) { _popup_buffer.append( "[" ); _popup_buffer.append( tax.getIdentifier().getProvider() ); @@ -4180,36 +4465,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _popup_buffer.append( confidence.getType() ); _popup_buffer.append( "] " ); } - _popup_buffer - .append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getValue(), - getOptions() - .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); + _popup_buffer.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getValue(), + getOptions() + .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); if ( confidence.getStandardDeviation() != Confidence.CONFIDENCE_DEFAULT_VALUE ) { _popup_buffer.append( " (sd=" ); - _popup_buffer.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence - .getStandardDeviation(), getOptions() - .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); + _popup_buffer.append( FORMATTER_CONFIDENCE + .format( ForesterUtil.round( confidence.getStandardDeviation(), + getOptions() + .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); _popup_buffer.append( ")" ); } } } if ( node.getNodeData().isHasProperties() ) { - final PropertiesMap properties = node.getNodeData().getProperties(); - for( final String ref : properties.getPropertyRefs() ) { + if ( _popup_buffer.length() > 0 ) { _popup_buffer.append( "\n" ); - final Property p = properties.getProperty( ref ); - _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); - _popup_buffer.append( "=" ); - _popup_buffer.append( p.getValue() ); - if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); - } } + _popup_buffer.append( node.getNodeData().getProperties().asText() ); } if ( _popup_buffer.length() > 0 ) { if ( !getConfiguration().isUseNativeUI() ) { _rollover_popup - .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) ); + .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) ); _rollover_popup.setBackground( getTreeColorSet().getBackgroundColor() ); if ( isInFoundNodes0( node ) && !isInFoundNodes1( node ) ) { _rollover_popup.setForeground( getTreeColorSet().getFoundColor0() ); @@ -4228,11 +4506,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _rollover_popup.setBorder( BorderFactory.createLineBorder( Color.BLACK ) ); } _rollover_popup.setText( _popup_buffer.toString() ); - _node_desc_popup = PopupFactory.getSharedInstance().getPopup( null, - _rollover_popup, - e.getLocationOnScreen().x + 10, - e.getLocationOnScreen().y - - ( lines * 20 ) ); + _node_desc_popup = PopupFactory.getSharedInstance() + .getPopup( null, + _rollover_popup, + e.getLocationOnScreen().x + 10, + e.getLocationOnScreen().y - ( lines * 20 ) ); _node_desc_popup.show(); } } @@ -4315,14 +4593,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { getControlPanel().setDrawPhylogramEnabled( false ); } - if ( getMainPanel().getMainFrame() == null ) { - // Must be "E" applet version. - ( ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet() ) - .setSelectedTypeInTypeMenu( getPhylogenyGraphicsType() ); - } - else { - getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( getPhylogenyGraphicsType() ); - } + getMainPanel().getMainFrame().setSelectedTypeInTypeMenu( getPhylogenyGraphicsType() ); } final void calcMaxDepth() { @@ -4342,22 +4613,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee calculateLongestExtNodeInfo(); if ( ( getLongestExtNodeInfo() > ( x * 0.6 ) ) && ( getTreeFontSet().getLargeFont().getSize() > ( 2 + TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) ) { - while ( ( getLongestExtNodeInfo() > ( x * 0.7 ) ) && ( getTreeFontSet().getLargeFont().getSize() > 2 ) ) { + 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 ) ) ) { + while ( ( getLongestExtNodeInfo() < ( x * 0.6 ) ) && ( getTreeFontSet().getLargeFont() + .getSize() <= ( getTreeFontSet().getLargeFontMemory().getSize() + - TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) ) { getMainPanel().getTreeFontSet().increaseFontSize(); calculateLongestExtNodeInfo(); } } //_length_of_longest_text = calcLengthOfLongestText(); int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes(); - final int max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny ); + final int max_depth = PhylogenyMethods.calculateMaxDepthConsiderCollapsed( _phylogeny ) + 1; if ( ext_nodes == 1 ) { ext_nodes = max_depth; if ( ext_nodes < 1 ) { @@ -4367,7 +4639,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee updateOvSizes(); float xdist = 0; float ov_xdist = 0; - if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) { + if ( !isNonLinedUpCladogram() ) { xdist = ( float ) ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( ext_nodes + 3.0 ) ); ov_xdist = ( float ) ( getOvMaxWidth() / ( ext_nodes + 3.0 ) ); } @@ -4388,9 +4660,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setXdistance( xdist ); setYdistance( ydist ); setOvXDistance( ov_xdist ); - final double height = _phylogeny.getHeight(); + final double height = _phylogeny.calculateHeight( !_options.isCollapsedWithAverageHeigh() ); + //final double height = PhylogenyMethods.calculateMaxDepth( _phylogeny ); if ( height > 0 ) { - final float corr = ( float ) ( ( x - ( 2.0 * TreePanel.MOVE ) - getLongestExtNodeInfo() - getXdistance() ) / height ); + final float corr = ( float ) ( ( x - ( 2.0 * TreePanel.MOVE ) - getLongestExtNodeInfo() + - getXdistance() ) / height ); setXcorrectionFactor( corr > 0 ? corr : 0 ); final float ov_corr = ( float ) ( ( getOvMaxWidth() - getOvXDistance() ) / height ); setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 ); @@ -4427,11 +4701,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { return; } - int max_possible_length = ForesterUtil.roundToInt( ( getSize().getWidth() - 2 * MOVE ) - * AptxConstants.EXT_NODE_INFO_LENGTH_MAX_RATIO ); + int max_possible_length = ForesterUtil + .roundToInt( ( getSize().getWidth() - ( 2 * MOVE ) ) * AptxConstants.EXT_NODE_INFO_LENGTH_MAX_RATIO ); if ( max_possible_length < 20 ) { - max_possible_length = 20; - } + max_possible_length = 20; + } int longest = 30; int longest_txt = 0; _longest_domain = 0; @@ -4453,7 +4727,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } boolean use_vis = false; final Graphics2D g = ( Graphics2D ) getGraphics(); - if ( getControlPanel().isUseVisualStyles() ) { + if ( g != null && getControlPanel().isUseVisualStyles() ) { use_vis = setFont( g, node, false ); } if ( !use_vis ) { @@ -4464,7 +4738,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) { sum += getFontMetricsForLargeDefaultFont().stringWidth( node.getNodeData().getBinaryCharacters() - .getGainedCharactersAsStringBuffer().toString() ); + .getGainedCharactersAsStringBuffer().toString() ); } if ( getControlPanel().isShowVectorData() && ( node.getNodeData().getVector() != null ) && ( node.getNodeData().getVector().size() > 0 ) ) { @@ -4480,8 +4754,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee // FIXME // TODO this might need some clean up final DomainArchitecture d = node.getNodeData().getSequence().getDomainArchitecture(); - sum += ( ( _domain_structure_width / ( ( RenderableDomainArchitecture ) d ).getOriginalSize() - .getWidth() ) * d.getTotalLength() ) + 10; + sum += ( ( _domain_structure_width + / ( ( RenderableDomainArchitecture ) d ).getOriginalSize().getWidth() ) * d.getTotalLength() ) + + 10; if ( d.getTotalLength() > _longest_domain ) { _longest_domain = d.getTotalLength(); } @@ -4501,12 +4776,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } _ext_node_with_longest_txt_info = longest_txt_node; - if ( longest >= max_possible_length ) { + if ( longest >= max_possible_length ) { _longest_ext_node_info = max_possible_length; - } - else { - _longest_ext_node_info = longest; - } + } + else { + _longest_ext_node_info = longest; + } _length_of_longest_text = calcLengthOfLongestText(); } @@ -4601,65 +4876,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - 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; - } - } - void clearCurrentExternalNodesDataBuffer() { setCurrentExternalNodesDataBuffer( new StringBuilder() ); } @@ -4694,6 +4910,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + final void uncollapseAll( final PhylogenyNode node ) { + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { + JOptionPane.showMessageDialog( this, + "Cannot uncollapse in unrooted display type", + "Attempt to uncollapse in unrooted display", + JOptionPane.WARNING_MESSAGE ); + return; + } + if ( !node.isExternal() ) { + TreePanelUtil.uncollapseSubtree( node ); + updateSetOfCollapsedExternalNodes(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + calculateLongestExtNodeInfo(); + setNodeInPreorderToNull(); + _control_panel.displayedPhylogenyMightHaveChanged( true ); + resetPreferredSize(); + updateOvSizes(); + _main_panel.adjustJScrollPane(); + repaint(); + } + } + final void collapseSpeciesSpecificSubtrees() { if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) { return; @@ -4706,9 +4945,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee calculateLongestExtNodeInfo(); setNodeInPreorderToNull(); resetPreferredSize(); + resetDepthCollapseDepthValue(); + resetRankCollapseRankValue(); _main_panel.adjustJScrollPane(); + getControlPanel().showWhole(); setArrowCursor(); - repaint(); } final void colorRank( final String rank ) { @@ -4745,18 +4986,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setEdited( true ); JOptionPane.showMessageDialog( this, msg, - "Taxonomy Colorization Completed (" + rank + ")", + "Taxonomy Rank-Colorization Completed (" + rank + ")", JOptionPane.INFORMATION_MESSAGE ); } else { - String msg = "Could not taxonomy colorize any subtree via " + rank + ".\n"; + String msg = "Could not taxonomy rank-colorize any subtree via " + rank + ".\n"; msg += "Possible solutions (given that suitable taxonomic information is present):\n"; msg += "select a different rank (e.g. phylum, genus, ...)\n"; msg += " and/or\n"; msg += "execute:\n"; - msg += "1. \"" + MainFrameApplication.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n"; - msg += "2. \"" + MainFrameApplication.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)"; - JOptionPane.showMessageDialog( this, msg, "Taxonomy Colorization Failed", JOptionPane.WARNING_MESSAGE ); + msg += "1. \"" + MainFrame.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n"; + msg += "2. \"" + MainFrame.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)"; + JOptionPane.showMessageDialog( this, + msg, + "Taxonomy Rank-Colorization Failed", + JOptionPane.WARNING_MESSAGE ); } } @@ -4788,7 +5032,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee * @param y * @return pointer to the node at x,y, null if not found */ - final PhylogenyNode findNode( final int x, final int y ) { + public final PhylogenyNode findNode( final int x, final int y ) { if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { return null; } @@ -4826,15 +5070,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return _domain_structure_e_value_thr_exp; } - final Set getFoundNodes0() { + public final Set getFoundNodes0() { return _found_nodes_0; } - final Set getFoundNodes1() { + public final Set getFoundNodes1() { return _found_nodes_1; } - List getFoundNodesAsListOfPhylogenyNodes() { + public List getFoundNodesAsListOfPhylogenyNodes() { final List additional_nodes = new ArrayList(); if ( getFoundNodes0() != null ) { for( final Long id : getFoundNodes0() ) { @@ -4913,7 +5157,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return getTreeColorSet().getTaxonomyColor(); } - final File getTreeFile() { + public final File getTreeFile() { return _treefile; } @@ -4944,14 +5188,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) { RenderableDomainArchitecture rds = null; - if ( !( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) { + if ( !( node.getNodeData().getSequence() + .getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) { if ( SPECIAL_DOMAIN_COLORING ) { rds = new RenderableDomainArchitecture( node.getNodeData().getSequence() - .getDomainArchitecture(), node.getName() ); + .getDomainArchitecture(), node.getName() ); } else { rds = new RenderableDomainArchitecture( node.getNodeData().getSequence() - .getDomainArchitecture() ); + .getDomainArchitecture() ); } node.getNodeData().getSequence().setDomainArchitecture( rds ); } @@ -4983,25 +5228,37 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean inOv( final MouseEvent e ) { return ( ( e.getX() > ( getVisibleRect().x + getOvXPosition() + 1 ) ) && ( e.getX() < ( ( getVisibleRect().x + getOvXPosition() + getOvMaxWidth() ) - 1 ) ) - && ( e.getY() > ( getVisibleRect().y + getOvYPosition() + 1 ) ) && ( e.getY() < ( ( getVisibleRect().y - + getOvYPosition() + getOvMaxHeight() ) - 1 ) ) ); + && ( e.getY() > ( getVisibleRect().y + getOvYPosition() + 1 ) ) + && ( e.getY() < ( ( getVisibleRect().y + getOvYPosition() + getOvMaxHeight() ) - 1 ) ) ); } final boolean inOvRectangle( final MouseEvent e ) { return ( ( e.getX() >= ( getOvRectangle().getX() - 1 ) ) && ( e.getX() <= ( getOvRectangle().getX() + getOvRectangle().getWidth() + 1 ) ) - && ( e.getY() >= ( getOvRectangle().getY() - 1 ) ) && ( e.getY() <= ( getOvRectangle().getY() - + getOvRectangle().getHeight() + 1 ) ) ); - } - - final boolean isApplet() { - return getMainPanel() instanceof MainPanelApplets; + && ( e.getY() >= ( getOvRectangle().getY() - 1 ) ) + && ( e.getY() <= ( getOvRectangle().getY() + getOvRectangle().getHeight() + 1 ) ) ); } final boolean isCanCollapse() { return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ); } + final boolean isCanUncollapseAll( final PhylogenyNode node ) { + if ( node.isExternal() || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) ) { + return false; + } + if ( node.isCollapse() ) { + return true; + } + final PhylogenyNodeIterator it = new PreorderTreeIterator( node ); + while ( it.hasNext() ) { + if ( it.next().isCollapse() ) { + return true; + } + } + return false; + } + final boolean isCanColorSubtree() { return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ); } @@ -5011,8 +5268,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final boolean isCanCut( final PhylogenyNode node ) { - return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() && !node - .isRoot() ); + return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() + && !node.isRoot() ); } final boolean isCanDelete() { @@ -5029,8 +5286,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final boolean isCanSubtree( final PhylogenyNode node ) { - return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal() && ( !node - .isRoot() || ( _subtree_index > 0 ) ) ); + return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal() + && ( !node.isRoot() || ( _subtree_index > 0 ) ) ); } final boolean isCurrentTreeIsSubtree() { @@ -5096,7 +5353,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee y = max_y; } getMainPanel().getCurrentScrollPane().getViewport() - .setViewPosition( new Point( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ) ) ); + .setViewPosition( new Point( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ) ) ); setInOvRect( true ); repaint(); } @@ -5133,10 +5390,28 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } else { - // no node was clicked + // no node was clicked so partition tree instead _highlight_node = null; - } + + _clicked_x = e.getX(); + if (!getPhylogeny().isEmpty()) { + // should be calculated on each partition as the tree can theoretically + // change in the meantime + PhylogenyNode furthestNode = PhylogenyMethods.calculateNodeWithMaxDistanceToRoot( _phylogeny ); + _furthest_node_x = furthestNode.getXcoord(); + _root_x = _phylogeny.getRoot().getXcoord(); + + // don't bother if 0 distance tree or clicked x lies outside of tree + if (_furthest_node_x != _root_x && !(_clicked_x < _root_x || _clicked_x > _furthest_node_x)) + { + _partition_tree = true; + + } + + } + } + } repaint(); } @@ -5283,10 +5558,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _urt_factor *= f; } - final JApplet obtainApplet() { - return ( ( MainPanelApplets ) getMainPanel() ).getApplet(); - } - final void paintBranchCircular( final PhylogenyNode p, final PhylogenyNode c, final Graphics2D g, @@ -5343,8 +5614,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g ); if ( isInFoundNodes( c ) || isInCurrentExternalNodes( c ) ) { 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 ); + 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 ); } } @@ -5410,6 +5684,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final int graphics_file_height, final int graphics_file_x, final int graphics_file_y ) { + if (_partition_tree) { +// float threshold = (_clicked_x - _root_x) / (_furthest_node_x - _root_x); +// drawLine( _clicked_x, 0, _clicked_x, getHeight(),g); + + _partition_tree = false; + } + if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { return; } @@ -5433,8 +5714,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else { if ( !to_graphics_file ) { - g.setPaint( new GradientPaint( r.x, r.y, getTreeColorSet().getBackgroundColor(), r.x, r.y - + r.height, getTreeColorSet().getBackgroundColorGradientBottom() ) ); + g.setPaint( new GradientPaint( r.x, + r.y, + getTreeColorSet().getBackgroundColor(), + r.x, + r.y + r.height, + getTreeColorSet().getBackgroundColorGradientBottom() ) ); g.fill( r ); } else { @@ -5456,19 +5741,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) { _external_node_index = 0; // Position starting X of tree - if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/) { + if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/ ) { _phylogeny.getRoot().setXcoord( TreePanel.MOVE ); } else if ( ( _phylogeny.getRoot().getDistanceToParent() > 0.0 ) && getControlPanel().isDrawPhylogram() ) { - _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + ( _phylogeny.getRoot() - .getDistanceToParent() * getXcorrectionFactor() ) ) ); + _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + + ( _phylogeny.getRoot().getDistanceToParent() * getXcorrectionFactor() ) ) ); } else { _phylogeny.getRoot().setXcoord( TreePanel.MOVE + getXdistance() ); } // Position starting Y of tree _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() ) - + ( TreePanel.MOVE / 2.0f ) ); + + ( TreePanel.MOVE / 2.0f ) ); final int dynamic_hiding_factor = calcDynamicHidingFactor(); if ( getControlPanel().isDynamicallyHideData() ) { if ( dynamic_hiding_factor > 1 ) { @@ -5486,10 +5771,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } final boolean disallow_shortcutting = ( dynamic_hiding_factor < 40 ) - || getControlPanel().isUseVisualStyles() || getOptions().isShowDefaultNodeShapesForMarkedNodes() - || ( ( getFoundNodes0() != null ) && !getFoundNodes0().isEmpty() ) - || ( ( getFoundNodes1() != null ) && !getFoundNodes1().isEmpty() ) - || ( ( getCurrentExternalNodes() != null ) && !getCurrentExternalNodes().isEmpty() ) + /* || getControlPanel().isUseVisualStyles() || getOptions().isShowDefaultNodeShapesForMarkedNodes()*/ //TODO check if this is really not needed. || to_graphics_file || to_pdf; for( final PhylogenyNode element : _nodes_in_preorder ) { paintNodeRectangular( g, @@ -5524,8 +5806,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL; _dynamic_hiding_factor = 0; if ( getControlPanel().isDynamicallyHideData() ) { - _dynamic_hiding_factor = ( int ) ( ( getFontMetricsForLargeDefaultFont().getHeight() * 1.5 * getPhylogeny() - .getNumberOfExternalNodes() ) / ( TWO_PI * 10 ) ); + _dynamic_hiding_factor = ( int ) ( ( getFontMetricsForLargeDefaultFont().getHeight() * 1.5 + * getPhylogeny().getNumberOfExternalNodes() ) / ( TWO_PI * 10 ) ); } if ( getControlPanel().getDynamicallyHideData() != null ) { if ( _dynamic_hiding_factor > 1 ) { @@ -5565,12 +5847,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) { - final int radius = ( int ) ( ( Math.min( getPreferredSize().getWidth(), getPreferredSize().getHeight() ) / 2 ) - ( MOVE + getLongestExtNodeInfo() ) ); + final int radius = ( int ) ( ( Math.min( getPreferredSize().getWidth(), getPreferredSize().getHeight() ) + / 2 ) - ( MOVE + getLongestExtNodeInfo() ) ); final int d = radius + MOVE + getLongestExtNodeInfo(); _dynamic_hiding_factor = 0; if ( getControlPanel().isDynamicallyHideData() && ( radius > 0 ) ) { - _dynamic_hiding_factor = ( int ) ( ( getFontMetricsForLargeDefaultFont().getHeight() * 1.5 * getPhylogeny() - .getNumberOfExternalNodes() ) / ( TWO_PI * radius ) ); + _dynamic_hiding_factor = ( int ) ( ( getFontMetricsForLargeDefaultFont().getHeight() * 1.5 + * getPhylogeny().getNumberOfExternalNodes() ) / ( TWO_PI * radius ) ); } if ( getControlPanel().getDynamicallyHideData() != null ) { if ( _dynamic_hiding_factor > 1 ) { @@ -5602,9 +5885,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getStartingAngle(), x_pos + radius_ov, y_pos + radius_ov, - ( int ) ( radius_ov - ( getLongestExtNodeInfo() / ( getVisibleRect().width / getOvRectangle() - .getWidth() ) ) ), - g ); + ( int ) ( radius_ov - ( getLongestExtNodeInfo() + / ( getVisibleRect().width / getOvRectangle().getWidth() ) ) ), + g ); g.setTransform( _at ); paintOvRectangle( g ); } @@ -5613,6 +5896,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final void recalculateMaxDistanceToRoot() { _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() ); + if ( getPhylogeny().getRoot().getDistanceToParent() > 0 ) { + _max_distance_to_root += getPhylogeny().getRoot().getDistanceToParent(); + } } /** @@ -5683,24 +5969,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee y = TreePanel.MOVE + ForesterUtil.roundToInt( getYdistance() * getPhylogeny().getRoot().getNumberOfExternalNodes() * 2 ); if ( getControlPanel().isDrawPhylogram() ) { - x = TreePanel.MOVE - + getLongestExtNodeInfo() - + ForesterUtil - .roundToInt( ( getXcorrectionFactor() * getPhylogeny().getHeight() ) + getXdistance() ); - + x = TreePanel.MOVE + getLongestExtNodeInfo() + + ForesterUtil.roundToInt( ( getXcorrectionFactor() + * getPhylogeny().calculateHeight( !_options.isCollapsedWithAverageHeigh() ) ) + + getXdistance() ); } else { - if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) { - x = TreePanel.MOVE - + getLongestExtNodeInfo() - + ForesterUtil.roundToInt( getXdistance() - * ( getPhylogeny().getRoot().getNumberOfExternalNodes() + 2 ) ); + if ( !isNonLinedUpCladogram() ) { + x = TreePanel.MOVE + getLongestExtNodeInfo() + ForesterUtil + .roundToInt( getXdistance() * ( getPhylogeny().getRoot().getNumberOfExternalNodes() + 2 ) ); } else { - x = TreePanel.MOVE - + getLongestExtNodeInfo() - + ForesterUtil.roundToInt( getXdistance() - * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) ); + x = TreePanel.MOVE + getLongestExtNodeInfo() + ForesterUtil + .roundToInt( getXdistance() * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) ); } } setPreferredSize( new Dimension( x, y ) ); @@ -5740,11 +6021,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _current_external_nodes_data_buffer = sb; } - final void setFoundNodes0( final Set found_nodes ) { + public final void setFoundNodes0( final Set found_nodes ) { _found_nodes_0 = found_nodes; } - final void setFoundNodes1( final Set found_nodes ) { + public final void setFoundNodes1( final Set found_nodes ) { _found_nodes_1 = found_nodes; } @@ -5825,7 +6106,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getTreeFontSet().tinyFonts(); } - final void setTreeFile( final File treefile ) { + public final void setTreeFile( final File treefile ) { _treefile = treefile; } @@ -5890,7 +6171,20 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sub_phylogenies_temp_roots[ _subtree_index ] = node; ++_subtree_index; _phylogeny = TreePanelUtil.subTree( node, _phylogeny ); + if ( _phylogeny.getRoot().isCollapse() ) { + _phylogeny.getRoot().setCollapse( false ); + } + _phylogeny.externalNodesHaveChanged(); + _phylogeny.clearHashIdToNodeMap(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); updateSubSuperTreeButton(); + getMainPanel().getControlPanel().search0(); + getMainPanel().getControlPanel().search1(); + resetRankCollapseRankValue(); + resetDepthCollapseDepthValue(); + getMainPanel().getControlPanel().updateDomainStructureEvaluethresholdDisplay(); + getMainPanel().getControlPanel().updateDepthCollapseDepthDisplay(); + getMainPanel().getControlPanel().updateRankCollapseRankDisplay(); } else if ( node.isRoot() && isCurrentTreeIsSubtree() ) { superTree(); @@ -5908,9 +6202,42 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sub_phylogenies[ _subtree_index ] = null; _sub_phylogenies_temp_roots[ _subtree_index ] = null; _phylogeny = _sub_phylogenies[ --_subtree_index ]; + _phylogeny.externalNodesHaveChanged(); + _phylogeny.clearHashIdToNodeMap(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); + getMainPanel().getControlPanel().search0(); + getMainPanel().getControlPanel().search1(); + resetRankCollapseRankValue(); + resetDepthCollapseDepthValue(); + getMainPanel().getControlPanel().updateDomainStructureEvaluethresholdDisplay(); + getMainPanel().getControlPanel().updateDepthCollapseDepthDisplay(); + getMainPanel().getControlPanel().updateRankCollapseRankDisplay(); updateSubSuperTreeButton(); } + final void orderSubtree( final PhylogenyNode node ) { + if ( node.isExternal() ) { + return; + } + DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.NODE_NAME; + if ( getControlPanel().isShowTaxonomyScientificNames() || getControlPanel().isShowTaxonomyCode() ) { + pri = DESCENDANT_SORT_PRIORITY.TAXONOMY; + } + else if ( getControlPanel().isShowSeqNames() || getControlPanel().isShowSeqSymbols() + || getControlPanel().isShowGeneNames() ) { + pri = DESCENDANT_SORT_PRIORITY.SEQUENCE; + } + PhylogenyMethods.orderAppearanceX( node, true, pri ); + setNodeInPreorderToNull(); + getPhylogeny().externalNodesHaveChanged(); + getPhylogeny().clearHashIdToNodeMap(); + getPhylogeny().recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + setEdited( true ); + getControlPanel().displayedPhylogenyMightHaveChanged( true ); + repaint(); + } + final void swap( final PhylogenyNode node ) { if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) { return; @@ -5975,7 +6302,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final void updateOvSizes() { - if ( ( getWidth() > ( 1.05 * getVisibleRect().width ) ) || ( getHeight() > ( 1.05 * getVisibleRect().height ) ) ) { + if ( ( getWidth() > ( 1.05 * getVisibleRect().width ) ) + || ( getHeight() > ( 1.05 * getVisibleRect().height ) ) ) { setOvOn( true ); float l = getLongestExtNodeInfo(); final float w_ratio = getOvMaxWidth() / getWidth(); @@ -5983,7 +6311,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes(); setOvYDistance( getOvMaxHeight() / ( 2 * ext_nodes ) ); float ov_xdist = 0; - if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) { + if ( !isNonLinedUpCladogram() ) { ov_xdist = ( ( getOvMaxWidth() - l ) / ( ext_nodes ) ); } else { @@ -5997,7 +6325,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee ydist = 0.0f; } setOvXDistance( ov_xdist ); - final double height = _phylogeny.getHeight(); + final double height = _phylogeny.calculateHeight( !_options.isCollapsedWithAverageHeigh() ); if ( height > 0 ) { final float ov_corr = ( float ) ( ( ( getOvMaxWidth() - l ) - getOvXDistance() ) / height ); setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 ); @@ -6039,6 +6367,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + final void updateButtonToUncollapseAll() { + if ( PhylogenyMethods.isHasCollapsedNodes( _phylogeny ) ) { + getControlPanel().activateButtonToUncollapseAll(); + } + else { + getControlPanel().deactivateButtonToUncollapseAll(); + } + } + final void zoomInDomainStructure() { if ( _domain_structure_width < 2000 ) { _domain_structure_width *= 1.2; @@ -6062,8 +6399,141 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.drawString( str, x, y ); } + final private void drawStringX( final String str, final float x, final float y, final Graphics2D g ) { + //TODO + //FIXME + if ( getAttributedStringMap() == null /*&& getAttributedStringMap().containsKey(str) */ ) { + final AttributedString as = new AttributedString( str ); + //Font plainFont = new Font("Times New Roman", Font.PLAIN, 24); + as.addAttribute( TextAttribute.FONT, g.getFont() ); + as.addAttribute( TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 1, 3 ); + as.addAttribute( TextAttribute.SUPERSCRIPT, TextAttribute.SUPERSCRIPT_SUPER, 3, 4 ); + as.addAttribute( TextAttribute.FOREGROUND, Color.BLUE, 1, 2 ); + as.addAttribute( TextAttribute.FOREGROUND, Color.PINK, 3, 5 ); + as.addAttribute( TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON, 2, 4 ); + g.drawString( as.getIterator(), x, y ); + } + else { + g.drawString( str, x, y ); + } + } + + private final Map getAttributedStringMap() { + return _attributed_string_map; + } + + private final void setAttributedStringMap( final Map attributed_string_map ) { + _attributed_string_map = attributed_string_map; + } + 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 ) ); + || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) + || ( key_code == KeyEvent.VK_1 ) ); + } + + public void decreaseDepthCollapseLevel() { + if ( ( _phylogeny != null ) && ( _phylogeny.getNumberOfExternalNodes() > 2 ) ) { + if ( _depth_collapse_level <= 1 ) { + _depth_collapse_level = PhylogenyMethods.calculateMaxDepth( _phylogeny ); + uncollapseAll(); + } + else { + --_depth_collapse_level; + PhylogenyMethods.collapseToDepth( _phylogeny, _depth_collapse_level ); + } + } + } + + public void increaseDepthCollapseLevel() { + if ( ( _phylogeny != null ) && ( _phylogeny.getNumberOfExternalNodes() > 2 ) ) { + final int max = PhylogenyMethods.calculateMaxDepth( _phylogeny ); + if ( _depth_collapse_level >= max ) { + _depth_collapse_level = 1; + } + else { + ++_depth_collapse_level; + } + PhylogenyMethods.collapseToDepth( _phylogeny, _depth_collapse_level ); + } + } + + public void decreaseRankCollapseLevel() { + if ( ( _phylogeny != null ) && ( _phylogeny.getNumberOfExternalNodes() > 2 ) ) { + final String ranks[] = PhylogenyMethods.obtainPresentRanksSorted( _phylogeny ); + if ( ranks.length > 1 ) { + if ( _rank_collapse_level <= 0 ) { + _rank_collapse_level = ranks.length - 1; + uncollapseAll(); + } + else { + --_rank_collapse_level; + PhylogenyMethods.collapseToRank( _phylogeny, + mapToAbsoluteRankLevel( ranks, _rank_collapse_level ) ); + } + } + } + } + + public void increaseRankCollapseLevel() { + if ( ( _phylogeny != null ) && ( _phylogeny.getNumberOfExternalNodes() > 2 ) ) { + final String ranks[] = PhylogenyMethods.obtainPresentRanksSorted( _phylogeny ); + if ( ranks.length > 1 ) { + if ( _rank_collapse_level >= ( ranks.length - 1 ) ) { + _rank_collapse_level = 0; + PhylogenyMethods.collapseToRank( _phylogeny, + mapToAbsoluteRankLevel( ranks, _rank_collapse_level ) ); + } + else if ( _rank_collapse_level == ( ranks.length - 2 ) ) { + ++_rank_collapse_level; + uncollapseAll(); + } + else { + ++_rank_collapse_level; + PhylogenyMethods.collapseToRank( _phylogeny, + mapToAbsoluteRankLevel( ranks, _rank_collapse_level ) ); + } + } + } + } + + private final static int mapToAbsoluteRankLevel( final String present_ranks_sorted[], + final int rank_collapse_level ) { + final String rank_str = present_ranks_sorted[ rank_collapse_level ]; + if ( !TaxonomyUtil.RANK_TO_INT.containsKey( rank_str ) ) { + throw new IllegalStateException( "unexpected exception: cannot find rank " + rank_str ); + } + return TaxonomyUtil.RANK_TO_INT.get( rank_str ); + } + + private final void uncollapseAll() { + final PhylogenyNodeIterator it = new PreorderTreeIterator( _phylogeny ); + while ( it.hasNext() ) { + it.next().setCollapse( false ); + } + } + + final int resetDepthCollapseDepthValue() { + return _depth_collapse_level = -1; + } + + final int getDepthCollapseDepthValue() { + return _depth_collapse_level; + } + + final void setDepthCollapseDepthValue( final int depth_collapse_level ) { + _depth_collapse_level = depth_collapse_level; + } + + final int resetRankCollapseRankValue() { + return _rank_collapse_level = -1; + } + + final int getRankCollapseRankValue() { + return _rank_collapse_level; + } + + final void setRankCollapseRankValue( final int rank_collapse_level ) { + _rank_collapse_level = rank_collapse_level; } }