X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Farchaeopteryx%2FTreePanel.java;h=3ad39351f9b3cc2b4e81eb2fe38aeaee38c3c1a9;hb=7bbb45295594e9574ee64a32fac17a93b5aa6ade;hp=8f8baa4e89fd759bed440cf08b3d8e9052ee0904;hpb=7aa2563168935732ea6d59a3f1c6cd8bf9a4ad61;p=jalview.git diff --git a/forester/java/src/org/forester/archaeopteryx/TreePanel.java b/forester/java/src/org/forester/archaeopteryx/TreePanel.java index 8f8baa4..3ad3935 100644 --- a/forester/java/src/org/forester/archaeopteryx/TreePanel.java +++ b/forester/java/src/org/forester/archaeopteryx/TreePanel.java @@ -34,9 +34,9 @@ import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; -import java.awt.Polygon; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; @@ -54,6 +54,7 @@ import java.awt.geom.Arc2D; import java.awt.geom.CubicCurve2D; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; +import java.awt.geom.Path2D; import java.awt.geom.QuadCurve2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -75,8 +76,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.List; +import java.util.Map.Entry; import java.util.Set; +import java.util.SortedMap; import java.util.SortedSet; +import java.util.TreeMap; import javax.swing.BorderFactory; import javax.swing.JApplet; @@ -130,6 +134,13 @@ import org.forester.util.SequenceIdParser; public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable { + private static final BasicStroke STROKE_2 = new BasicStroke( 2f ); + private static final BasicStroke STROKE_1 = new BasicStroke( 1f ); + private static final BasicStroke STROKE_075 = new BasicStroke( 0.75f ); + private static final BasicStroke STROKE_05 = new BasicStroke( 0.5f ); + private static final BasicStroke STROKE_025 = new BasicStroke( 0.25f ); + private static final BasicStroke STROKE_01 = new BasicStroke( 0.1f ); + private static final BasicStroke STROKE_005 = new BasicStroke( 0.05f ); private static final float PI = ( float ) ( Math.PI ); private static final double TWO_PI = 2 * Math.PI; private static final float ONEHALF_PI = ( float ) ( 1.5 * Math.PI ); @@ -151,7 +162,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private final static NumberFormat FORMATTER_CONFIDENCE; private final static NumberFormat FORMATTER_BRANCH_LENGTH; private final static int WIGGLE = 2; - private final static int LIMIT_FOR_HQ_RENDERING = 1000; + private final static int LIMIT_FOR_HQ_RENDERING = 2000; private final static int CONFIDENCE_LEFT_MARGIN = 4; private final RenderingHints _rendering_hints = new RenderingHints( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT ); @@ -180,7 +191,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee private float _last_drag_point_y = 0; private ControlPanel _control_panel = null; private int _external_node_index = 0; - private final Polygon _polygon = new Polygon(); + private final Path2D.Float _polygon = new Path2D.Float(); private final StringBuilder _sb = new StringBuilder(); private JColorChooser _color_chooser = null; private double _scale_distance = 0.0; @@ -609,8 +620,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getControlPanel().isShowAnnotation() && ( node.getNodeData().getSequence().getAnnotations() != null ) && !node.getNodeData().getSequence().getAnnotations().isEmpty() ) { - sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getAnnotation( 0 ) - .asSimpleText() + sum += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node + .getNodeData().getSequence().getAnnotations(), getOptions().isShowAnnotationRefSource() ) + " " ); } if ( getControlPanel().isShowDomainArchitectures() @@ -688,21 +699,25 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final Color calculateTaxonomyBasedColor( final Taxonomy tax ) { - String species = tax.getTaxonomyCode(); - if ( ForesterUtil.isEmpty( species ) ) { - species = tax.getScientificName(); - if ( ForesterUtil.isEmpty( species ) ) { - species = tax.getCommonName(); - } - } - if ( ForesterUtil.isEmpty( species ) ) { + if ( ForesterUtil.isEmpty( tax.getTaxonomyCode() ) && ForesterUtil.isEmpty( tax.getScientificName() ) ) { return getTreeColorSet().getTaxonomyColor(); } - // Look in species hash - Color c = getControlPanel().getSpeciesColors().get( species ); + Color c = null; + if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) { + c = getControlPanel().getSpeciesColors().get( tax.getTaxonomyCode() ); + } + if ( ( c == null ) && !ForesterUtil.isEmpty( tax.getScientificName() ) ) { + c = getControlPanel().getSpeciesColors().get( tax.getScientificName() ); + } if ( c == null ) { - c = AptxUtil.calculateColorFromString( species ); - getControlPanel().getSpeciesColors().put( species, c ); + if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) { + c = TreePanelUtil.calculateColorFromString( tax.getTaxonomyCode(), true ); + getControlPanel().getSpeciesColors().put( tax.getTaxonomyCode(), c ); + } + else { + c = TreePanelUtil.calculateColorFromString( tax.getScientificName(), true ); + getControlPanel().getSpeciesColors().put( tax.getScientificName(), c ); + } } return c; } @@ -786,7 +801,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !node.isExternal() && !node.isRoot() ) { final boolean collapse = !node.isCollapse(); - AptxUtil.collapseSubtree( node, collapse ); + TreePanelUtil.collapseSubtree( node, collapse ); updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); @@ -805,7 +820,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - AptxUtil.collapseSpeciesSpecificSubtrees( _phylogeny ); + TreePanelUtil.collapseSpeciesSpecificSubtrees( _phylogeny ); updateSetOfCollapsedExternalNodes(); _phylogeny.recalculateNumberOfExternalDescendants( true ); resetNodeIdToDistToLeafMap(); @@ -823,7 +838,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } setWaitCursor(); AptxUtil.removeBranchColors( _phylogeny ); - final int colorizations = AptxUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this ); + final int colorizations = TreePanelUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this ); if ( colorizations > 0 ) { _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { @@ -869,7 +884,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } setWaitCursor(); AptxUtil.removeBranchColors( _phylogeny ); - AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); + TreePanelUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this ); _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { _control_panel.getColorBranchesCb().setSelected( true ); @@ -1521,7 +1536,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height ); } } - g.setStroke( new BasicStroke( 1 ) ); + setupStroke( g ); } else { g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) ); @@ -1874,22 +1889,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } if ( getMainPanel().getOptions().isAntialiasScreen() ) { - if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) - && !getMainPanel().getOptions().isShowDefaultNodeShapesInternal() - && !getMainPanel().getOptions().isShowDefaultNodeShapesExternal() - && ( ( getControlPanel() != null ) && !getControlPanel().isShowDomainArchitectures() ) ) { - _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF ); - } - else { - _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); - } - try { - _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB ); - } - catch ( final Throwable e ) { - _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON ); - } + _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); + // try { + _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB ); + // } + // catch ( final Throwable e ) { + // _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON ); + //} } else { _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF ); @@ -1968,7 +1974,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _sub_phylogenies[ _subtree_index ] = _phylogeny; _sub_phylogenies_temp_roots[ _subtree_index ] = node; ++_subtree_index; - _phylogeny = subTree( node, _phylogeny ); + _phylogeny = TreePanelUtil.subTree( node, _phylogeny ); updateSubSuperTreeButton(); } else if ( node.isRoot() && isCurrentTreeIsSubtree() ) { @@ -2018,7 +2024,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return; } setWaitCursor(); - AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); + TreePanelUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this ); _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { _control_panel.getColorBranchesCb().setSelected( true ); @@ -2328,13 +2334,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( getControlPanel().isColorAccordingToAnnotation() && ( getControlPanel().getAnnotationColors() != null ) ) { final StringBuilder sb = new StringBuilder(); for( final Annotation a : ann ) { - sb.append( !ForesterUtil.isEmpty( a.getRef() ) ? a.getRef() : a.getDesc() ); + sb.append( !ForesterUtil.isEmpty( a.getRefValue() ) ? a.getRefValue() : a.getDesc() ); } final String ann_str = sb.toString(); if ( !ForesterUtil.isEmpty( ann_str ) ) { c = getControlPanel().getAnnotationColors().get( ann_str ); if ( c == null ) { - c = AptxUtil.calculateColorFromString( ann_str ); + c = TreePanelUtil.calculateColorFromString( ann_str, false ); getControlPanel().getAnnotationColors().put( ann_str, c ); } if ( c == null ) { @@ -2367,42 +2373,48 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee JOptionPane.WARNING_MESSAGE ); } - final private void colorizeSubtree( final Color c, final PhylogenyNode node ) { - if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { - JOptionPane.showMessageDialog( this, - "Cannot colorize subtree in unrooted display type", - "Attempt to colorize subtree in unrooted display", - JOptionPane.WARNING_MESSAGE ); - return; - } + final private void colorizeSubtree( final Color c, + final PhylogenyNode node, + final List additional_nodes ) { _control_panel.setColorBranches( true ); if ( _control_panel.getColorBranchesCb() != null ) { _control_panel.getColorBranchesCb().setSelected( true ); } - for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) { - it.next().getBranchData().setBranchColor( new BranchColor( c ) ); + if ( node != null ) { + for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) { + it.next().getBranchData().setBranchColor( new BranchColor( c ) ); + } + } + if ( additional_nodes != null ) { + for( final PhylogenyNode n : additional_nodes ) { + n.getBranchData().setBranchColor( new BranchColor( c ) ); + } } repaint(); } final private void colorSubtree( final PhylogenyNode node ) { - Color intitial_color = null; - if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) - && ( ( ( !node.isRoot() && ( node.getParent().getNumberOfDescendants() < 3 ) ) ) || ( node.isRoot() ) ) ) { - intitial_color = PhylogenyMethods.getBranchColorValue( node ); + if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) { + JOptionPane.showMessageDialog( this, + "Cannot colorize subtree in unrooted display type", + "Attempt to colorize subtree in unrooted display", + JOptionPane.WARNING_MESSAGE ); + return; + } + _color_chooser.setPreviewPanel( new JPanel() ); + SubtreeColorizationActionListener al; + if ( ( getFoundNodes() != null ) && !getFoundNodes().isEmpty() ) { + final List additional_nodes = new ArrayList(); + for( final Long id : getFoundNodes() ) { + additional_nodes.add( _phylogeny.getNode( id ) ); + } + al = new SubtreeColorizationActionListener( _color_chooser, node, additional_nodes ); } else { - intitial_color = getTreeColorSet().getBranchColor(); + al = new SubtreeColorizationActionListener( _color_chooser, node ); } - _color_chooser.setColor( intitial_color ); - _color_chooser.setPreviewPanel( new JPanel() ); final JDialog dialog = JColorChooser - .createDialog( this, - "Subtree colorization", - true, - _color_chooser, - new SubtreeColorizationActionListener( _color_chooser, node ), - null ); + .createDialog( this, "Subtree colorization", true, _color_chooser, al, null ); dialog.setVisible( true ); } @@ -2423,22 +2435,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee repaint(); } - private String createAnnotationString( final SortedSet ann ) { - final StringBuilder sb = new StringBuilder(); - boolean first = true; - for( final Annotation a : ann ) { - if ( !first ) { - sb.append( "|" ); - } - else { - first = false; - } - sb.append( a.asSimpleText() ); - } - final String ann_str = sb.toString(); - return ann_str; - } - final private String createASimpleTextRepresentationOfANode( final PhylogenyNode node ) { final String tax = PhylogenyMethods.getSpecies( node ); String label = node.getName(); @@ -2910,30 +2906,27 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return Blast.isContainsQueryForBlast( node ); } - final private boolean isCanOpenSeqWeb( final PhylogenyNode node ) { - if ( node.getNodeData().isHasSequence() - && ( node.getNodeData().getSequence().getAccession() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getSource() ) - && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getValue() ) - && getConfiguration().isHasWebLink( node.getNodeData().getSequence().getAccession().getSource() - .toLowerCase() ) ) { - return true; + final private String isCanOpenSeqWeb( final PhylogenyNode node ) { + String v = ForesterUtil.extractUniProtKbProteinSeqIdentifier( node ); + if ( ForesterUtil.isEmpty( v ) ) { + v = ForesterUtil.extractGenbankAccessor( node ); + } + if ( ForesterUtil.isEmpty( v ) ) { + v = ForesterUtil.extractRefSeqAccessorAccessor( node ); + } + if ( ForesterUtil.isEmpty( v ) ) { + v = ForesterUtil.extractGInumber( node ); } - return false; + return v; } final private boolean isCanOpenTaxWeb( final PhylogenyNode node ) { if ( node.getNodeData().isHasTaxonomy() - && ( ( ( node.getNodeData().getTaxonomy().getIdentifier() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getProvider() ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && getConfiguration() - .isHasWebLink( node.getNodeData().getTaxonomy().getIdentifier().getProvider().toLowerCase() ) ) - || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) + && ( ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) || ( ( node - .getNodeData().getTaxonomy().getIdentifier() != null ) - && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && node - .getNodeData().getTaxonomy().getIdentifier().getValue().startsWith( "http://" ) ) ) ) { + .getNodeData().getTaxonomy().getIdentifier() != null ) && !ForesterUtil.isEmpty( node + .getNodeData().getTaxonomy().getIdentifier().getValue() ) ) ) ) { return true; } else { @@ -3153,7 +3146,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final String title = clickto_names.get( i ); _node_popup_menu_items[ i ] = new JMenuItem( title ); if ( title.equals( Configuration.clickto_options[ Configuration.open_seq_web ][ 0 ] ) ) { - _node_popup_menu_items[ i ].setEnabled( isCanOpenSeqWeb( node ) ); + final String id = isCanOpenSeqWeb( node ); + if ( !ForesterUtil.isEmpty( id ) ) { + _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + id + "]" ); + _node_popup_menu_items[ i ].setEnabled( true ); + } + else { + _node_popup_menu_items[ i ].setEnabled( false ); + } } else if ( title.equals( Configuration.clickto_options[ Configuration.open_tax_web ][ 0 ] ) ) { _node_popup_menu_items[ i ].setEnabled( isCanOpenTaxWeb( node ) ); @@ -3236,6 +3236,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee return "Scientific Names"; case TAXONOMY_CODE: return "Taxonomy Codes"; + case TAXONOMY_COMM0N_NAME: + return "Taxonomy Common Names"; case UNKNOWN: return "User Selected Data"; default: @@ -3245,35 +3247,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void openSeqWeb( final PhylogenyNode node ) { - if ( !isCanOpenSeqWeb( node ) ) { + if ( ForesterUtil.isEmpty( isCanOpenSeqWeb( node ) ) ) { cannotOpenBrowserWarningMessage( "sequence" ); return; } - String uri_str = null; - final Sequence seq = node.getNodeData().getSequence(); - final String source = seq.getAccession().getSource().toLowerCase(); - String url; - if ( source.toLowerCase().equals( "ncbi" ) ) { - url = Constants.NCBI_ALL_DATABASE_SEARCH; - } - else { - final WebLink weblink = getConfiguration().getWebLink( source ); - url = weblink.getUrl().toString(); - } - try { - uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 ); - } - catch ( final UnsupportedEncodingException e ) { - AptxUtil.showErrorMessage( this, e.toString() ); - e.printStackTrace(); - } + final String uri_str = TreePanelUtil.createUriForSeqWeb( node, getConfiguration(), this ); if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - JApplet applet = null; - if ( isApplet() ) { - applet = obtainApplet(); - } - AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), + isApplet(), + isApplet() ? obtainApplet() : null, + "_aptx_seq" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -3296,32 +3280,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } String uri_str = null; final Taxonomy tax = node.getNodeData().getTaxonomy(); - if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) - && getConfiguration().isHasWebLink( tax.getIdentifier().getProvider().toLowerCase() ) ) { - final String type = tax.getIdentifier().getProvider().toLowerCase(); - final WebLink weblink = getConfiguration().getWebLink( type ); + if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) + && tax.getIdentifier().getValue().startsWith( "http://" ) ) { try { - uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 ); + uri_str = new URI( tax.getIdentifier().getValue() ).toString(); } - catch ( final UnsupportedEncodingException e ) { + catch ( final URISyntaxException e ) { AptxUtil.showErrorMessage( this, e.toString() ); + uri_str = null; e.printStackTrace(); } } - else if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) - && tax.getIdentifier().getValue().startsWith( "http://" ) ) { + else if ( ( tax.getIdentifier() != null ) + && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() ) + && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() ) + && ( tax.getIdentifier().getProvider().equalsIgnoreCase( "ncbi" ) || tax.getIdentifier().getProvider() + .equalsIgnoreCase( "uniprot" ) ) ) { try { - uri_str = new URI( tax.getIdentifier().getValue() ).toString(); + uri_str = "http://www.uniprot.org/taxonomy/" + + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 ); } - catch ( final URISyntaxException e ) { + catch ( final UnsupportedEncodingException e ) { AptxUtil.showErrorMessage( this, e.toString() ); - uri_str = null; e.printStackTrace(); } } else if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) { try { - uri_str = "http://www.eol.org/search?q=" + uri_str = "http://www.uniprot.org/taxonomy/?query=" + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { @@ -3341,7 +3327,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } else if ( !ForesterUtil.isEmpty( tax.getCommonName() ) ) { try { - uri_str = "http://www.eol.org/search?q=" + uri_str = "http://www.uniprot.org/taxonomy/?query=" + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 ); } catch ( final UnsupportedEncodingException e ) { @@ -3351,11 +3337,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } if ( !ForesterUtil.isEmpty( uri_str ) ) { try { - JApplet applet = null; - if ( isApplet() ) { - applet = obtainApplet(); - } - AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" ); + AptxUtil.launchWebBrowser( new URI( uri_str ), + isApplet(), + isApplet() ? obtainApplet() : null, + "_aptx_tax" ); } catch ( final IOException e ) { AptxUtil.showErrorMessage( this, e.toString() ); @@ -3665,30 +3650,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { d = ( Math.log10( d ) * _y_distance ) / 2.5; } - final int box_size = getOptions().getDefaultNodeShapeSize(); + final int box_size = getOptions().getDefaultNodeShapeSize() + 1; if ( d < box_size ) { d = box_size; } + final float xx = node.getXcoord() - ( 2 * box_size ); + final float xxx = xx > node.getParent().getXcoord() + 1 ? xx : node.getParent().getXcoord() + 1; _polygon.reset(); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ), - ForesterUtil.roundToInt( node.getYcoord() ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), - ForesterUtil.roundToInt( node.getYcoord() - d ) ); - _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ), - ForesterUtil.roundToInt( node.getYcoord() + d ) ); + _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() == NodeVisualization.NodeFill.SOLID ) { g.setColor( c ); - g.fillPolygon( _polygon ); + g.fill( _polygon ); } else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) { g.setColor( getBackground() ); - g.fillPolygon( _polygon ); + g.fill( _polygon ); g.setColor( c ); - g.drawPolygon( _polygon ); + g.draw( _polygon ); } else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) { - g.setPaint( new GradientPaint( node.getXcoord() - box_size, node.getYcoord(), getBackground(), ( node - .getXcoord() + box_size ), ( float ) ( node.getYcoord() - d ), c, false ) ); + g.setPaint( new GradientPaint( xxx, node.getYcoord(), getBackground(), node.getXcoord(), ( float ) ( node + .getYcoord() - d ), c, false ) ); g.fill( _polygon ); g.setPaint( c ); g.draw( _polygon ); @@ -3833,7 +3818,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) { outline_color = Color.BLACK; } - else if ( getControlPanel().isEvents() && AptxUtil.isHasAssignedEvent( node ) ) { + else if ( getControlPanel().isEvents() && TreePanelUtil.isHasAssignedEvent( node ) ) { final Event event = node.getNodeData().getEvent(); if ( event.isDuplication() ) { outline_color = getTreeColorSet().getDuplicationBoxColor(); @@ -3940,6 +3925,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) { return; } + _sb.setLength( 0 ); int x = 0; final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2; if ( getControlPanel().isShowTaxonomyImages() @@ -3978,11 +3964,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getSequenceColor() ); } - _sb.setLength( 0 ); if ( node.isCollapse() && ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) ) { - _sb.append( " [" ); - _sb.append( node.getAllExternalDescendants().size() ); - _sb.append( "]" ); + if ( _sb.length() > 0 ) { + _sb.setLength( 0 ); + _sb.append( "(" ); + _sb.append( node.getAllExternalDescendants().size() ); + _sb.append( ")" ); + } + } + else { + _sb.setLength( 0 ); } if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) { if ( _sb.length() > 0 ) { @@ -4110,7 +4101,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else if ( getControlPanel().isColorAccordingToAnnotation() ) { g.setColor( calculateColorForAnnotation( ann ) ); } - final String ann_str = createAnnotationString( ann ); + final String ann_str = TreePanelUtil.createAnnotationString( ann, getOptions().isShowAnnotationRefSource() ); TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g ); _sb.setLength( 0 ); @@ -4292,7 +4283,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final private void paintNodeLite( final Graphics2D g, final PhylogenyNode node ) { if ( node.isCollapse() ) { - if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) { + if ( !node.isRoot() && !node.getParent().isCollapse() ) { paintCollapsedNode( g, node, false, false, false ); } return; @@ -4346,7 +4337,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final boolean to_graphics_file ) { final boolean is_in_found_nodes = isInFoundNodes( node ) || isInCurrentExternalNodes( node ); if ( node.isCollapse() ) { - if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) { + if ( ( !node.isRoot() && !node.getParent().isCollapse() ) ) { paintCollapsedNode( g, node, to_graphics_file, to_pdf, is_in_found_nodes ); } return; @@ -4500,6 +4491,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .getAccession().toString() + " " ); } + if ( getControlPanel().isShowAnnotation() + && ( node.getNodeData().getSequence().getAnnotations() != null ) + && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) { + x += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node + .getNodeData().getSequence().getAnnotations(), getOptions() + .isShowAnnotationRefSource() ) + + " " ); + } } if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) { x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " ); @@ -4533,16 +4532,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } final private void paintOvRectangle( final Graphics2D g ) { - final float w_ratio = ( float ) getWidth() / getVisibleRect().width; - final float h_ratio = ( float ) getHeight() / getVisibleRect().height; - final float x_ratio = ( float ) getWidth() / getVisibleRect().x; - final float y_ratio = ( float ) getHeight() / getVisibleRect().y; + final float w_ratio = ( ( float ) getWidth() ) / getVisibleRect().width; + final float h_ratio = ( ( float ) getHeight() ) / getVisibleRect().height; + final float x_ratio = ( ( float ) getWidth() ) / getVisibleRect().x; + final float y_ratio = ( ( float ) getHeight() ) / getVisibleRect().y; final float width = getOvMaxWidth() / w_ratio; final float height = getOvMaxHeight() / h_ratio; final float x = getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / x_ratio ); final float y = getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / y_ratio ); g.setColor( getTreeColorSet().getFoundColor() ); getOvRectangle().setRect( x, y, width, height ); + final Stroke s = g.getStroke(); + g.setStroke( STROKE_1 ); if ( ( width < 6 ) && ( height < 6 ) ) { drawRectFilled( x, y, 6, 6, g ); getOvVirtualRectangle().setRect( x, y, 6, 6 ); @@ -4562,6 +4563,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } getOvVirtualRectangle().setRect( x, y, width, height ); } + g.setStroke( s ); } final private void paintPhylogenyLite( final Graphics2D g ) { @@ -4570,9 +4572,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee .setXSecondary( ( float ) ( getVisibleRect().x + getOvXPosition() + ( MOVE / ( getVisibleRect().width / getOvRectangle() .getWidth() ) ) ) ); _phylogeny.getRoot().setYSecondary( ( getVisibleRect().y + getOvYStart() ) ); + final Stroke s = g.getStroke(); + g.setStroke( STROKE_05 ); for( final PhylogenyNode element : _nodes_in_preorder ) { paintNodeLite( g, element ); } + g.setStroke( s ); paintOvRectangle( g ); } @@ -4624,12 +4629,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee else { g.setColor( getTreeColorSet().getBranchLengthColor() ); } + final Stroke s = g.getStroke(); + g.setStroke( STROKE_1 ); drawLine( x1, y1, x1, y2, g ); drawLine( x2, y1, x2, y2, g ); drawLine( x1, y3, x2, y3, g ); if ( getScaleLabel() != null ) { g.drawString( getScaleLabel(), ( x1 + 2 ), y3 - 2 ); } + g.setStroke( s ); } final private int paintTaxonomy( final Graphics2D g, @@ -4948,11 +4956,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee sb.append( " " ); } final Property p = properties.getProperty( ref ); - sb.append( getPartAfterColon( p.getRef() ) ); + sb.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); sb.append( "=" ); sb.append( p.getValue() ); if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - sb.append( getPartAfterColon( p.getUnit() ) ); + sb.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); } } return sb; @@ -5010,6 +5018,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee _scale_label = scale_label; } + private final void setupStroke( final Graphics2D g ) { + if ( getYdistance() < 0.001 ) { + g.setStroke( STROKE_005 ); + } + else if ( getYdistance() < 0.01 ) { + g.setStroke( STROKE_01 ); + } + else if ( getYdistance() < 0.5 ) { + g.setStroke( STROKE_025 ); + } + else if ( getYdistance() < 1 ) { + g.setStroke( STROKE_05 ); + } + else if ( getYdistance() < 2 ) { + g.setStroke( STROKE_075 ); + } + else if ( getYdistance() < 20 ) { + g.setStroke( STROKE_1 ); + } + else { + g.setStroke( STROKE_2 ); + } + } + final private void setUpUrtFactor() { final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width : getVisibleRect().height; @@ -5067,14 +5099,44 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee final StringBuilder sb = new StringBuilder(); if ( n.getNodeData().isHasSequence() && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) { + final StringBuilder ann = new StringBuilder(); + if ( !ForesterUtil.isEmpty( n.getName() ) ) { + ann.append( n.getName() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) { + ann.append( "SYM=" ); + ann.append( n.getNodeData().getSequence().getSymbol() ); + ann.append( "|" ); + } if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) { - sb.append( SequenceWriter.toFasta( n.getNodeData().getSequence().getName(), n.getNodeData() - .getSequence().getMolecularSequence(), 60 ) ); + ann.append( "NAME=" ); + ann.append( n.getNodeData().getSequence().getName() ); + ann.append( "|" ); } - else { - sb.append( SequenceWriter.toFasta( n.getName(), n.getNodeData().getSequence() - .getMolecularSequence(), 60 ) ); + if ( n.getNodeData().getSequence().getAccession() != null ) { + ann.append( "ACC=" ); + ann.append( n.getNodeData().getSequence().getAccession().asText() ); + ann.append( "|" ); + } + if ( n.getNodeData().isHasTaxonomy() ) { + if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { + ann.append( "TAXID=" ); + ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() ); + ann.append( "|" ); + } + if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) { + ann.append( "SN=" ); + ann.append( n.getNodeData().getTaxonomy().getScientificName() ); + ann.append( "|" ); + } + } + String ann_str = ann.toString().trim(); + if ( ann_str.endsWith( "|" ) ) { + ann_str = ann_str.substring( 0, ann_str.length() - 1 ); } + sb.append( SequenceWriter.toFasta( ann_str, n.getNodeData().getSequence() + .getMolecularSequence(), 60 ) ); data.add( sb.toString() ); } break; @@ -5090,6 +5152,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee data.add( n.getNodeData().getTaxonomy().getScientificName() ); } break; + case TAXONOMY_COMM0N_NAME: + if ( n.getNodeData().isHasTaxonomy() + && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) { + data.add( n.getNodeData().getTaxonomy().getCommonName() ); + } + break; case TAXONOMY_CODE: if ( n.getNodeData().isHasTaxonomy() && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) { @@ -5097,24 +5165,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } break; case UNKNOWN: - AptxUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data ); + TreePanelUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data ); break; default: throw new IllegalArgumentException( "unknown data element: " + getOptions().getExtDescNodeDataToReturn() ); } } // for loop + final StringBuilder sb = new StringBuilder(); + final int size = makeSB( data, getOptions(), sb ); if ( ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) || ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.BUFFER_ONLY ) ) { - final StringBuilder sb = new StringBuilder(); - for( final String d : data ) { - if ( !ForesterUtil.isEmpty( d ) ) { - if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) { - System.out.println( d ); - } - sb.append( d ); - sb.append( ForesterUtil.LINE_SEPARATOR ); - } + if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) { + System.out.println( sb ); } if ( sb.length() < 1 ) { clearCurrentExternalNodesDataBuffer(); @@ -5124,25 +5187,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) { - final StringBuilder sb = new StringBuilder(); - for( final String d : data ) { - if ( !ForesterUtil.isEmpty( d ) ) { - sb.append( d ); - sb.append( ForesterUtil.LINE_SEPARATOR ); - } - } if ( sb.length() < 1 ) { - AptxUtil.showInformationMessage( this, - "No Appropriate Data (" + obtainTitleForExtDescNodeData() + ")", - "Descendants of selected node do not contain selected data" ); + TreePanelUtil.showInformationMessage( this, "No Appropriate Data (" + obtainTitleForExtDescNodeData() + + ")", "Descendants of selected node do not contain selected data" ); clearCurrentExternalNodesDataBuffer(); } else { setCurrentExternalNodesDataBuffer( sb ); - final String title = "External Descendants " - + ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" - : obtainTitleForExtDescNodeData() ) + " (" + data.size() + "/" - + node.getNumberOfExternalNodes() + ") For Node " + node; + final String title = ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data" + : obtainTitleForExtDescNodeData() ) + + " for " + + data.size() + + "/" + + node.getNumberOfExternalNodes() + + " external descendats of node " + + node + + ", unique entries: " + size; final String s = sb.toString().trim(); if ( getMainPanel().getMainFrame() == null ) { // Must be "E" applet version. @@ -5156,20 +5216,62 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } + private int makeSB( final List data, final Options optz, final StringBuilder sb ) { + final SortedMap map = new TreeMap(); + if ( ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ ) + && ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ_FASTA ) ) { + for( final String d : data ) { + if ( !ForesterUtil.isEmpty( d ) ) { + if ( map.containsKey( d ) ) { + map.put( d, map.get( d ) + 1 ); + } + else { + map.put( d, 1 ); + } + } + } + } + int size = 0; + if ( ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ ) + && ( optz.getExtDescNodeDataToReturn() != NODE_DATA.SEQUENCE_MOL_SEQ_FASTA ) ) { + for( final Entry e : map.entrySet() ) { + final String v = e.getKey(); + final Object c = e.getValue(); + sb.append( v ); + sb.append( "\t" ); + sb.append( c ); + sb.append( ForesterUtil.LINE_SEPARATOR ); + } + size = map.size(); + } + else { + for( final String d : data ) { + if ( !ForesterUtil.isEmpty( d ) ) { + sb.append( d ); + sb.append( ForesterUtil.LINE_SEPARATOR ); + } + } + size = data.size(); + } + return size; + } + final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) { try { if ( ( node.getName().length() > 0 ) - || ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) - || ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) ) - || ( node.getNodeData().isHasDate() ) || ( node.getNodeData().isHasDistribution() ) - || node.getBranchData().isHasConfidences() ) { + || ( node.getNodeData().isHasTaxonomy() && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData() + .getTaxonomy() ) ) + || ( node.getNodeData().isHasSequence() && !TreePanelUtil.isSequenceEmpty( node.getNodeData() + .getSequence() ) ) || ( node.getNodeData().isHasDate() ) + || ( node.getNodeData().isHasDistribution() ) || node.getBranchData().isHasConfidences() ) { _popup_buffer.setLength( 0 ); short lines = 0; if ( node.getName().length() > 0 ) { lines++; _popup_buffer.append( node.getName() ); } - if ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) { + if ( node.getNodeData().isHasTaxonomy() + && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) { lines++; boolean enc_data = false; final Taxonomy tax = node.getNodeData().getTaxonomy(); @@ -5251,7 +5353,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } } - if ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) ) { + if ( node.getNodeData().isHasSequence() + && !TreePanelUtil.isSequenceEmpty( node.getNodeData().getSequence() ) ) { lines++; boolean enc_data = false; if ( _popup_buffer.length() > 0 ) { @@ -5330,11 +5433,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee for( final String ref : properties.getPropertyRefs() ) { _popup_buffer.append( "\n" ); final Property p = properties.getProperty( ref ); - _popup_buffer.append( getPartAfterColon( p.getRef() ) ); + _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getRef() ) ); _popup_buffer.append( "=" ); _popup_buffer.append( p.getValue() ); if ( !ForesterUtil.isEmpty( p.getUnit() ) ) { - _popup_buffer.append( getPartAfterColon( p.getUnit() ) ); + _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) ); } } } @@ -5454,70 +5557,39 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee } } - final private static void drawString( final int i, final double x, final double y, final Graphics2D g ) { - g.drawString( String.valueOf( i ), ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) ); - } - final private static void drawString( final String str, final double x, final double y, final Graphics2D g ) { g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) ); } - final private static String getPartAfterColon( final String s ) { - final int i = s.indexOf( ':' ); - if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) { - return s; - } - return s.substring( i + 1, s.length() ); - } - - final private static boolean isSequenceEmpty( final Sequence seq ) { - return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() ) - && ForesterUtil.isEmpty( seq.getSymbol() ); - } - - final private static boolean isTaxonomyEmpty( final Taxonomy tax ) { - return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() ) - && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) && tax - .getSynonyms().isEmpty() ); - } - final private static boolean plusPressed( final int key_code ) { return ( ( key_code == KeyEvent.VK_ADD ) || ( key_code == KeyEvent.VK_PLUS ) || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) || ( key_code == KeyEvent.VK_1 ) ); } - final private static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) { - final Phylogeny new_phy = new Phylogeny(); - new_phy.setRooted( true ); - new_phy.setName( source_phy.getName() ); - new_phy.setDescription( source_phy.getDescription() ); - new_phy.setType( source_phy.getType() ); - new_phy.setDistanceUnit( source_phy.getDistanceUnit() ); - new_phy.setConfidence( source_phy.getConfidence() ); - new_phy.setIdentifier( source_phy.getIdentifier() ); - new_phy.setRoot( new_root.copyNodeDataShallow() ); - int i = 0; - for( final PhylogenyNode n : new_root.getDescendants() ) { - new_phy.getRoot().setChildNode( i++, n ); - } - return new_phy; - } - final private class SubtreeColorizationActionListener implements ActionListener { - JColorChooser _chooser; - PhylogenyNode _node; + JColorChooser _chooser = null; + PhylogenyNode _node = null; + List _additional_nodes = null; SubtreeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) { _chooser = chooser; _node = node; } + SubtreeColorizationActionListener( final JColorChooser chooser, + final PhylogenyNode node, + final List additional_nodes ) { + _chooser = chooser; + _node = node; + _additional_nodes = additional_nodes; + } + @Override public void actionPerformed( final ActionEvent e ) { final Color c = _chooser.getColor(); if ( c != null ) { - colorizeSubtree( c, _node ); + colorizeSubtree( c, _node, _additional_nodes ); } } }