/*
* StatesPainter.java
*
* Copyright (C) 2006-2014 Andrew Rambaut
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package figtree.treeviewer.painters;
import jebl.evolution.graphs.Node;
import jebl.evolution.trees.Tree;
import figtree.treeviewer.decorators.DiscreteColourDecorator;
import java.awt.*;
import java.awt.geom.Rectangle2D;
/**
* @author Andrew Rambaut
* @version $Id$
*
* $HeadURL$
*
* $LastChangedBy$
* $LastChangedDate$
* $LastChangedRevision$
*/
public class StatesPainter extends BasicLabelPainter {
public StatesPainter(String[] annotationNames, DiscreteColourDecorator[] decorators) {
super(PainterIntent.TIP);
this.annotationNames = annotationNames;
this.decorators = decorators;
}
public Rectangle2D calibrate(Graphics2D g2, Node node) {
super.calibrate(g2, node);
int siteCount = annotationNames.length;
// blockSize = super.getPreferredHeight() / 2;
// blockGap = blockSize / 2;
blockSize = super.getPreferredHeight() * 0.8;
blockGap = 1;
width = (siteCount * (blockSize + blockGap)) + blockGap + blockGap;
return new Rectangle2D.Double(0.0, 0.0, getPreferredWidth(), getPreferredHeight());
}
public double getPreferredWidth() {
return super.getPreferredWidth() + width;
}
public void paint(Graphics2D g2, Node node, Justification justification, Rectangle2D bounds) {
Tree tree = getTree();
Stroke oldStroke = g2.getStroke();
Paint oldPaint = g2.getPaint();
float yOffset = (float)getPreferredHeight() / 2;
switch (justification) {
case FLUSH:
case LEFT: {
super.paint(g2, node, justification,
new Rectangle2D.Double(bounds.getX() + width, bounds.getY(), bounds.getWidth() - width, bounds.getHeight()));
double x = blockGap;
int i = 0;
for (String name: annotationNames) {
Object item = tree.getTaxon(node).getAttribute(name);
if (item != null) {
decorators[i].setItem(item);
int state = ((Number)item).intValue();
// Now create a bounds for the label
Rectangle2D block = new Rectangle2D.Double(
x, yOffset - (blockSize / 2.0),
blockSize, blockSize);
g2.setPaint(decorators[i].getPaint(Color.white));
g2.fill(block);
g2.setPaint(Color.white);
g2.setFont(new Font("helvetica", Font.PLAIN, 9));
FontMetrics fm = g2.getFontMetrics();
g2.drawString(Integer.toString(state), (float)(x+1), (float)(yOffset - (blockSize / 2.0) + fm.getAscent() + 1));
g2.setPaint(Color.black);
g2.setFont(new Font("helvetica", Font.PLAIN, 9));
g2.drawString(Integer.toString(state), (float)x, (float)(yOffset - (blockSize / 2.0) + fm.getAscent()));
}
x += blockSize + blockGap;
i++;
}
} break;
case RIGHT: {
super.paint(g2, node, justification,
new Rectangle2D.Double(bounds.getX(), bounds.getY(), bounds.getWidth() - width, bounds.getHeight()));
int i = 0;
for (String name: annotationNames) {
double x = getPreferredWidth() - blockGap - blockSize;
Object item = tree.getTaxon(node).getAttribute(name);
if (item != null) {
decorators[i].setItem(item);
// Now create a bounds for the label
Rectangle2D block = new Rectangle2D.Double(
x, yOffset - (blockSize / 2.0),
blockSize, blockSize);
g2.setPaint(decorators[i].getPaint(Color.white));
g2.fill(block);
x -= (blockSize + blockGap);
i++;
}
}
} break;
default:
throw new IllegalArgumentException("Unrecognized alignment enum option");
}
g2.setStroke(oldStroke);
g2.setPaint(oldPaint);
}
private String[] annotationNames = null;
private DiscreteColourDecorator[] decorators;
private double width;
private double blockSize = 8;
private double blockGap = 2;
}