/*
* BioJava development code
*
* This code may be freely distributed and modified under the
* terms of the GNU Lesser General Public Licence. This should
* be distributed with the code. If you do not have a copy,
* see:
*
* http://www.gnu.org/copyleft/lesser.html
*
* Copyright for this code is held jointly by the individual
* authors. These should be listed in @author doc comments.
*
* For more information on the BioJava project and its aims,
* or to join the biojava-l mailing list, visit the home page
* at:
*
* http://www.biojava.org/
*
*/
package org.biojava.bio.gui.sequence;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.List;
import org.biojava.bio.BioRuntimeException;
import org.biojava.bio.seq.io.SymbolTokenization;
import org.biojava.bio.symbol.Location;
import org.biojava.bio.symbol.SymbolList;
/**
* SymbolSequenceRenderer
renders symbols of a
* SymbolList
.
*
* @author Matthew Pocock
* @author Thomas Down
* @author David Huen
* @author Keith James
* @author Kalle Näslund
*/
public class SymbolSequenceRenderer implements SequenceRenderer
{
private double depth = 25.0;
private Paint outline;
public SymbolSequenceRenderer()
{
outline = Color.black;
}
public double getDepth(SequenceRenderContext context)
{
return depth + 1.0;
}
public double getMinimumLeader(SequenceRenderContext context)
{
return 0.0;
}
public double getMinimumTrailer(SequenceRenderContext context)
{
return 0.0;
}
public void paint(Graphics2D g2, SequenceRenderContext context)
{
Rectangle2D prevClip = g2.getClipBounds();
AffineTransform prevTransform = g2.getTransform();
g2.setPaint(outline);
Font font = context.getFont();
Rectangle2D maxCharBounds =
font.getMaxCharBounds(g2.getFontRenderContext());
double scale = context.getScale();
if (scale >= (maxCharBounds.getWidth() * 0.3) &&
scale >= (maxCharBounds.getHeight() * 0.3))
{
double xFontOffset = 0.0;
double yFontOffset = 0.0;
// These offsets are not set quite correctly yet. The
// Rectangle2D from getMaxCharBounds() seems slightly
// off. The "correct" application of translations based on
// the Rectangle2D seem to give the wrong results. The
// values below are mostly fudges.
if (context.getDirection() == SequenceRenderContext.HORIZONTAL)
{
xFontOffset = maxCharBounds.getCenterX() * 0.25;
yFontOffset = - maxCharBounds.getCenterY() + (depth * 0.5);
}
else
{
xFontOffset = - maxCharBounds.getCenterX() + (depth * 0.5);
yFontOffset = - maxCharBounds.getCenterY() * 3.0;
}
SymbolList seq = context.getSymbols();
SymbolTokenization toke = null;
try {
toke = seq.getAlphabet().getTokenization("token");
} catch (Exception ex) {
throw new BioRuntimeException(ex);
}
Location visible = GUITools.getVisibleRange(context, g2);
for (int sPos = visible.getMin(); sPos <= visible.getMax(); sPos++)
{
double gPos = context.sequenceToGraphics(sPos);
String s = "?";
try {
s = toke.tokenizeSymbol(seq.symbolAt(sPos));
} catch (Exception ex) {
// We'll ignore the case of not being able to tokenize it
}
if (context.getDirection() == SequenceRenderContext.HORIZONTAL)
{
g2.drawString(s,
(float) (gPos + xFontOffset),
(float) yFontOffset);
}
else
{
g2.drawString(s,
(float) xFontOffset,
(float) (gPos + yFontOffset));
}
}
}
g2.setClip(prevClip);
g2.setTransform(prevTransform);
}
public SequenceViewerEvent processMouseEvent(SequenceRenderContext context,
MouseEvent me,
List path)
{
path.add(this);
int sPos = context.graphicsToSequence(me.getPoint());
return new SequenceViewerEvent(this, null, sPos, me, path);
}
}