下面列出了怎么用java.awt.font.LineMetrics的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* A utility method that draws a string inside a rectangle.
*
* @param g2 the graphics device.
* @param bounds the rectangle.
* @param font the font.
* @param text the text.
*/
private void drawStringInRect(Graphics2D g2, Rectangle2D bounds, Font font,
String text) {
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics(font);
Rectangle2D r = TextUtilities.getTextBounds(text, g2, fm);
double x = bounds.getX();
if (r.getWidth() < bounds.getWidth()) {
x = x + (bounds.getWidth() - r.getWidth()) / 2;
}
LineMetrics metrics = font.getLineMetrics(
text, g2.getFontRenderContext()
);
g2.drawString(
text, (float) x, (float) (bounds.getMaxY()
- this.bottomInnerGap - metrics.getDescent())
);
}
/**
* A utility method that draws a string inside a rectangle.
*
* @param g2 the graphics device.
* @param bounds the rectangle.
* @param font the font.
* @param text the text.
*/
private void drawStringInRect(Graphics2D g2, Rectangle2D bounds, Font font,
String text) {
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics(font);
Rectangle2D r = TextUtilities.getTextBounds(text, g2, fm);
double x = bounds.getX();
if (r.getWidth() < bounds.getWidth()) {
x = x + (bounds.getWidth() - r.getWidth()) / 2;
}
LineMetrics metrics = font.getLineMetrics(
text, g2.getFontRenderContext()
);
g2.drawString(
text, (float) x, (float) (bounds.getMaxY()
- this.bottomInnerGap - metrics.getDescent())
);
}
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0, 0, fpd.width, fpd.height);
g.setColor(Color.RED);
FontRenderContext frc = ((Graphics2D)g).getFontRenderContext();
LineMetrics lm = f.getLineMetrics(fps, frc);
int h = (int)(fpd.height - 20 - lm.getAscent());
g.drawLine(20, h, fpd.width - 20, h);
h = fpd.height - 20;
g.drawLine(20, h, fpd.width - 20, h);
h = (int)(fpd.height - 20 + lm.getDescent());
g.drawLine(20, h, fpd.width - 20, h);
g.setColor(Color.BLACK);
g.setFont(f);
g.drawString(fps, 50, fpd.height - 20);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
/**
* Returns the bounds for the specified text.
*
* @param text the text (<code>null</code> permitted).
* @param g2 the graphics context (not <code>null</code>).
* @param fm the font metrics (not <code>null</code>).
*
* @return The text bounds (<code>null</code> if the <code>text</code>
* argument is <code>null</code>).
*/
public static Rectangle2D getTextBounds(String text, Graphics2D g2,
FontMetrics fm) {
final Rectangle2D bounds;
if (TextUtilities.useFontMetricsGetStringBounds) {
bounds = fm.getStringBounds(text, g2);
// getStringBounds() can return incorrect height for some Unicode
// characters...see bug parade 6183356, let's replace it with
// something correct
LineMetrics lm = fm.getFont().getLineMetrics(text,
g2.getFontRenderContext());
bounds.setRect(bounds.getX(), bounds.getY(), bounds.getWidth(),
lm.getHeight());
}
else {
double width = fm.stringWidth(text);
double height = fm.getHeight();
bounds = new Rectangle2D.Double(0.0, -fm.getAscent(), width,
height);
}
return bounds;
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
/**
* A utility method that draws a string inside a rectangle.
*
* @param g2 the graphics device.
* @param bounds the rectangle.
* @param font the font.
* @param text the text.
*/
private void drawStringInRect(Graphics2D g2, Rectangle2D bounds, Font font,
String text) {
g2.setFont(font);
FontMetrics fm = g2.getFontMetrics(font);
Rectangle2D r = TextUtilities.getTextBounds(text, g2, fm);
double x = bounds.getX();
if (r.getWidth() < bounds.getWidth()) {
x = x + (bounds.getWidth() - r.getWidth()) / 2;
}
LineMetrics metrics = font.getLineMetrics(
text, g2.getFontRenderContext()
);
g2.drawString(
text, (float) x, (float) (bounds.getMaxY()
- this.bottomInnerGap - metrics.getDescent())
);
}
public Rectangle2D getLogicalBounds() {
setFRCTX();
initPositions();
LineMetrics lm = font.getLineMetrics("", frc);
float minX, minY, maxX, maxY;
// horiz only for now...
minX = 0;
minY = -lm.getAscent();
maxX = 0;
maxY = lm.getDescent() + lm.getLeading();
if (glyphs.length > 0) {
maxX = positions[positions.length - 2];
}
return new Rectangle2D.Float(minX, minY, maxX - minX, maxY - minY);
}
/**
* Draws the label for one axis.
*
* @param g2 the graphics device.
* @param plotArea the plot area
* @param value the value of the label (ignored).
* @param cat the category (zero-based index).
* @param startAngle the starting angle.
* @param extent the extent of the arc.
*/
protected void drawLabel(Graphics2D g2, Rectangle2D plotArea, double value,
int cat, double startAngle, double extent) {
FontRenderContext frc = g2.getFontRenderContext();
String label;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
// if series are in rows, then the categories are the column keys
label = this.labelGenerator.generateColumnLabel(this.dataset, cat);
}
else {
// if series are in columns, then the categories are the row keys
label = this.labelGenerator.generateRowLabel(this.dataset, cat);
}
Rectangle2D labelBounds = getLabelFont().getStringBounds(label, frc);
LineMetrics lm = getLabelFont().getLineMetrics(label, frc);
double ascent = lm.getAscent();
Point2D labelLocation = calculateLabelLocation(labelBounds, ascent,
plotArea, startAngle);
Composite saveComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
g2.setPaint(getLabelPaint());
g2.setFont(getLabelFont());
g2.drawString(label, (float) labelLocation.getX(),
(float) labelLocation.getY());
g2.setComposite(saveComposite);
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelWidth(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr, upperStr;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*
* @since 1.0.7
*/
protected double estimateMaximumTickLabelWidth(Graphics2D g2,
TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of the
// font)...
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = "";
String upperStr = "";
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* A utility method for determining the height of the tallest tick label.
*
* @param ticks the ticks.
* @param g2 the graphics device.
* @param drawArea the area within which the plot and axes should be drawn.
* @param vertical a flag that indicates whether or not the tick labels
* are 'vertical'.
*
* @return The height of the tallest tick label.
*/
protected double findMaximumTickLabelHeight(List ticks, Graphics2D g2,
Rectangle2D drawArea, boolean vertical) {
RectangleInsets insets = getTickLabelInsets();
Font font = getTickLabelFont();
g2.setFont(font);
double maxHeight = 0.0;
if (vertical) {
FontMetrics fm = g2.getFontMetrics(font);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
Tick tick = (Tick) iterator.next();
Rectangle2D labelBounds = null;
if (tick instanceof LogTick) {
LogTick lt = (LogTick) tick;
if (lt.getAttributedLabel() != null) {
labelBounds = AttrStringUtils.getTextBounds(
lt.getAttributedLabel(), g2);
}
} else if (tick.getText() != null) {
labelBounds = TextUtilities.getTextBounds(
tick.getText(), g2, fm);
}
if (labelBounds != null && labelBounds.getWidth()
+ insets.getTop() + insets.getBottom() > maxHeight) {
maxHeight = labelBounds.getWidth()
+ insets.getTop() + insets.getBottom();
}
}
} else {
LineMetrics metrics = font.getLineMetrics("ABCxyz",
g2.getFontRenderContext());
maxHeight = metrics.getHeight()
+ insets.getTop() + insets.getBottom();
}
return maxHeight;
}
/**
* Returns the height of the band.
*
* @param g2 the graphics device.
*
* @return The height of the band.
*/
public double getHeight(Graphics2D g2) {
double result = 0.0;
if (this.markers.size() > 0) {
LineMetrics metrics = this.font.getLineMetrics(
"123g", g2.getFontRenderContext()
);
result = this.topOuterGap + this.topInnerGap + metrics.getHeight()
+ this.bottomInnerGap + this.bottomOuterGap;
}
return result;
}
private double drawHeader(Graphics2D g, Rectangle2D clip) {
LineMetrics lineMetrics = getHeaderFooterLineMetrics(g);
double w = clip.getWidth();
double x = clip.getX();
double y = clip.getY();
double h = 0;
boolean wasDrawn = false;
String headerText1 = myPrintSettings.FOOTER_HEADER_TEXT1;
if (headerText1 != null && headerText1.length() > 0 &&
PrintSettings.HEADER.equals(myPrintSettings.FOOTER_HEADER_PLACEMENT1)) {
h = drawHeaderOrFooterLine(g, x, y, w, headerText1, myPrintSettings.FOOTER_HEADER_ALIGNMENT1);
wasDrawn = true;
y += h;
}
String headerText2 = myPrintSettings.FOOTER_HEADER_TEXT2;
if (headerText2 != null && headerText2.length() > 0 &&
PrintSettings.HEADER.equals(myPrintSettings.FOOTER_HEADER_PLACEMENT2)) {
if (PrintSettings.LEFT.equals(myPrintSettings.FOOTER_HEADER_ALIGNMENT1) &&
PrintSettings.RIGHT.equals(myPrintSettings.FOOTER_HEADER_ALIGNMENT2) &&
wasDrawn) {
y -= h;
}
h = drawHeaderOrFooterLine(g, x, y, w, headerText2, myPrintSettings.FOOTER_HEADER_ALIGNMENT2);
y += h;
wasDrawn = true;
}
return wasDrawn ? y - clip.getY() + lineMetrics.getHeight() / 3 : 0;
}
/**
* Returns the height of the band.
*
* @param g2 the graphics device.
*
* @return The height of the band.
*/
public double getHeight(Graphics2D g2) {
double result = 0.0;
if (this.markers.size() > 0) {
LineMetrics metrics = this.font.getLineMetrics(
"123g", g2.getFontRenderContext()
);
result = this.topOuterGap + this.topInnerGap + metrics.getHeight()
+ this.bottomInnerGap + this.bottomOuterGap;
}
return result;
}
/**
* Draws the label for one axis.
*
* @param g2 the graphics device.
* @param plotArea the plot area
* @param value the value of the label (ignored).
* @param cat the category (zero-based index).
* @param startAngle the starting angle.
* @param extent the extent of the arc.
*/
protected void drawLabel(Graphics2D g2, Rectangle2D plotArea, double value,
int cat, double startAngle, double extent) {
FontRenderContext frc = g2.getFontRenderContext();
String label = null;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
// if series are in rows, then the categories are the column keys
label = this.labelGenerator.generateColumnLabel(this.dataset, cat);
}
else {
// if series are in columns, then the categories are the row keys
label = this.labelGenerator.generateRowLabel(this.dataset, cat);
}
Rectangle2D labelBounds = getLabelFont().getStringBounds(label, frc);
LineMetrics lm = getLabelFont().getLineMetrics(label, frc);
double ascent = lm.getAscent();
Point2D labelLocation = calculateLabelLocation(labelBounds, ascent,
plotArea, startAngle);
Composite saveComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
g2.setPaint(getLabelPaint());
g2.setFont(getLabelFont());
g2.drawString(label, (float) labelLocation.getX(),
(float) labelLocation.getY());
g2.setComposite(saveComposite);
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*
* @since 1.0.7
*/
protected double estimateMaximumTickLabelWidth(Graphics2D g2,
TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of the
// font)...
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr = "";
String upperStr = "";
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Draws the label for one axis.
*
* @param g2 the graphics device.
* @param plotArea the plot area
* @param value the value of the label (ignored).
* @param cat the category (zero-based index).
* @param startAngle the starting angle.
* @param extent the extent of the arc.
*/
protected void drawLabel(Graphics2D g2, Rectangle2D plotArea, double value,
int cat, double startAngle, double extent) {
FontRenderContext frc = g2.getFontRenderContext();
String label;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
// if series are in rows, then the categories are the column keys
label = this.labelGenerator.generateColumnLabel(this.dataset, cat);
}
else {
// if series are in columns, then the categories are the row keys
label = this.labelGenerator.generateRowLabel(this.dataset, cat);
}
Rectangle2D labelBounds = getLabelFont().getStringBounds(label, frc);
LineMetrics lm = getLabelFont().getLineMetrics(label, frc);
double ascent = lm.getAscent();
Point2D labelLocation = calculateLabelLocation(labelBounds, ascent,
plotArea, startAngle);
Composite saveComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
g2.setPaint(getLabelPaint());
g2.setFont(getLabelFont());
g2.drawString(label, (float) labelLocation.getX(),
(float) labelLocation.getY());
g2.setComposite(saveComposite);
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
private double estimateMaximumTickLabelWidth(Graphics2D g2,
DateTickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
Font tickLabelFont = getTickLabelFont();
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = tickLabelFont.getLineMetrics("ABCxyz", frc);
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of
// the font)...
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
DateRange range = (DateRange) getRange();
Date lower = range.getLowerDate();
Date upper = range.getUpperDate();
String lowerStr = null;
String upperStr = null;
DateFormat formatter = getDateFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.dateToString(lower);
upperStr = unit.dateToString(upper);
}
FontMetrics fm = g2.getFontMetrics(tickLabelFont);
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Returns the height of the band.
*
* @param g2 the graphics device.
*
* @return The height of the band.
*/
public double getHeight(Graphics2D g2) {
double result = 0.0;
if (this.markers.size() > 0) {
LineMetrics metrics = this.font.getLineMetrics(
"123g", g2.getFontRenderContext()
);
result = this.topOuterGap + this.topInnerGap + metrics.getHeight()
+ this.bottomInnerGap + this.bottomOuterGap;
}
return result;
}
/**
* Returns the height of the band.
*
* @param g2 the graphics device.
*
* @return The height of the band.
*/
public double getHeight(Graphics2D g2) {
double result = 0.0;
if (this.markers.size() > 0) {
LineMetrics metrics = this.font.getLineMetrics(
"123g", g2.getFontRenderContext()
);
result = this.topOuterGap + this.topInnerGap + metrics.getHeight()
+ this.bottomInnerGap + this.bottomOuterGap;
}
return result;
}
/**
* Estimates the maximum width of the tick labels, assuming the specified
* tick unit is used.
* <P>
* Rather than computing the string bounds of every tick on the axis, we
* just look at two values: the lower bound and the upper bound for the
* axis. These two values will usually be representative.
*
* @param g2 the graphics device.
* @param unit the tick unit to use for calculation.
*
* @return The estimated maximum width of the tick labels.
*/
protected double estimateMaximumTickLabelWidth(Graphics2D g2,
TickUnit unit) {
RectangleInsets tickLabelInsets = getTickLabelInsets();
double result = tickLabelInsets.getLeft() + tickLabelInsets.getRight();
if (isVerticalTickLabels()) {
// all tick labels have the same width (equal to the height of the
// font)...
FontRenderContext frc = g2.getFontRenderContext();
LineMetrics lm = getTickLabelFont().getLineMetrics("0", frc);
result += lm.getHeight();
}
else {
// look at lower and upper bounds...
FontMetrics fm = g2.getFontMetrics(getTickLabelFont());
Range range = getRange();
double lower = range.getLowerBound();
double upper = range.getUpperBound();
String lowerStr, upperStr;
NumberFormat formatter = getNumberFormatOverride();
if (formatter != null) {
lowerStr = formatter.format(lower);
upperStr = formatter.format(upper);
}
else {
lowerStr = unit.valueToString(lower);
upperStr = unit.valueToString(upper);
}
double w1 = fm.stringWidth(lowerStr);
double w2 = fm.stringWidth(upperStr);
result += Math.max(w1, w2);
}
return result;
}
/**
* Draws the label for one axis.
*
* @param g2 the graphics device.
* @param plotArea the plot area
* @param value the value of the label (ignored).
* @param cat the category (zero-based index).
* @param startAngle the starting angle.
* @param extent the extent of the arc.
*/
protected void drawLabel(Graphics2D g2, Rectangle2D plotArea, double value,
int cat, double startAngle, double extent) {
FontRenderContext frc = g2.getFontRenderContext();
String label = null;
if (this.dataExtractOrder == TableOrder.BY_ROW) {
// if series are in rows, then the categories are the column keys
label = this.labelGenerator.generateColumnLabel(this.dataset, cat);
}
else {
// if series are in columns, then the categories are the row keys
label = this.labelGenerator.generateRowLabel(this.dataset, cat);
}
Rectangle2D labelBounds = getLabelFont().getStringBounds(label, frc);
LineMetrics lm = getLabelFont().getLineMetrics(label, frc);
double ascent = lm.getAscent();
Point2D labelLocation = calculateLabelLocation(labelBounds, ascent,
plotArea, startAngle);
Composite saveComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
1.0f));
g2.setPaint(getLabelPaint());
g2.setFont(getLabelFont());
g2.drawString(label, (float) labelLocation.getX(),
(float) labelLocation.getY());
g2.setComposite(saveComposite);
}
/**
* Create a simple implementation of a TextSource.
*
* Chars is an array containing clen chars in the context, in
* logical order, contiguously starting at cstart. Start and len
* represent that portion of the context representing the true
* source; start, like cstart, is relative to the start of the
* character array.
*
* Level is the bidi level (0-63 for the entire context. Flags is
* the layout flags. Font is the font, frc is the render context,
* and lm is the line metrics for the entire source text, but not
* necessarily the context.
*/
StandardTextSource(char[] chars,
int start,
int len,
int cstart,
int clen,
int level,
int flags,
Font font,
FontRenderContext frc,
CoreMetrics cm) {
if (chars == null) {
throw new IllegalArgumentException("bad chars: null");
}
if (cstart < 0) {
throw new IllegalArgumentException("bad cstart: " + cstart);
}
if (start < cstart) {
throw new IllegalArgumentException("bad start: " + start + " for cstart: " + cstart);
}
if (clen < 0) {
throw new IllegalArgumentException("bad clen: " + clen);
}
if (cstart + clen > chars.length) {
throw new IllegalArgumentException("bad clen: " + clen + " cstart: " + cstart + " for array len: " + chars.length);
}
if (len < 0) {
throw new IllegalArgumentException("bad len: " + len);
}
if ((start + len) > (cstart + clen)) {
throw new IllegalArgumentException("bad len: " + len + " start: " + start + " for cstart: " + cstart + " clen: " + clen);
}
if (font == null) {
throw new IllegalArgumentException("bad font: null");
}
if (frc == null) {
throw new IllegalArgumentException("bad frc: null");
}
this.chars = chars;
this.start = start;
this.len = len;
this.cstart = cstart;
this.clen = clen;
this.level = level;
this.flags = flags;
this.font = font;
this.frc = frc;
if (cm != null) {
this.cm = cm;
} else {
LineMetrics metrics = font.getLineMetrics(chars, cstart, clen, frc);
this.cm = ((FontLineMetrics)metrics).cm;
}
}
/**
* Create a simple implementation of a TextSource.
*
* Chars is an array containing clen chars in the context, in
* logical order, contiguously starting at cstart. Start and len
* represent that portion of the context representing the true
* source; start, like cstart, is relative to the start of the
* character array.
*
* Level is the bidi level (0-63 for the entire context. Flags is
* the layout flags. Font is the font, frc is the render context,
* and lm is the line metrics for the entire source text, but not
* necessarily the context.
*/
public StandardTextSource(char[] chars,
int start,
int len,
int cstart,
int clen,
int level,
int flags,
Font font,
FontRenderContext frc,
CoreMetrics cm) {
if (chars == null) {
throw new IllegalArgumentException("bad chars: null");
}
if (cstart < 0) {
throw new IllegalArgumentException("bad cstart: " + cstart);
}
if (start < cstart) {
throw new IllegalArgumentException("bad start: " + start + " for cstart: " + cstart);
}
if (clen < 0) {
throw new IllegalArgumentException("bad clen: " + clen);
}
if (cstart + clen > chars.length) {
throw new IllegalArgumentException("bad clen: " + clen + " cstart: " + cstart + " for array len: " + chars.length);
}
if (len < 0) {
throw new IllegalArgumentException("bad len: " + len);
}
if ((start + len) > (cstart + clen)) {
throw new IllegalArgumentException("bad len: " + len + " start: " + start + " for cstart: " + cstart + " clen: " + clen);
}
if (font == null) {
throw new IllegalArgumentException("bad font: null");
}
if (frc == null) {
throw new IllegalArgumentException("bad frc: null");
}
this.chars = chars.clone();
this.start = start;
this.len = len;
this.cstart = cstart;
this.clen = clen;
this.level = level;
this.flags = flags;
this.font = font;
this.frc = frc;
if (cm != null) {
this.cm = cm;
} else {
LineMetrics metrics = font.getLineMetrics(chars, cstart, clen, frc);
this.cm = ((FontLineMetrics)metrics).cm;
}
}
/**
* A utility method that calculates the anchor offsets for a string.
* Normally, the (x, y) coordinate for drawing text is a point on the
* baseline at the left of the text string. If you add these offsets to
* (x, y) and draw the string, then the anchor point should coincide with
* the (x, y) point.
*
* @param g2 the graphics device (not <code>null</code>).
* @param text the text.
* @param anchor the anchor point.
*
* @return The offsets.
*/
private static float[] deriveTextBoundsAnchorOffsets(Graphics2D g2,
String text, TextAnchor anchor) {
float[] result = new float[2];
FontRenderContext frc = g2.getFontRenderContext();
Font f = g2.getFont();
FontMetrics fm = g2.getFontMetrics(f);
Rectangle2D bounds = getTextBounds(text, fm);
LineMetrics metrics = f.getLineMetrics(text, frc);
float ascent = metrics.getAscent();
float halfAscent = ascent / 2.0f;
float descent = metrics.getDescent();
float leading = metrics.getLeading();
float xAdj = 0.0f;
float yAdj = 0.0f;
if (anchor.isHorizontalCenter()) {
xAdj = (float) -bounds.getWidth() / 2.0f;
}
else if (anchor.isRight()) {
xAdj = (float) -bounds.getWidth();
}
if (anchor.isTop()) {
yAdj = -descent - leading + (float) bounds.getHeight();
}
else if (anchor.isHalfAscent()) {
yAdj = halfAscent;
}
else if (anchor.isVerticalCenter()) {
yAdj = -descent - leading + (float) (bounds.getHeight() / 2.0);
}
else if (anchor.isBaseline()) {
yAdj = 0.0f;
}
else if (anchor.isBottom()) {
yAdj = -metrics.getDescent() - metrics.getLeading();
}
result[0] = xAdj;
result[1] = yAdj;
return result;
}