X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Farchaeopteryx%2FTreePanel.java;h=924eae9e4c8a408a2ea05d44cbcf670b9ba6388f;hb=9c1299acd081df2bd8c6c7320ce7f102f0fa5440;hp=2f3df261bf3124bf29ea898202d5416e1e3757d4;hpb=aecd652a29342d239f7d90e21e6526d71f44bd33;p=jalview.git diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanel.java b/forester/java/src/org/forester/archaeopteryx/TreePanel.java index 2f3df26..924eae9 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanel.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanel.java @@ -89,21 +89,30 @@ import javax.swing.JTextArea; import javax.swing.Popup; import javax.swing.PopupFactory; +import org.forester.archaeopteryx.Configuration.EXT_NODE_DATA_RETURN_ON; import org.forester.archaeopteryx.ControlPanel.NodeClickAction; import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE; import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION; import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE; import org.forester.archaeopteryx.phylogeny.data.RenderableDomainArchitecture; import org.forester.archaeopteryx.phylogeny.data.RenderableVector; +import org.forester.archaeopteryx.tools.Blast; +import org.forester.archaeopteryx.tools.ImageLoader; import org.forester.io.parsers.phyloxml.PhyloXmlUtil; import org.forester.phylogeny.Phylogeny; import org.forester.phylogeny.PhylogenyMethods; +import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY; import org.forester.phylogeny.PhylogenyNode; import org.forester.phylogeny.data.Annotation; import org.forester.phylogeny.data.BranchColor; import org.forester.phylogeny.data.Confidence; import org.forester.phylogeny.data.Event; +import org.forester.phylogeny.data.NodeData.NODE_DATA; +import org.forester.phylogeny.data.NodeVisualization; +import org.forester.phylogeny.data.NodeVisualization.NodeFill; +import org.forester.phylogeny.data.NodeVisualization.NodeShape; import org.forester.phylogeny.data.PhylogenyData; +import org.forester.phylogeny.data.PhylogenyDataUtil; import org.forester.phylogeny.data.PropertiesMap; import org.forester.phylogeny.data.Property; import org.forester.phylogeny.data.Sequence; @@ -116,6 +125,7 @@ import org.forester.util.BasicDescriptiveStatistics; import org.forester.util.DescriptiveStatistics; import org.forester.util.ForesterConstants; import org.forester.util.ForesterUtil; +import org.forester.util.SequenceIdParser; public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable { @@ -134,15 +144,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private final static int EURO_D = 10; private final static String NODE_POPMENU_NODE_CLIENT_PROPERTY = "node"; private final static int MIN_ROOT_LENGTH = 3; - private final static int BOX_SIZE = 4; - private final static int HALF_BOX_SIZE = TreePanel.BOX_SIZE / 2; private final static int MAX_SUBTREES = 100; private final static int MAX_NODE_FRAMES = 10; private final static int MOVE = 20; private final static NumberFormat FORMATTER_CONFIDENCE; private final static NumberFormat FORMATTER_BRANCH_LENGTH; private final static int WIGGLE = 2; - private final static int HALF_BOX_SIZE_PLUS_WIGGLE = HALF_BOX_SIZE + WIGGLE; private final static int LIMIT_FOR_HQ_RENDERING = 1000; private final static int CONFIDENCE_LEFT_MARGIN = 4; // TODO "rendering_hints" was static before. Need to make sure everything is OK with it not @@ -204,11 +211,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private static double _180_OVER_PI = 180.0 / Math.PI; private static final float ROUNDED_D = 8; private int _circ_max_depth; - private int _circ_num_ext_nodes; private PhylogenyNode _root; final private Arc2D _arc = new Arc2D.Double(); final private HashMap _urt_nodeid_angle_map = new HashMap(); final private HashMap _urt_nodeid_index_map = new HashMap(); + final private Set _collapsed_external_nodeid_set = new HashSet(); HashMap _nodeid_dist_to_leaf = new HashMap(); private AffineTransform _at; private double _max_distance_to_root = -1; @@ -216,12 +223,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private boolean _edited = false; private Popup _node_desc_popup; private JTextArea _rollover_popup; + // private final int _box_size; + // private final int _half_box_size; //private final short _skip_counter = 0; private final StringBuffer _popup_buffer = new StringBuffer(); final private static Font POPUP_FONT = new Font( Configuration.getDefaultFontFamilyName(), Font.PLAIN, 12 ); - private static final boolean DRAW_MEAN_COUNTS = true; //TODO remove me later private Sequence _query_sequence = null; private final FontRenderContext _frc = new FontRenderContext( null, false, @@ -263,7 +271,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _main_panel = tjp; _configuration = configuration; _phylogeny = t; - _phy_has_branch_lengths = ForesterUtil.isHasAtLeastOneBranchLengthLargerThanZero( _phylogeny ); + _phy_has_branch_lengths = AptxUtil.isHasAtLeastOneBranchLengthLargerThanZero( _phylogeny ); init(); // if ( !_phylogeny.isEmpty() ) { _phylogeny.recalculateNumberOfExternalDescendants( true ); @@ -339,11 +347,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + @Override final public void actionPerformed( final ActionEvent e ) { - int index; boolean done = false; final JMenuItem node_popup_menu_item = ( JMenuItem ) e.getSource(); - for( index = 0; ( index < _node_popup_menu_items.length ) && !done; index++ ) { + for( int index = 0; ( index < _node_popup_menu_items.length ) && !done; index++ ) { // NOTE: index corresponds to the indices of click-to options // in the control panel. if ( node_popup_menu_item == _node_popup_menu_items[ index ] ) { @@ -364,7 +372,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee errorMessageNoCutCopyPasteInUnrootedDisplay(); return; } - final String label = getASimpleTextRepresentationOfANode( node ); + final String label = createASimpleTextRepresentationOfANode( node ); String msg = ""; if ( ForesterUtil.isEmpty( label ) ) { msg = "How to add the new, empty node?"; @@ -404,8 +412,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { phy.addAsChild( node ); } + setNodeInPreorderToNull(); _phylogeny.externalNodesHaveChanged(); - _phylogeny.hashIDs(); + _phylogeny.clearHashIdToNodeMap(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); setEdited( true ); @@ -440,43 +449,75 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final void assignGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node, final Graphics g ) { + final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) { if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { - g.setColor( PhylogenyMethods.getBranchColorValue( node ) ); + return ( PhylogenyMethods.getBranchColorValue( node ) ); } else { - g.setColor( getTreeColorSet().getBranchColor() ); + return ( getTreeColorSet().getBranchColor() ); } } final private void blast( final PhylogenyNode node ) { if ( !isCanBlast( node ) ) { JOptionPane.showMessageDialog( this, - "No sequence information present", + "Insufficient information present", "Cannot Blast", - JOptionPane.WARNING_MESSAGE ); + JOptionPane.INFORMATION_MESSAGE ); return; } - if ( node.getNodeData().isHasSequence() ) { - String name = ""; - if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) { - name = node.getNodeData().getSequence().getName(); - } - else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) { - name = node.getNodeData().getSequence().getSymbol(); - } - else if ( node.getNodeData().getSequence().getAccession() != null ) { - name = node.getNodeData().getSequence().getAccession().getValue(); - } - if ( !ForesterUtil.isEmpty( name ) ) { + else { + final String query = Blast.obtainQueryForBlast( node ); + System.out.println( "query for BLAST is: " + query ); + char type = '?'; + if ( !ForesterUtil.isEmpty( query ) ) { + if ( node.getNodeData().isHasSequence() ) { + if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getType() ) ) { + if ( node.getNodeData().getSequence().getType().toLowerCase() + .equals( PhyloXmlUtil.SEQ_TYPE_PROTEIN ) ) { + type = 'p'; + } + else { + type = 'n'; + } + } + else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) { + if ( ForesterUtil.seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() ) ) { + type = 'p'; + } + else { + type = 'n'; + } + } + } + if ( type == '?' ) { + if ( SequenceIdParser.isProtein( query ) ) { + type = 'p'; + } + else { + type = 'n'; + } + } + JApplet applet = null; + if ( isApplet() ) { + applet = obtainApplet(); + } try { - System.out.println( "trying: " + name ); - final Blast s = new Blast(); - s.go( name ); + Blast.openNcbiBlastWeb( query, type == 'n', applet, this ); } catch ( final Exception e ) { e.printStackTrace(); } + if ( Constants.ALLOW_DDBJ_BLAST ) { + try { + System.out.println( "trying: " + query ); + final Blast s = new Blast(); + s.ddbjBlast( query ); + } + catch ( final Exception e ) { + e.printStackTrace(); + } + } } } } @@ -526,7 +567,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { return; } - int longest = 20; + int max_length = ForesterUtil.roundToInt( ( getSize().getWidth() - MOVE ) + * Constants.EXT_NODE_INFO_LENGTH_MAX_RATIO ); + if ( max_length < 40 ) { + max_length = 40; + } + int longest = 30; for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) { int sum = 0; if ( node.isCollapse() ) { @@ -556,6 +602,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .asSimpleText() + " " ); } + if ( getControlPanel().isShowDomainArchitectures() + && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) { + sum += ( ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture() ) + .getRenderingSize().getWidth(); + } } if ( node.getNodeData().isHasTaxonomy() ) { final Taxonomy tax = node.getNodeData().getTaxonomy(); @@ -570,25 +621,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee sum += getTreeFontSet()._fm_large_italic.stringWidth( tax.getCommonName() + " ()" ); } } + if ( getControlPanel().isShowProperties() && node.getNodeData().isHasProperties() ) { + sum += getTreeFontSet()._fm_large.stringWidth( propertiesToString( node ).toString() ); + } if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) { sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getBinaryCharacters() .getGainedCharactersAsStringBuffer().toString() ); } - if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence() - && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) { - sum += ( ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture() ) - .getRenderingSize().getWidth(); - } - if ( sum >= Constants.EXT_NODE_INFO_LENGTH_MAX ) { - setLongestExtNodeInfo( Constants.EXT_NODE_INFO_LENGTH_MAX ); + if ( sum >= max_length ) { + setLongestExtNodeInfo( max_length ); return; } if ( sum > longest ) { longest = sum; } } - if ( longest >= Constants.EXT_NODE_INFO_LENGTH_MAX ) { - setLongestExtNodeInfo( Constants.EXT_NODE_INFO_LENGTH_MAX ); + if ( longest >= max_length ) { + setLongestExtNodeInfo( max_length ); } else { setLongestExtNodeInfo( longest ); @@ -656,7 +705,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee // Look in species hash Color c = getControlPanel().getSpeciesColors().get( species ); if ( c == null ) { - c = Util.calculateColorFromString( species ); + c = AptxUtil.calculateColorFromString( species ); getControlPanel().getSpeciesColors().put( species, c ); } return c; @@ -685,10 +734,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !node.isExternal() && !node.isRoot() ) { final boolean collapse = !node.isCollapse(); - Util.collapseSubtree( node, collapse ); + AptxUtil.collapseSubtree( node, collapse ); + updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); calculateLongestExtNodeInfo(); + setNodeInPreorderToNull(); + _control_panel.displayedPhylogenyMightHaveChanged( true ); resetPreferredSize(); updateOvSizes(); _main_panel.adjustJScrollPane(); @@ -701,10 +753,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - Util.collapseSpeciesSpecificSubtrees( _phylogeny ); + AptxUtil.collapseSpeciesSpecificSubtrees( _phylogeny ); + updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); calculateLongestExtNodeInfo(); + setNodeInPreorderToNull(); resetPreferredSize(); _main_panel.adjustJScrollPane(); setArrowCursor(); @@ -755,7 +809,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - Util.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); + AptxUtil.removeBranchColors( _phylogeny ); + AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { _control_panel.getColorBranchesCb().setSelected( true ); @@ -764,11 +819,57 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } + final void colorRank( final String rank ) { + if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) { + return; + } + setWaitCursor(); + AptxUtil.removeBranchColors( _phylogeny ); + final int colorizations = AptxUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this ); + if ( colorizations > 0 ) { + _control_panel.setColorBranches( true ); + if ( _control_panel.getColorBranchesCb() != null ) { + _control_panel.getColorBranchesCb().setSelected( true ); + } + if ( _control_panel.getColorAccSpeciesCb() != null ) { + _control_panel.getColorAccSpeciesCb().setSelected( false ); + } + _options.setColorLabelsSameAsParentBranch( true ); + _control_panel.repaint(); + } + setArrowCursor(); + repaint(); + if ( colorizations > 0 ) { + String msg = "Taxonomy colorization via " + rank + " completed:\n"; + if ( colorizations > 1 ) { + msg += "colorized " + colorizations + " subtrees"; + } + else { + msg += "colorized one subtree"; + } + JOptionPane.showMessageDialog( this, + msg, + "Taxonomy Colorization Completed (" + rank + ")", + JOptionPane.INFORMATION_MESSAGE ); + } + else { + String msg = "Could not taxonomy 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 ); + } + } + final private void copySubtree( final PhylogenyNode node ) { if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { errorMessageNoCutCopyPasteInUnrootedDisplay(); return; } + setNodeInPreorderToNull(); setCutOrCopiedTree( _phylogeny.copy( node ) ); final List nodes = PhylogenyMethods.getAllDescendants( node ); final Set node_ids = new HashSet( nodes.size() ); @@ -792,7 +893,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.ERROR_MESSAGE ); return; } - final String label = getASimpleTextRepresentationOfANode( node ); + final String label = createASimpleTextRepresentationOfANode( node ); final int r = JOptionPane.showConfirmDialog( null, "Cut subtree" + label + "?", "Confirm Cutting of Subtree", @@ -800,10 +901,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( r != JOptionPane.OK_OPTION ) { return; } + setNodeInPreorderToNull(); setCopiedAndPastedNodes( null ); setCutOrCopiedTree( _phylogeny.copy( node ) ); _phylogeny.deleteSubtree( node, true ); - _phylogeny.hashIDs(); + _phylogeny.clearHashIdToNodeMap(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); setEdited( true ); @@ -844,7 +946,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.ERROR_MESSAGE ); return; } - final String label = getASimpleTextRepresentationOfANode( node ); + final String label = createASimpleTextRepresentationOfANode( node ); final Object[] options = { "Node only", "Entire subtree", "Cancel" }; final int r = JOptionPane.showOptionDialog( this, "Delete" + label + "?", @@ -854,6 +956,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee null, options, options[ 2 ] ); + setNodeInPreorderToNull(); boolean node_only = true; if ( r == 1 ) { node_only = false; @@ -868,7 +971,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _phylogeny.deleteSubtree( node, true ); } _phylogeny.externalNodesHaveChanged(); - _phylogeny.hashIDs(); + _phylogeny.clearHashIdToNodeMap(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); setEdited( true ); @@ -932,6 +1035,52 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.fill( _rectangle ); } + final private void drawRectGradient( final double x, + final double y, + final double width, + final double heigth, + final Graphics2D g, + final Color color_1, + final Color color_2, + final Color color_border ) { + _rectangle.setFrame( x, y, width, heigth ); + g.setPaint( new GradientPaint( ( float ) x, + ( float ) y, + color_1, + ( float ) ( x + width ), + ( float ) ( y + heigth ), + color_2, + false ) ); + g.fill( _rectangle ); + if ( color_border != null ) { + g.setPaint( color_border ); + g.draw( _rectangle ); + } + } + + final private void drawOvalGradient( final double x, + final double y, + final double width, + final double heigth, + final Graphics2D g, + final Color color_1, + final Color color_2, + final Color color_border ) { + _ellipse.setFrame( x, y, width, heigth ); + g.setPaint( new GradientPaint( ( float ) x, + ( float ) y, + color_1, + ( float ) ( x + width ), + ( float ) ( y + heigth ), + color_2, + false ) ); + g.fill( _ellipse ); + if ( color_border != null ) { + g.setPaint( color_border ); + g.draw( _ellipse ); + } + } + final private void errorMessageNoCutCopyPasteInUnrootedDisplay() { JOptionPane.showMessageDialog( this, "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display", @@ -950,20 +1099,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { return null; } + final int half_box_size_plus_wiggle = ( getOptions().getDefaultNodeShapeSize() / 2 ) + WIGGLE; for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) { final PhylogenyNode node = iter.next(); if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) ) - && ( ( node.getXcoord() - HALF_BOX_SIZE_PLUS_WIGGLE ) <= x ) - && ( ( node.getXcoord() + HALF_BOX_SIZE_PLUS_WIGGLE ) >= x ) - && ( ( node.getYcoord() - HALF_BOX_SIZE_PLUS_WIGGLE ) <= y ) - && ( ( node.getYcoord() + HALF_BOX_SIZE_PLUS_WIGGLE ) >= y ) ) { + && ( ( node.getXcoord() - half_box_size_plus_wiggle ) <= x ) + && ( ( node.getXcoord() + half_box_size_plus_wiggle ) >= x ) + && ( ( node.getYcoord() - half_box_size_plus_wiggle ) <= y ) + && ( ( node.getYcoord() + half_box_size_plus_wiggle ) >= y ) ) { return node; } } return null; } - final private String getASimpleTextRepresentationOfANode( final PhylogenyNode node ) { + final private String createASimpleTextRepresentationOfANode( final PhylogenyNode node ) { final String tax = PhylogenyMethods.getSpecies( node ); String label = node.getName(); if ( !ForesterUtil.isEmpty( label ) && !ForesterUtil.isEmpty( tax ) ) { @@ -1091,7 +1241,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee * * @return a pointer to the phylogeny */ - final Phylogeny getPhylogeny() { + public final Phylogeny getPhylogeny() { return _phylogeny; } @@ -1207,11 +1357,133 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee case EDIT_NODE_DATA: showNodeEditFrame( node ); break; + case SORT_DESCENDENTS: + sortDescendants( node ); + break; + case GET_EXT_DESC_DATA: + showExtDescNodeData( node ); + break; default: throw new IllegalArgumentException( "unknown action: " + action ); } } + private void showExtDescNodeData( final PhylogenyNode node ) { + final List data = new ArrayList(); + for( final PhylogenyNode n : node.getAllExternalDescendants() ) { + switch ( getOptions().getExtDescNodeDataToReturn() ) { + case NODE_NAME: + if ( !ForesterUtil.isEmpty( n.getName() ) ) { + data.add( n.getName() ); + } + break; + case SEQUENCE_NAME: + if ( n.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) { + data.add( n.getNodeData().getSequence().getName() ); + } + break; + case SEQUENCE_SYMBOL: + if ( n.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { + data.add( n.getNodeData().getSequence().getSymbol() ); + } + break; + case SEQUENCE_MOL_SEQ: + if ( n.getNodeData().isHasSequence() + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) { + data.add( n.getNodeData().getSequence().getMolecularSequence() ); + } + break; + case SEQUENCE_ACC: + if ( n.getNodeData().isHasSequence() && ( n.getNodeData().getSequence().getAccession() != null ) + && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getAccession().toString() ) ) { + data.add( n.getNodeData().getSequence().getAccession().toString() ); + } + break; + case TAXONOMY_SCIENTIFIC_NAME: + if ( n.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { + data.add( n.getNodeData().getTaxonomy().getScientificName() ); + } + break; + case TAXONOMY_CODE: + if ( n.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + data.add( n.getNodeData().getTaxonomy().getTaxonomyCode() ); + } + break; + case UNKNOWN: + AptxUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data ); + break; + default: + throw new IllegalArgumentException( "unknown data element: " + + getOptions().getExtDescNodeDataToReturn() ); + } + } // for loop + if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) { + for( final String d : data ) { + if ( !ForesterUtil.isEmpty( d ) ) { + System.out.println( d ); + } + } + } + else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) { + final StringBuilder sb = new StringBuilder(); + for( final String d : data ) { + if ( !ForesterUtil.isEmpty( d ) ) { + sb.append( d ); + sb.append( "\n" ); + } + } + if ( sb.length() < 1 ) { + AptxUtil.showInformationMessage( this, + "No Appropriate Data (" + obtainTitleForExtDescNodeData() + ")", + "Descendants of selected node do not contain selected data" ); + } + else { + final String title = "External Descendants " + + ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" + : obtainTitleForExtDescNodeData() ) + " (" + data.size() + "/" + + node.getNumberOfExternalNodes() + ") For Node " + node; + if ( getMainPanel().getMainFrame() == null ) { + // Must be "E" applet version. + final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet(); + final String s = sb.toString().trim(); + ae.showTextFrame( s, title ); + ae.setCurrentExternalNodesDataBuffer( s ); + } + else { + getMainPanel().getMainFrame().showTextFrame( sb.toString(), title ); + } + } + } + } + + private final String obtainTitleForExtDescNodeData() { + switch ( getOptions().getExtDescNodeDataToReturn() ) { + case NODE_NAME: + return "Node Names"; + case SEQUENCE_NAME: + return "Sequence Names"; + case SEQUENCE_SYMBOL: + return "Sequence Symbols"; + case SEQUENCE_MOL_SEQ: + return "Molecular Sequences"; + case SEQUENCE_ACC: + return "Sequence Accessors"; + case TAXONOMY_SCIENTIFIC_NAME: + return "Scientific Names"; + case TAXONOMY_CODE: + return "Taxonomy Codes"; + case UNKNOWN: + return "User Selected Data"; + default: + throw new IllegalArgumentException( "unknown data element: " + + getOptions().getExtDescNodeDataToReturn() ); + } + } + final void increaseDomainStructureEvalueThreshold() { if ( _domain_structure_e_value_thr_exp < 3 ) { _domain_structure_e_value_thr_exp += 1; @@ -1219,9 +1491,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void increaseOvSize() { - if ( ( getOvMaxWidth() < getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) - && ( getOvMaxHeight() < getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect() - .getHeight() / 2 ) ) { + if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) ) + && ( getOvMaxHeight() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect() + .getHeight() / 2 ) ) ) { setOvMaxWidth( getOvMaxWidth() + 5 ); setOvMaxHeight( getOvMaxHeight() + 5 ); updateOvSettings(); @@ -1234,7 +1506,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - Util.inferCommonPartOfScientificNames( _phylogeny ); + AptxUtil.inferCommonPartOfScientificNames( _phylogeny ); setArrowCursor(); repaint(); } @@ -1248,7 +1520,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setTreeFile( null ); setEdited( false ); initializeOvSettings(); - setStartingAngle( TWO_PI * 3 / 4 ); + setStartingAngle( ( TWO_PI * 3 ) / 4 ); final ImageLoader il = new ImageLoader( this ); new Thread( il ).start(); } @@ -1298,24 +1570,24 @@ 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 ) ); + 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 ) ) ); } 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 ) ); + 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 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 ) ); + return ( ( x >= ( getOvVirtualRectangle().x - 1 ) ) + && ( x <= ( getOvVirtualRectangle().x + getOvVirtualRectangle().width + 1 ) ) + && ( y >= ( getOvVirtualRectangle().y - 1 ) ) && ( y <= ( getOvVirtualRectangle().y + + getOvVirtualRectangle().height + 1 ) ) ); } final private boolean inOvVirtualRectangle( final MouseEvent e ) { @@ -1327,10 +1599,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private boolean isCanBlast( final PhylogenyNode node ) { - return ( node.getNodeData().isHasSequence() && ( ( ( node.getNodeData().getSequence().getAccession() != null ) && !ForesterUtil - .isEmpty( node.getNodeData().getSequence().getAccession().getValue() ) ) - || !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) || !ForesterUtil.isEmpty( node - .getNodeData().getSequence().getSymbol() ) ) ); + if ( !node.getNodeData().isHasSequence() && ForesterUtil.isEmpty( node.getName() ) ) { + return false; + } + return Blast.isContainsQueryForBlast( node ); } final boolean isCanCollapse() { @@ -1420,16 +1692,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getControlPanel().isShowTaxonomyImages() ) { y_dist = 40 + ( int ) getYdistance(); } - return ( ( node.getYcoord() < getVisibleRect().getMinY() - y_dist ) - || ( node.getYcoord() > getVisibleRect().getMaxY() + y_dist ) || ( ( node.getParent() != null ) && ( node + return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - y_dist ) ) + || ( 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 ) ); + return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - 20 ) ) + || ( node.getYcoord() > ( getVisibleRect().getMaxY() + 20 ) ) + || ( node.getXcoord() < ( getVisibleRect().getMinX() - 20 ) ) || ( node.getXcoord() > ( getVisibleRect() + .getMaxX() + 20 ) ) ); } final private boolean isNonLinedUpCladogram() { @@ -1629,9 +1901,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _node_popup_menu_items[ i ].setEnabled( isCanOpenTaxWeb( node ) ); } else if ( title.equals( Configuration.clickto_options[ Configuration.blast ][ 0 ] ) ) { - if ( Constants.__RELEASE || Constants.__SNAPSHOT_RELEASE ) { - continue; - } _node_popup_menu_items[ i ].setEnabled( isCanBlast( node ) ); } else if ( title.equals( Configuration.clickto_options[ Configuration.delete_subtree_or_node ][ 0 ] ) ) { @@ -1672,7 +1941,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _node_popup_menu_items[ i ].setEnabled( isCanReroot() ); } else if ( title.equals( Configuration.clickto_options[ Configuration.collapse_uncollapse ][ 0 ] ) ) { - _node_popup_menu_items[ i ].setEnabled( isCanCollapse() ); + _node_popup_menu_items[ i ].setEnabled( ( isCanCollapse() && !node.isExternal() ) ); } else if ( title.equals( Configuration.clickto_options[ Configuration.color_subtree ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( isCanColorSubtree() ); @@ -1680,6 +1949,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( title.equals( Configuration.clickto_options[ Configuration.subtree ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( isCanSubtree( node ) ); } + else if ( title.equals( Configuration.clickto_options[ Configuration.swap ][ 0 ] ) ) { + _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() == 2 ); + } + else if ( title.equals( Configuration.clickto_options[ Configuration.sort_descendents ][ 0 ] ) ) { + _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() > 1 ); + } _node_popup_menu_items[ i ].addActionListener( this ); _node_popup_menu.add( _node_popup_menu_items[ i ] ); } @@ -1696,6 +1971,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.WARNING_MESSAGE ); return; } + setNodeInPreorderToNull(); setWaitCursor(); PhylogenyMethods.midpointRoot( _phylogeny ); resetNodeIdToDistToLeafMap(); @@ -1707,9 +1983,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getOptions().isShowOverview() && isOvOn() && isInOv() ) { final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth(); final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight(); - double x = ( e.getX() - getVisibleRect().x - getOvXPosition() - getOvRectangle().getWidth() / 2.0 ) + double x = ( e.getX() - getVisibleRect().x - getOvXPosition() - ( getOvRectangle().getWidth() / 2.0 ) ) * w_ratio; - double y = ( e.getY() - getVisibleRect().y - getOvYPosition() - getOvRectangle().getHeight() / 2.0 ) + double y = ( e.getY() - getVisibleRect().y - getOvYPosition() - ( getOvRectangle().getHeight() / 2.0 ) ) * h_ratio; if ( x < 0 ) { x = 0; @@ -1806,8 +2082,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth(); final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight(); final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition(); - double dx = ( w_ratio * e.getX() - w_ratio * getLastDragPointX() ); - double dy = ( h_ratio * e.getY() - h_ratio * getLastDragPointY() ); + double dx = ( ( w_ratio * e.getX() ) - ( w_ratio * getLastDragPointX() ) ); + double dy = ( ( h_ratio * e.getY() ) - ( h_ratio * getLastDragPointY() ) ); scroll_position.x = ForesterUtil.roundToInt( scroll_position.x + dx ); scroll_position.y = ForesterUtil.roundToInt( scroll_position.y + dy ); if ( scroll_position.x <= 0 ) { @@ -1899,6 +2175,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setCursor( ARROW_CURSOR ); } + @Override final public void mouseWheelMoved( final MouseWheelEvent e ) { final int notches = e.getWheelRotation(); if ( inOvVirtualRectangle( e ) ) { @@ -2008,7 +2285,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } if ( !ForesterUtil.isEmpty( uri_str ) ) { @@ -2017,14 +2294,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( isApplet() ) { applet = obtainApplet(); } - Util.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" ); } catch ( final IOException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } catch ( final URISyntaxException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2048,7 +2325,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2058,7 +2335,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee uri_str = new URI( tax.getIdentifier().getValue() ).toString(); } catch ( final URISyntaxException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); uri_str = null; e.printStackTrace(); } @@ -2069,7 +2346,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2079,7 +2356,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee + URLEncoder.encode( tax.getTaxonomyCode(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2089,7 +2366,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2099,14 +2376,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( isApplet() ) { applet = obtainApplet(); } - Util.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" ); } catch ( final IOException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } catch ( final URISyntaxException e ) { - Util.showErrorMessage( this, e.toString() ); + AptxUtil.showErrorMessage( this, e.toString() ); e.printStackTrace(); } } @@ -2126,7 +2403,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final double root_y = _root.getYcoord(); final double dx = root_x - p.getXcoord(); final double dy = root_y - p.getYcoord(); - final double parent_radius = Math.sqrt( dx * dx + dy * dy ); + final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) ); final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle; assignGraphicsForBranchWithColorForParentBranch( c, false, g, to_pdf, to_graphics_file ); if ( ( c.isFirstChildNode() || c.isLastChildNode() ) @@ -2143,7 +2420,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( c.isExternal() ) { final boolean is_in_found_nodes = isInFoundNodes( c ); if ( ( _dynamic_hiding_factor > 1 ) && !is_in_found_nodes - && ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor != 1 ) ) { + && ( ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor ) != 1 ) ) { return; } paintNodeDataUnrootedCirc( g, c, to_pdf, to_graphics_file, radial_labels, 0, is_in_found_nodes ); @@ -2157,7 +2434,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final double dx = root_x - p.getXSecondary(); final double dy = root_y - p.getYSecondary(); final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle; - final double parent_radius = Math.sqrt( dx * dx + dy * dy ); + final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) ); g.setColor( getTreeColorSet().getOvColor() ); if ( ( c.isFirstChildNode() || c.isLastChildNode() ) && ( Math.abs( arc ) > 0.02 ) ) { final double r2 = 2.0 * parent_radius; @@ -2245,7 +2522,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private void paintBranchRectangular( final Graphics2D g, final float x1, final float x2, - float y1, + final float y1, final float y2, final PhylogenyNode node, final boolean to_pdf, @@ -2266,131 +2543,87 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.draw( _cubic_curve ); } else { - float x2a = x2; - float x1a = x1; - // draw the vertical line - boolean draw_horizontal = true; + final float x2a = x2; + final float x1a = x1; float y2_r = 0; if ( node.isFirstChildNode() || node.isLastChildNode() || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) { - boolean draw_vertical = true; - final PhylogenyNode parent = node.getParent(); - if ( ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file ) || ( ( getControlPanel() - .isEvents() ) && ( parent != null ) && parent.isHasAssignedEvent() ) ) - && ( _phylogeny.isRooted() || !( ( parent != null ) && parent.isRoot() ) ) - && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !parent - .isDuplication() ) ) { - if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) - && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) { - if ( Math.abs( y2 - y1 ) <= TreePanel.HALF_BOX_SIZE ) { - draw_vertical = false; - } - else { - if ( y1 < y2 ) { - y1 += TreePanel.HALF_BOX_SIZE; - } - else { - if ( !to_pdf ) { - y1 -= TreePanel.HALF_BOX_SIZE + 1; - } - else { - y1 -= TreePanel.HALF_BOX_SIZE; - } - } - } - } - if ( ( x2 - x1 ) <= TreePanel.HALF_BOX_SIZE ) { - draw_horizontal = false; - } - else if ( !draw_vertical ) { - x1a += TreePanel.HALF_BOX_SIZE; - } - if ( ( ( x2 - x1a ) > TreePanel.HALF_BOX_SIZE ) - && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !node - .isDuplication() ) ) { - x2a -= TreePanel.HALF_BOX_SIZE; - } + if ( !to_graphics_file + && !to_pdf + && ( ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) && ( y1 < ( getVisibleRect().getMinY() - 20 ) ) ) || ( ( y2 > ( getVisibleRect() + .getMaxY() + 20 ) ) && ( y1 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) ) { + // Do nothing. } - if ( draw_vertical ) { - 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 { - if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { - float x2c = x1 + EURO_D; - if ( x2c > x2a ) { - x2c = x2a; - } - drawLine( x1, y1, x2c, y2, g ); + else { + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { + float x2c = x1 + EURO_D; + if ( x2c > x2a ) { + x2c = x2a; } - else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { - if ( y2 > y1 ) { - y2_r = y2 - ROUNDED_D; - if ( y2_r < y1 ) { - y2_r = y1; - } - drawLine( x1, y1, x1, y2_r, g ); - } - else { - y2_r = y2 + ROUNDED_D; - if ( y2_r > y1 ) { - y2_r = y1; - } - drawLine( x1, y1, x1, y2_r, g ); + drawLine( x1, y1, x2c, y2, g ); + } + else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { + if ( y2 > y1 ) { + y2_r = y2 - ROUNDED_D; + if ( y2_r < y1 ) { + y2_r = y1; } + drawLine( x1, y1, x1, y2_r, g ); } else { - drawLine( x1, y1, x1, y2, g ); + y2_r = y2 + ROUNDED_D; + if ( y2_r > y1 ) { + y2_r = y1; + } + drawLine( x1, y1, x1, y2_r, g ); } } + else { + drawLine( x1, y1, x1, y2, g ); + } } } // draw the horizontal line if ( !to_graphics_file && !to_pdf - && ( ( y2 < getVisibleRect().getMinY() - 20 ) || ( y2 > getVisibleRect().getMaxY() + 20 ) ) ) { + && ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) || ( y2 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) { return; } float x1_r = 0; - if ( draw_horizontal ) { - if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) { - if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { - x1_r = x1a + ROUNDED_D; - if ( x1_r < x2a ) { - drawLine( x1_r, y2, x2a, y2, g ); - } - } - else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { - final float x1c = x1a + EURO_D; - if ( x1c < x2a ) { - drawLine( x1c, y2, x2a, y2, g ); - } + if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) { + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { + x1_r = x1a + ROUNDED_D; + if ( x1_r < x2a ) { + drawLine( x1_r, y2, x2a, y2, g ); } - else { - drawLine( x1a, y2, x2a, y2, g ); + } + else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { + final float x1c = x1a + EURO_D; + if ( x1c < x2a ) { + drawLine( x1c, y2, x2a, y2, g ); } } else { - final double w = PhylogenyMethods.getBranchWidthValue( node ); - if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { - x1_r = x1a + ROUNDED_D; - if ( x1_r < x2a ) { - drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g ); - } - } - else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { - final float x1c = x1a + EURO_D; - if ( x1c < x2a ) { - drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g ); - } + drawLine( x1a, y2, x2a, y2, g ); + } + } + else { + final double w = PhylogenyMethods.getBranchWidthValue( node ); + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) { + x1_r = x1a + ROUNDED_D; + if ( x1_r < x2a ) { + drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g ); } - else { - drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g ); + } + else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) { + final float x1c = x1a + EURO_D; + if ( x1c < x2a ) { + drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g ); } } + else { + drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g ); + } } if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) { if ( x1_r > x2a ) { @@ -2406,7 +2639,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.draw( _arc ); } } - paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) ); + if ( node.isExternal() ) { + paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) ); + } } final void paintCircular( final Phylogeny phy, @@ -2417,23 +2652,49 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final Graphics2D g, final boolean to_pdf, final boolean to_graphics_file ) { - _circ_num_ext_nodes = phy.getNumberOfExternalNodes(); + final int circ_num_ext_nodes = phy.getNumberOfExternalNodes() - _collapsed_external_nodeid_set.size(); + System.out.println( "# collapsed external = " + _collapsed_external_nodeid_set.size() ); _root = phy.getRoot(); _root.setXcoord( center_x ); _root.setYcoord( center_y ); - paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) ); final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL; double current_angle = starting_angle; int i = 0; for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) { final PhylogenyNode n = it.next(); - n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) ); - n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) ); - _urt_nodeid_angle_map.put( n.getId(), current_angle ); - _urt_nodeid_index_map.put( n.getId(), i++ ); - current_angle += ( TWO_PI / _circ_num_ext_nodes ); + if ( !n.isCollapse() ) { + n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) ); + n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) ); + _urt_nodeid_angle_map.put( n.getId(), current_angle ); + _urt_nodeid_index_map.put( n.getId(), i++ ); + current_angle += ( TWO_PI / circ_num_ext_nodes ); + } + else { + //TODO remove me + System.out.println( "is collapse" + n.getName() ); + } } paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, g, to_pdf, to_graphics_file ); + paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) ); + } + + void updateSetOfCollapsedExternalNodes() { + final Phylogeny phy = getPhylogeny(); + _collapsed_external_nodeid_set.clear(); + if ( phy != null ) { + E: for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) { + final PhylogenyNode ext_node = it.next(); + PhylogenyNode n = ext_node; + while ( !n.isRoot() ) { + if ( n.isCollapse() ) { + _collapsed_external_nodeid_set.add( ext_node.getId() ); + ext_node.setCollapse( true ); + continue E; + } + n = n.getParent(); + } + } + } } final void paintCircularLite( final Phylogeny phy, @@ -2442,17 +2703,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final int center_y, final int radius, final Graphics2D g ) { - _circ_num_ext_nodes = phy.getNumberOfExternalNodes(); + final int circ_num_ext_nodes = phy.getNumberOfExternalNodes(); _root = phy.getRoot(); _root.setXSecondary( center_x ); _root.setYSecondary( center_y ); double current_angle = starting_angle; for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) { final PhylogenyNode n = it.next(); - n.setXSecondary( ( float ) ( center_x + radius * Math.cos( current_angle ) ) ); - n.setYSecondary( ( float ) ( center_y + radius * Math.sin( current_angle ) ) ); + n.setXSecondary( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) ); + n.setYSecondary( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) ); _urt_nodeid_angle_map.put( n.getId(), current_angle ); - current_angle += ( TWO_PI / _circ_num_ext_nodes ); + current_angle += ( TWO_PI / circ_num_ext_nodes ); } paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g ); } @@ -2466,9 +2727,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final Graphics2D g, final boolean to_pdf, final boolean to_graphics_file ) { - if ( n.isExternal() ) { + if ( n.isExternal() || n.isCollapse() ) { //~~circ collapse if ( !_urt_nodeid_angle_map.containsKey( n.getId() ) ) { - System.out.println( "no " + n + ", fucker!" );//TODO + System.out.println( "no " + n + " =====>>>>>>> ERROR!" );//TODO } return _urt_nodeid_angle_map.get( n.getId() ); } @@ -2488,11 +2749,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } double r = 0; if ( !n.isRoot() ) { - r = 1 - ( ( ( double ) _circ_max_depth - PhylogenyMethods.calculateDepth( n ) ) / _circ_max_depth ); + r = 1 - ( ( ( double ) _circ_max_depth - n.calculateDepth() ) / _circ_max_depth ); } final double theta = sum / descs.size(); - n.setXcoord( ( float ) ( center_x + r * radius * Math.cos( theta ) ) ); - n.setYcoord( ( float ) ( center_y + r * radius * Math.sin( theta ) ) ); + n.setXcoord( ( float ) ( center_x + ( r * radius * Math.cos( theta ) ) ) ); + n.setYcoord( ( float ) ( center_y + ( r * radius * Math.sin( theta ) ) ) ); _urt_nodeid_angle_map.put( n.getId(), theta ); for( final PhylogenyNode desc : descs ) { paintBranchCircular( n, desc, g, radial_labels, to_pdf, to_graphics_file ); @@ -2517,11 +2778,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } float r = 0; if ( !n.isRoot() ) { - r = 1 - ( ( ( float ) _circ_max_depth - PhylogenyMethods.calculateDepth( n ) ) / _circ_max_depth ); + r = 1 - ( ( ( float ) _circ_max_depth - n.calculateDepth() ) / _circ_max_depth ); } final double theta = _urt_nodeid_angle_map.get( n.getId() ); - n.setXSecondary( ( float ) ( center_x + radius * r * Math.cos( theta ) ) ); - n.setYSecondary( ( float ) ( center_y + radius * r * Math.sin( theta ) ) ); + n.setXSecondary( ( float ) ( center_x + ( radius * r * Math.cos( theta ) ) ) ); + n.setYSecondary( ( float ) ( center_y + ( radius * r * Math.sin( theta ) ) ) ); for( final PhylogenyNode desc : descs ) { paintBranchCircularLite( n, desc, g ); } @@ -2533,21 +2794,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_graphics_file, final boolean to_pdf, final boolean is_in_found_nodes ) { + Color c = null; if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { - g.setColor( Color.BLACK ); + c = Color.BLACK; } else if ( is_in_found_nodes ) { - g.setColor( getTreeColorSet().getFoundColor() ); + c = getTreeColorSet().getFoundColor(); } else if ( getControlPanel().isColorAccordingToTaxonomy() ) { - g.setColor( getTaxonomyBasedColor( node ) ); + c = getTaxonomyBasedColor( node ); } else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) { - g.setColor( PhylogenyMethods.getBranchColorValue( node ) ); + c = PhylogenyMethods.getBranchColorValue( node ); } else { - g.setColor( getTreeColorSet().getCollapseFillColor() ); + c = getTreeColorSet().getCollapseFillColor(); } double d = node.getAllExternalDescendants().size(); if ( d > 1000 ) { @@ -2556,17 +2818,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { d = ( Math.log10( d ) * _y_distance ) / 2.5; } - if ( d < BOX_SIZE ) { - d = BOX_SIZE; + final int box_size = getOptions().getDefaultNodeShapeSize(); + if ( d < box_size ) { + d = box_size; } _polygon.reset(); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - TreePanel.BOX_SIZE ), + _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ), ForesterUtil.roundToInt( node.getYcoord() ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ), + _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), ForesterUtil.roundToInt( node.getYcoord() - d ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ), + _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), ForesterUtil.roundToInt( node.getYcoord() + d ) ); - g.fillPolygon( _polygon ); + if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { + g.setColor( c ); + g.fillPolygon( _polygon ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) { + g.setColor( getBackground() ); + g.fillPolygon( _polygon ); + g.setColor( c ); + g.drawPolygon( _polygon ); + } + else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { + g.setPaint( new GradientPaint( node.getXcoord() - box_size, node.getYcoord(), getBackground(), ( node + .getXcoord() + box_size ), ( float ) ( node.getYcoord() - d ), c, false ) ); + g.fill( _polygon ); + g.setPaint( c ); + g.draw( _polygon ); + } paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes ); } @@ -2597,36 +2876,45 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final PhylogenyNode node, final boolean to_pdf, final boolean to_graphics_file ) { - String conf_str = ""; final List confidences = node.getBranchData().getConfidences(); - if ( confidences.size() == 1 ) { - final double value = node.getBranchData().getConfidence( 0 ).getValue(); - if ( ( value == Confidence.CONFIDENCE_DEFAULT_VALUE ) || ( value < getOptions().getMinConfidenceValue() ) ) { - return; - } - conf_str = FORMATTER_CONFIDENCE.format( value ); - } - else if ( confidences.size() > 1 ) { - boolean one_ok = false; - boolean not_first = false; - Collections.sort( confidences ); - final StringBuilder sb = new StringBuilder(); - for( final Confidence confidence : confidences ) { - final double value = confidence.getValue(); - if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) { - if ( value >= getOptions().getMinConfidenceValue() ) { - one_ok = true; - } - if ( not_first ) { - sb.append( "/" ); - } - else { - not_first = true; + // if ( confidences.size() == 1 ) { + // final double value = node.getBranchData().getConfidence( 0 ).getValue(); + // if ( ( value == Confidence.CONFIDENCE_DEFAULT_VALUE ) || ( value < getOptions().getMinConfidenceValue() ) ) { + // return; + // } + // conf_str = FORMATTER_CONFIDENCE.format( value ); + // } + // else if ( confidences.size() > 1 ) { + boolean one_ok = false; + boolean not_first = false; + Collections.sort( confidences ); + final StringBuilder sb = new StringBuilder(); + String conf_str = ""; + for( final Confidence confidence : confidences ) { + final double value = confidence.getValue(); + if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) { + if ( value >= getOptions().getMinConfidenceValue() ) { + one_ok = true; + } + if ( not_first ) { + sb.append( "/" ); + } + else { + not_first = true; + } + 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( ")" ); } - sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( value, getOptions() - .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) ); } } + //} if ( one_ok ) { conf_str = sb.toString(); } @@ -2657,8 +2945,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void paintFoundNode( final int x, final int y, final Graphics2D g ) { + final int box_size = getOptions().getDefaultNodeShapeSize(); + final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2; g.setColor( getTreeColorSet().getFoundColor() ); - g.fillRect( x - TreePanel.HALF_BOX_SIZE, y - TreePanel.HALF_BOX_SIZE, TreePanel.BOX_SIZE, TreePanel.BOX_SIZE ); + g.fillRect( x - half_box_size, y - half_box_size, box_size, box_size ); } final private void paintGainedAndLostCharacters( final Graphics2D g, @@ -2715,33 +3005,93 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g ); } else { + Color outline_color = null; if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { - g.setColor( Color.BLACK ); + outline_color = Color.BLACK; } - else if ( getControlPanel().isEvents() && Util.isHasAssignedEvent( node ) ) { + else if ( getControlPanel().isEvents() && AptxUtil.isHasAssignedEvent( node ) ) { final Event event = node.getNodeData().getEvent(); if ( event.isDuplication() ) { - g.setColor( getTreeColorSet().getDuplicationBoxColor() ); + outline_color = getTreeColorSet().getDuplicationBoxColor(); } else if ( event.isSpeciation() ) { - g.setColor( getTreeColorSet().getSpecBoxColor() ); + outline_color = getTreeColorSet().getSpecBoxColor(); } else if ( event.isSpeciationOrDuplication() ) { - g.setColor( getTreeColorSet().getDuplicationOrSpeciationColor() ); + outline_color = getTreeColorSet().getDuplicationOrSpeciationColor(); } } - else { - assignGraphicsForNodeBoxWithColorForParentBranch( node, g ); + else if ( getOptions().isTaxonomyColorizeNodeShapes() ) { + outline_color = getTaxonomyBasedColor( node ); } - if ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file ) - || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) { - if ( to_pdf || to_graphics_file ) { - if ( node.isDuplication() || !getOptions().isPrintBlackAndWhite() ) { - drawOvalFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g ); + else { + outline_color = getGraphicsForNodeBoxWithColorForParentBranch( node ); + if ( to_pdf && ( outline_color == getTreeColorSet().getBranchColor() ) ) { + outline_color = getTreeColorSet().getBranchColorForPdf(); + } + } + final int box_size = getOptions().getDefaultNodeShapeSize(); + final int half_box_size = box_size / 2; + if ( getOptions().isShowDefaultNodeShapes() || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) { + if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) { + if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { + drawOvalGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + to_pdf ? Color.WHITE : outline_color, + to_pdf ? outline_color : getBackground(), + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) { + Color background = getBackground(); + if ( to_pdf ) { + background = Color.WHITE; + } + drawOvalGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + background, + background, + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { + g.setColor( outline_color ); + drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); } } - else { - drawRectFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g ); + else if ( getOptions().getDefaultNodeShape() == NodeVisualization.NodeShape.RECTANGLE ) { + if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.GRADIENT ) { + drawRectGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + to_pdf ? Color.WHITE : outline_color, + to_pdf ? outline_color : getBackground(), + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) { + Color background = getBackground(); + if ( to_pdf ) { + background = Color.WHITE; + } + drawRectGradient( x - half_box_size, + y - half_box_size, + box_size, + box_size, + g, + background, + background, + outline_color ); + } + else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) { + g.setColor( outline_color ); + drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g ); + } } } } @@ -2758,20 +3108,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getOptions().isShowBranchLengthValues() && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) ) - && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyNode.DISTANCE_DEFAULT ) ) { + && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) { paintBranchLength( g, node, to_pdf, to_graphics_file ); } if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) { return; } int x = 0; + 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() ) ) { - x += drawTaxonomyImage( node.getXcoord() + 2 + TreePanel.HALF_BOX_SIZE, node.getYcoord(), node, g ); + x += drawTaxonomyImage( node.getXcoord() + 2 + half_box_size, node.getYcoord(), node, g ); } if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel() .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) { @@ -2832,6 +3183,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sb.append( node.getNodeData().getSequence().getAccession().getValue() ); } } + if ( getControlPanel().isShowProperties() && node.getNodeData().isHasProperties() ) { + if ( _sb.length() > 0 ) { + _sb.append( " " ); + } + _sb.append( propertiesToString( node ) ); + } g.setFont( getTreeFontSet().getLargeFont() ); if ( is_in_found_nodes ) { g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) ); @@ -2840,7 +3197,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) { down_shift_factor = 1; } - final double pos_x = node.getXcoord() + x + 2 + TreePanel.HALF_BOX_SIZE; + final double pos_x = node.getXcoord() + x + 2 + half_box_size; final double pos_y = ( node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ) ); final String sb_str = _sb.toString(); // GUILHEM_BEG ______________ @@ -2865,7 +3222,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee && 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 + TreePanel.HALF_BOX_SIZE; + final double linePosX = node.getXcoord() + 2 + half_box_size; final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue() + ")"; @@ -2882,7 +3239,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee x += CONFIDENCE_LEFT_MARGIN + confidenceWidth; } } - if ( x + nodeTextBoundsWidth > 0 ) /* we only underline if there is something displayed */ + 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 */ @@ -2923,7 +3280,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( calculateColorForAnnotation( ann ) ); } final String ann_str = ann.asSimpleText().toString(); - TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + TreePanel.HALF_BOX_SIZE, node.getYcoord() + TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g ); _sb.setLength( 0 ); _sb.append( ann_str ); @@ -2944,35 +3301,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( getControlPanel().isShowBinaryCharacters() ) { TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer() - .toString(), node.getXcoord() + x + 1 + TreePanel.HALF_BOX_SIZE, node.getYcoord() + .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g ); paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters() .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters() .getLostCharactersAsStringBuffer().toString() ); } else { - if ( DRAW_MEAN_COUNTS && node.isInternal() ) { - final List ec = node.getAllExternalDescendants(); - double sum = 0; - int count = 0; - for( final PhylogenyNode phylogenyNode : ec ) { - count++; - if ( phylogenyNode.getNodeData().getBinaryCharacters() != null ) { - sum += phylogenyNode.getNodeData().getBinaryCharacters().getPresentCount(); - } - } - final double mean = ForesterUtil.round( sum / count, 1 ); - TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount() + " [" - + mean + "]", node.getXcoord() + x + 4 + TreePanel.HALF_BOX_SIZE, node.getYcoord() - + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g ); - } - else { - TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(), - node.getXcoord() + x + 4 + TreePanel.HALF_BOX_SIZE, - node.getYcoord() - + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), - g ); - } + TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(), + node.getXcoord() + x + 4 + half_box_size, + node.getYcoord() + + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), + g ); paintGainedAndLostCharacters( g, node, "+" + node.getNodeData().getBinaryCharacters().getGainedCount(), "-" + node.getNodeData().getBinaryCharacters().getLostCount() ); @@ -2981,6 +3321,36 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + private 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( getPartAfterColon( p.getRef() ) ); + sb.append( "=" ); + sb.append( p.getValue() ); + if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { + sb.append( getPartAfterColon( p.getUnit() ) ); + } + } + return sb; + } + + final private static String getPartAfterColon( final String s ) { + final int i = s.indexOf( ':' ); + if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) { + return s; + } + return s.substring( i + 1, s.length() ); + } + private double drawTaxonomyImage( final double x, final double y, final PhylogenyNode node, final Graphics2D g ) { final List us = new ArrayList(); for( final Taxonomy t : node.getNodeData().getTaxonomies() ) { @@ -3002,11 +3372,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } // y = y - ( 0.9 * getYdistance() ); final double hs = bi.getHeight() * scaling_factor; - double ws = bi.getWidth() * scaling_factor + offset; + double ws = ( bi.getWidth() * scaling_factor ) + offset; final double my_y = y - ( 0.5 * hs ); final int x_w = ( int ) ( x + ws + 0.5 ); final int y_h = ( int ) ( my_y + hs + 0.5 ); - if ( ( x_w - x > 7 ) && ( y_h - my_y > 7 ) ) { + if ( ( ( x_w - x ) > 7 ) && ( ( y_h - my_y ) > 7 ) ) { g.drawImage( bi, ( int ) ( x + 0.5 + offset ), ( int ) ( my_y + 0.5 ), @@ -3228,7 +3598,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee ++_external_node_index; } // Confidence values - if ( getControlPanel().isShowBootstrapValues() + if ( getControlPanel().isShowConfidenceValues() && !node.isExternal() && !node.isRoot() && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) @@ -3299,11 +3669,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee child_node.setYcoord( y2 ); y2 += _y_distance * child_node.getNumberOfExternalNodes(); } + paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) ); } 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() < getTreeFontSet()._fm_large + && ( ( node.isExternal() && ( ( _external_node_index % dynamic_hiding_factor ) != 1 ) ) || ( !node + .isExternal() && ( ( new_x_min < 20 ) || ( ( _y_distance * node.getNumberOfExternalNodes() ) < getTreeFontSet()._fm_large .getHeight() ) ) ) ) ) { return; } @@ -3330,17 +3701,53 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } catch ( final ClassCastException cce ) { cce.printStackTrace(); - return; } - rds.setRenderingHeight( 6 ); - int x = 0; - if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( node ).length() > 0 ) ) { - x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( node ) + " " ); - } - if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) { - x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " ); + if ( rds != null ) { + rds.setRenderingHeight( 6 ); + int x = 0; + if ( node.getNodeData().isHasTaxonomy() ) { + if ( getControlPanel().isShowTaxonomyCode() + && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) { + x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy() + .getTaxonomyCode() + + " " ); + } + if ( getControlPanel().isShowTaxonomyScientificNames() + && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) ) { + x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy() + .getScientificName() + + " " ); + } + if ( getControlPanel().isShowTaxonomyCommonNames() + && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) ) { + x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy() + .getCommonName() + + " " ); + } + } + if ( node.getNodeData().isHasSequence() ) { + if ( getControlPanel().isShowGeneNames() + && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) ) { + x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + + " " ); + } + if ( getControlPanel().isShowGeneSymbols() + && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) ) { + x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol() + + " " ); + } + if ( getControlPanel().isShowSequenceAcc() + && ( node.getNodeData().getSequence().getAccession() != null ) ) { + x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence() + .getAccession().toString() + + " " ); + } + } + if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) { + x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " ); + } + rds.render( node.getXcoord() + x, node.getYcoord() - 3, g, this, to_pdf ); } - rds.render( node.getXcoord() + x, node.getYcoord() - 3, g, this, to_pdf ); } } ////////////// @@ -3349,18 +3756,20 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final RenderableVector rv = RenderableVector.createInstance( node.getNodeData().getVector(), getStatisticsForExpressionValues(), getConfiguration() ); - int x = 0; - PhylogenyNode my_node = node; - if ( !getControlPanel().isDrawPhylogram() ) { - my_node = getPhylogeny().getFirstExternalNode(); - } - if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( my_node ).length() > 0 ) ) { - x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( my_node ) + " " ); - } - if ( getControlPanel().isShowNodeNames() && ( my_node.getName().length() > 0 ) ) { - x += getTreeFontSet()._fm_large.stringWidth( my_node.getName() + " " ); + if ( rv != null ) { + int x = 0; + PhylogenyNode my_node = node; + if ( !getControlPanel().isDrawPhylogram() ) { + my_node = getPhylogeny().getFirstExternalNode(); + } + if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( my_node ).length() > 0 ) ) { + x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( my_node ) + " " ); + } + if ( getControlPanel().isShowNodeNames() && ( my_node.getName().length() > 0 ) ) { + x += getTreeFontSet()._fm_large.stringWidth( my_node.getName() + " " ); + } + rv.render( my_node.getXcoord() + x, node.getYcoord() - 5, g, this, to_pdf ); } - rv.render( my_node.getXcoord() + x, node.getYcoord() - 5, g, this, to_pdf ); } ////////////// } @@ -3372,8 +3781,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final float y_ratio = ( float ) getHeight() / getVisibleRect().y; final float width = getOvMaxWidth() / w_ratio; final float height = getOvMaxHeight() / h_ratio; - final float x = getVisibleRect().x + getOvXPosition() + getOvMaxWidth() / x_ratio; - final float y = getVisibleRect().y + getOvYPosition() + getOvMaxHeight() / y_ratio; + final float x = getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / x_ratio ); + final float y = getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / y_ratio ); g.setColor( getTreeColorSet().getFoundColor() ); getOvRectangle().setRect( x, y, width, height ); if ( ( width < 6 ) && ( height < 6 ) ) { @@ -3404,6 +3813,9 @@ 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 ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) { + return; + } if ( _control_panel.isShowSequenceRelations() ) { _query_sequence = _control_panel.getSelectedQuerySequence(); } @@ -3471,7 +3883,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( _nodes_in_preorder == null ) { _nodes_in_preorder = new PhylogenyNode[ _phylogeny.getNodeCount() ]; - System.out.println( "total nodes: " + _nodes_in_preorder.length ); int i = 0; for( final PhylogenyNodeIterator it = _phylogeny.iteratorPreorder(); it.hasNext(); ) { _nodes_in_preorder[ i++ ] = it.next(); @@ -3482,8 +3893,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee // paintNodeRectangular( g, it.next(), to_pdf, getControlPanel().isDynamicallyHideData() // && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file ); //} - for( int i = 0; i < _nodes_in_preorder.length; ++i ) { - paintNodeRectangular( g, _nodes_in_preorder[ i ], to_pdf, getControlPanel().isDynamicallyHideData() + for( final PhylogenyNode element : _nodes_in_preorder ) { + paintNodeRectangular( g, element, to_pdf, getControlPanel().isDynamicallyHideData() && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file ); } if ( getOptions().isShowScale() && getControlPanel().isDrawPhylogram() && ( getScaleDistance() > 0.0 ) ) { @@ -3523,7 +3934,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } paintUnrooted( _phylogeny.getRoot(), angle, - ( float ) ( angle + 2 * Math.PI ), + ( float ) ( angle + ( 2 * Math.PI ) ), radial_labels, g, to_pdf, @@ -3544,7 +3955,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.setColor( getTreeColorSet().getOvColor() ); paintUnrootedLite( _phylogeny.getRoot(), angle, - angle + 2 * Math.PI, + angle + ( 2 * Math.PI ), g, ( getUrtFactorOv() / ( getVisibleRect().width / getOvMaxWidth() ) ) ); paintOvRectangle( g ); @@ -3608,8 +4019,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) { // paintNodeLite( g, it.next() ); //} - for( int i = 0; i < _nodes_in_preorder.length; ++i ) { - paintNodeLite( g, _nodes_in_preorder[ i ] ); + for( final PhylogenyNode element : _nodes_in_preorder ) { + paintNodeLite( g, element ); } paintOvRectangle( g ); } @@ -3698,7 +4109,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getTaxonomyColor() ); } - final double start_x = node.getXcoord() + 3 + TreePanel.HALF_BOX_SIZE + x_shift; + final double start_x = node.getXcoord() + 3 + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift; final double start_y = node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0 ) ); _sb.setLength( 0 ); @@ -3797,7 +4208,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( n.isRoot() ) { n.setXcoord( getWidth() / 2 ); n.setYcoord( getHeight() / 2 ); - paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) ); } if ( n.isExternal() ) { paintNodeDataUnrootedCirc( g, @@ -3845,16 +4255,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { length = getUrtFactor(); } - final double mid_angle = current_angle + arc_size / 2; - final float new_x = ( float ) ( x + Math.cos( mid_angle ) * length ); - final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length ); + final double mid_angle = current_angle + ( arc_size / 2 ); + final float new_x = ( float ) ( x + ( Math.cos( mid_angle ) * length ) ); + final float new_y = ( float ) ( y + ( Math.sin( mid_angle ) * length ) ); desc.setXcoord( new_x ); desc.setYcoord( new_y ); - paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) ); paintUnrooted( desc, current_angle, current_angle + arc_size, radial_labels, g, to_pdf, to_graphics_file ); current_angle += arc_size; assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file ); drawLine( x, y, new_x, new_y, g ); + paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) ); + } + if ( n.isRoot() ) { + paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) ); } } @@ -3864,8 +4277,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final Graphics2D g, final float urt_ov_factor ) { if ( n.isRoot() ) { - final int x_pos = ( int ) ( getVisibleRect().x + getOvXPosition() + getOvMaxWidth() / 2 ); - final int y_pos = ( int ) ( getVisibleRect().y + getOvYPosition() + getOvMaxHeight() / 2 ); + final int x_pos = ( int ) ( getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / 2 ) ); + final int y_pos = ( int ) ( getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / 2 ) ); n.setXSecondary( x_pos ); n.setYSecondary( y_pos ); } @@ -3892,9 +4305,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { length = urt_ov_factor; } - final double mid_angle = current_angle + arc_size / 2; - final float new_x = ( float ) ( x + Math.cos( mid_angle ) * length ); - final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length ); + final double mid_angle = current_angle + ( arc_size / 2 ); + final float new_x = ( float ) ( x + ( Math.cos( mid_angle ) * length ) ); + final float new_y = ( float ) ( y + ( Math.sin( mid_angle ) * length ) ); desc.setXSecondary( new_x ); desc.setYSecondary( new_y ); if ( isInFoundNodes( desc ) ) { @@ -3920,7 +4333,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.ERROR_MESSAGE ); return; } - final String label = getASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() ); + final String label = createASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() ); final Object[] options = { "As sibling", "As descendant", "Cancel" }; final int r = JOptionPane.showOptionDialog( this, "How to paste subtree" + label + "?", @@ -3939,7 +4352,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final Phylogeny buffer_phy = getCutOrCopiedTree().copy(); buffer_phy.setAllNodesToNotCollapse(); - buffer_phy.preOrderReId(); + PhylogenyMethods.preOrderReId( buffer_phy ); buffer_phy.setRooted( true ); boolean need_to_show_whole = false; if ( paste_as_sibling ) { @@ -3971,8 +4384,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } node_ids.add( node.getId() ); getCopiedAndPastedNodes().addAll( node_ids ); + setNodeInPreorderToNull(); _phylogeny.externalNodesHaveChanged(); - _phylogeny.hashIDs(); + _phylogeny.clearHashIdToNodeMap(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); setEdited( true ); @@ -3982,6 +4396,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } + @Override final public int print( final Graphics g, final PageFormat page_format, final int page_index ) throws PrinterException { if ( page_index > 0 ) { @@ -4021,7 +4436,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _node_frame_index--; _node_frames[ i ] = null; if ( i < _node_frame_index ) { - for( int j = 0; j < _node_frame_index - 1; j++ ) { + for( int j = 0; j < ( _node_frame_index - 1 ); j++ ) { _node_frames[ j ] = _node_frames[ j + 1 ]; } _node_frames[ _node_frame_index ] = null; @@ -4046,6 +4461,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getPhylogeny().reRoot( node ); getPhylogeny().recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); + setNodeInPreorderToNull(); resetPreferredSize(); getMainPanel().adjustJScrollPane(); repaint(); @@ -4089,7 +4505,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee setPreferredSize( new Dimension( x, y ) ); } - final void setArrowCursor() { + public final void setArrowCursor() { setCursor( ARROW_CURSOR ); repaint(); } @@ -4106,7 +4522,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee getMainPanel().setCutOrCopiedTree( cut_or_copied_tree ); } - final void setEdited( final boolean edited ) { + public final void setEdited( final boolean edited ) { _edited = edited; } @@ -4184,7 +4600,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee * @param x * @param y */ - final void setParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) { + public final void setParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) { // updateStyle(); not needed? if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) { initNodeData(); @@ -4274,7 +4690,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( getMainPanel().getOptions().isAntialiasScreen() ) { - if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) { + if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) + && !getMainPanel().getOptions().isShowDefaultNodeShapes() + && ( ( getControlPanel() != null ) && !getControlPanel().isShowDomainArchitectures() ) ) { _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF ); } else { @@ -4304,10 +4722,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee * @param t * an instance of a Phylogeny */ - final void setTree( final Phylogeny t ) { + public final void setTree( final Phylogeny t ) { + setNodeInPreorderToNull(); _phylogeny = t; } + final void setNodeInPreorderToNull() { + _nodes_in_preorder = null; + } + final void setTreeFile( final File treefile ) { _treefile = treefile; } @@ -4338,7 +4761,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _urt_factor_ov = urt_factor_ov; } - final void setWaitCursor() { + public final void setWaitCursor() { setCursor( WAIT_CURSOR ); repaint(); } @@ -4515,6 +4938,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .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( ")" ); + } + } + } + if ( node.getNodeData().isHasProperties() ) { + final PropertiesMap properties = node.getNodeData().getProperties(); + for( final String ref : properties.getPropertyRefs() ) { + _popup_buffer.append( "\n" ); + final Property p = properties.getProperty( ref ); + _popup_buffer.append( getPartAfterColon( p.getRef() ) ); + _popup_buffer.append( "=" ); + _popup_buffer.append( p.getValue() ); + if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { + _popup_buffer.append( getPartAfterColon( p.getUnit() ) ); + } } } if ( _popup_buffer.length() > 0 ) { @@ -4594,6 +5037,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.WARNING_MESSAGE ); return; } + setNodeInPreorderToNull(); if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) { _sub_phylogenies[ _subtree_index ] = _phylogeny; _sub_phylogenies_temp_roots[ _subtree_index ] = node; @@ -4630,6 +5074,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final void superTree() { + setNodeInPreorderToNull(); final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ]; for( final PhylogenyNode n : temp_root.getDescendants() ) { n.setParent( temp_root ); @@ -4641,8 +5086,48 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final void swap( final PhylogenyNode node ) { + if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) { + return; + } + if ( node.getNumberOfDescendants() > 2 ) { + JOptionPane.showMessageDialog( this, + "Cannot swap descendants of nodes with more than 2 descendants", + "Cannot swap descendants", + JOptionPane.ERROR_MESSAGE ); + return; + } + if ( !node.isExternal() ) { + node.swapChildren(); + setNodeInPreorderToNull(); + _phylogeny.externalNodesHaveChanged(); + _phylogeny.clearHashIdToNodeMap(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + setEdited( true ); + } + repaint(); + } + + final void sortDescendants( final PhylogenyNode node ) { if ( !node.isExternal() ) { - _phylogeny.swapChildren( node ); + DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.TAXONOMY; + if ( ( !getControlPanel().isShowTaxonomyScientificNames() && !getControlPanel().isShowTaxonomyCode() && !getControlPanel() + .isShowTaxonomyCommonNames() ) ) { + if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowGeneNames() || getControlPanel() + .isShowGeneSymbols() ) ) { + pri = DESCENDANT_SORT_PRIORITY.SEQUENCE; + } + else if ( getControlPanel().isShowNodeNames() ) { + pri = DESCENDANT_SORT_PRIORITY.NODE_NAME; + } + } + PhylogenyMethods.sortNodeDescendents( node, pri ); + setNodeInPreorderToNull(); + _phylogeny.externalNodesHaveChanged(); + _phylogeny.clearHashIdToNodeMap(); + _phylogeny.recalculateNumberOfExternalDescendants( true ); + resetNodeIdToDistToLeafMap(); + setEdited( true ); } repaint(); } @@ -4713,7 +5198,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - Util.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); + AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { _control_panel.getColorBranchesCb().setSelected( true ); @@ -4748,7 +5233,7 @@ 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(); @@ -4856,11 +5341,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - synchronized void setImageMap( final Hashtable image_map ) { + public synchronized void setImageMap( final Hashtable image_map ) { getMainPanel().setImageMap( image_map ); } - synchronized Hashtable getImageMap() { + public synchronized Hashtable getImageMap() { return getMainPanel().getImageMap(); } }