📄 standardlegend.java
字号:
private Rectangle2D calcRemainingDrawingArea(Rectangle2D available,
boolean horizontal, boolean inverted, RectangularShape legendArea) {
if (horizontal) {
// The remaining drawing area bounding box will have the same
// x origin, width and height independent of the anchor's
// location. The variable is the y coordinate. If the anchor is
// SOUTH, the y coordinate is simply the original y coordinate
// of the available area. If it is NORTH, we adjust original y
// by the total height of the legend and the initial gap.
double yy = available.getY();
double yloc = (inverted) ? yy
: yy + legendArea.getHeight()
+ getOuterGap().getBottomSpace(available.getHeight());
// return the remaining available drawing area
return new Rectangle2D.Double(available.getX(), yloc, available.getWidth(),
available.getHeight() - legendArea.getHeight()
- getOuterGap().getTopSpace(available.getHeight())
- getOuterGap().getBottomSpace(available.getHeight()));
}
else {
// The remaining drawing area bounding box will have the same
// y origin, width and height independent of the anchor's
// location. The variable is the x coordinate. If the anchor is
// EAST, the x coordinate is simply the original x coordinate
// of the available area. If it is WEST, we adjust original x
// by the total width of the legend and the initial gap.
double xloc = (inverted) ? available.getX()
: available.getX()
+ legendArea.getWidth()
+ getOuterGap().getLeftSpace(available.getWidth())
+ getOuterGap().getRightSpace(available.getWidth());
// return the remaining available drawing area
return new Rectangle2D.Double(xloc, available.getY(),
available.getWidth() - legendArea.getWidth()
- getOuterGap().getLeftSpace(available.getWidth())
- getOuterGap().getRightSpace(available.getWidth()),
available.getHeight());
}
}
/**
* Returns a list of drawable legend items for the specified legend item.
* Word-wrapping is applied to the specified legend item and it is broken
* into a few lines in order to fit into the specified
* <code>wordWrapWidth</code>.
*
* @param g2 the graphics context.
* @param legendItem the legend item.
* @param x the upper left x coordinate for the bounding box.
* @param y the upper left y coordinate for the bounding box.
* @param wordWrapWidth the word wrap width.
*
* @return A list of drawable legend items for the specified legend item.
*
* @see #setPreferredWidth(double)
*/
private List createAllDrawableLinesForItem(Graphics2D g2,
LegendItem legendItem, double x, double y, double wordWrapWidth) {
List drawableParts = new ArrayList();
DrawableLegendItem line = createDrawableLegendItem(g2, legendItem, x, y);
if (line.getWidth() < wordWrapWidth) {
// we don't need word-wrapping, return just a single line.
drawableParts.add(line);
return drawableParts;
}
// we need word-wrapping. start laying out the lines. add words to
// every line until it's full.
boolean firstLine = true;
double totalHeight = y;
String prefix = "";
String suffix = legendItem.getLabel().trim();
LegendItem tmpItem = new LegendItem(
prefix.trim(),
legendItem.getLabel(),
legendItem.getShape(),
legendItem.isShapeFilled(),
legendItem.getPaint(),
legendItem.getStroke(),
legendItem.getOutlinePaint(),
legendItem.getOutlineStroke()
);
line = createDrawableLegendItem(g2, tmpItem, x, totalHeight);
DrawableLegendItem goodLine = null; // no good known line yet.
do {
// save the suffix, we might need to restore it.
String prevSuffix = suffix;
// try to extend the prefix.
int spacePos = suffix.indexOf(" ");
if (spacePos < 0) {
// no space found, append all the suffix to the prefix.
prefix += suffix;
suffix = "";
}
else {
// move a word from suffix to prefix.
prefix += suffix.substring(0, spacePos + 1);
suffix = suffix.substring(spacePos + 1);
}
// Create a temporary legend item for the extended prefix.
// If first line, make its marker visible. Otherwise, paint marker
// in background paint.
Paint background = getBackgroundPaint();
tmpItem = new LegendItem(
prefix.trim(),
legendItem.getLabel(),
legendItem.getShape(),
legendItem.isShapeFilled(),
firstLine ? legendItem.getPaint() : background,
legendItem.getStroke(),
firstLine ? legendItem.getOutlinePaint() : background,
legendItem.getOutlineStroke());
// and create a line for it as well.
line = createDrawableLegendItem(g2, tmpItem, x, totalHeight);
// now check if line fits in width.
if (line.getWidth() < wordWrapWidth) {
// fits! save it as the last good known line.
goodLine = line;
}
else {
// doesn't fit. do we have a saved good line?
if (goodLine == null) {
// nope. this means we will have to add it anyway and exceed
// the desired wordWrapWidth. life is tough sometimes...
drawableParts.add(line);
totalHeight += line.getHeight();
}
else {
// yep, we have a saved good line, and we intend to use it...
drawableParts.add(goodLine);
totalHeight += goodLine.getHeight();
// restore previous suffix.
suffix = prevSuffix;
}
// prepare to start a new line.
firstLine = false;
prefix = "";
suffix = suffix.trim();
line = null; // mark as used to avoid using twice.
goodLine = null; // mark as used to avoid using twice.
}
}
while (!suffix.equals(""));
// make sure not to forget last line.
if (line != null) {
drawableParts.add(line);
}
return drawableParts;
}
/**
* Creates a drawable legend item.
* <P>
* The marker box for each entry will be positioned next to the name of the
* specified series within the legend area. The marker box will be square
* and 70% of the height of current font.
*
* @param graphics the graphics context (supplies font metrics etc.).
* @param legendItem the legend item.
* @param x the upper left x coordinate for the bounding box.
* @param y the upper left y coordinate for the bounding box.
*
* @return A legend item encapsulating all necessary info for drawing.
*/
private DrawableLegendItem createDrawableLegendItem(Graphics2D graphics,
LegendItem legendItem,
double x, double y) {
LOGGER.debug("In createDrawableLegendItem(x = " + x + ", y = " + y);
int insideGap = 2;
FontMetrics fm = graphics.getFontMetrics();
LineMetrics lm = fm.getLineMetrics(legendItem.getLabel(), graphics);
float textAscent = lm.getAscent();
float lineHeight = textAscent + lm.getDescent() + lm.getLeading();
DrawableLegendItem item = new DrawableLegendItem(legendItem);
float xLabelLoc = (float) (x + insideGap + 1.15f * lineHeight);
float yLabelLoc = (float) (y + insideGap + 0.5f * lineHeight);
item.setLabelPosition(new Point2D.Float(xLabelLoc, yLabelLoc));
float width = (float) (item.getLabelPosition().getX() - x
+ fm.stringWidth(legendItem.getLabel()) + 0.5 * textAscent);
float height = (2 * insideGap + lineHeight);
item.setBounds(x, y, width, height);
float boxDim = lineHeight * 0.70f;
float xloc = (float) (x + insideGap + 0.15f * lineHeight);
float yloc = (float) (y + insideGap + 0.15f * lineHeight);
if (this.displaySeriesLines) {
Line2D line = new Line2D.Float(
xloc, yloc + boxDim / 2, xloc + boxDim * 3, yloc + boxDim / 2
);
item.setLineStroke(legendItem.getStroke());
item.setLine(line);
// lengthen the bounds to accomodate the longer item
item.setBounds(
item.getX(), item.getY(), item.getWidth() + boxDim * 2, item.getHeight()
);
item.setLabelPosition(new Point2D.Float(xLabelLoc + boxDim * 2, yLabelLoc));
if (this.displaySeriesShapes) {
Shape marker = legendItem.getShape();
AffineTransform t1 = AffineTransform.getScaleInstance(
this.shapeScaleX, this.shapeScaleY
);
Shape s1 = t1.createTransformedShape(marker);
AffineTransform transformer = AffineTransform.getTranslateInstance(
xloc + (boxDim * 1.5), yloc + boxDim / 2);
Shape s2 = transformer.createTransformedShape(s1);
item.setMarker(s2);
}
}
else {
if (this.displaySeriesShapes) {
Shape marker = legendItem.getShape();
AffineTransform t1 = AffineTransform.getScaleInstance(
this.shapeScaleX, this.shapeScaleY
);
Shape s1 = t1.createTransformedShape(marker);
AffineTransform transformer = AffineTransform.getTranslateInstance(
xloc + boxDim / 2, yloc + boxDim / 2);
Shape s2 = transformer.createTransformedShape(s1);
item.setMarker(s2);
}
else {
item.setMarker(new Rectangle2D.Float(xloc, yloc, boxDim, boxDim));
}
}
item.setMarkerFilled(legendItem.isShapeFilled());
return item;
}
/**
* Tests an object for equality with this legend.
*
* @param obj the object.
*
* @return <code>true</code> or <code>false</code>.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj instanceof StandardLegend) {
StandardLegend l = (StandardLegend) obj;
if (super.equals(obj)) {
if (!ObjectUtils.equal(this.outerGap, l.outerGap)) {
return false;
}
if (!ObjectUtils.equal(this.outlineStroke, l.outlineStroke)) {
return false;
}
if (!ObjectUtils.equal(this.outlinePaint, l.outlinePaint)) {
return false;
}
if (!ObjectUtils.equal(this.backgroundPaint, l.backgroundPaint)) {
return false;
}
if (!ObjectUtils.equal(this.innerGap, l.innerGap)) {
return false;
}
if (!ObjectUtils.equal(this.title, l.title)) {
return false;
}
if (!ObjectUtils.equal(this.titleFont, l.titleFont)) {
return false;
}
if (!ObjectUtils.equal(this.itemFont, l.itemFont)) {
return false;
}
if (!ObjectUtils.equal(this.itemPaint, l.itemPaint)) {
return false;
}
if (this.outlineShapes != l.outlineShapes) {
return false;
}
if (!ObjectUtils.equal(this.shapeOutlineStroke, l.shapeOutlineStroke)) {
return false;
}
if (!ObjectUtils.equal(this.shapeOutlinePaint, l.shapeOutlinePaint)) {
return false;
}
if (this.displaySeriesShapes == l.displaySeriesShapes) {
return true;
}
}
}
return false;
}
/**
* Provides serialization support.
*
* @param stream the output stream.
*
* @throws IOException if there is an I/O error.
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
stream.defaultWriteObject();
SerialUtilities.writeStroke(this.outlineStroke, stream);
SerialUtilities.writePaint(this.outlinePaint, stream);
SerialUtilities.writePaint(this.backgroundPaint, stream);
SerialUtilities.writePaint(this.itemPaint, stream);
SerialUtilities.writeStroke(this.shapeOutlineStroke, stream);
SerialUtilities.writePaint(this.shapeOutlinePaint, stream);
}
/**
* Provides serialization support.
*
* @param stream the output stream.
*
* @throws IOException if there is an I/O error.
* @throws ClassNotFoundException if there is a classpath problem.
*/
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
this.outlineStroke = SerialUtilities.readStroke(stream);
this.outlinePaint = SerialUtilities.readPaint(stream);
this.backgroundPaint = SerialUtilities.readPaint(stream);
this.itemPaint = SerialUtilities.readPaint(stream);
this.shapeOutlineStroke = SerialUtilities.readStroke(stream);
this.shapeOutlinePaint = SerialUtilities.readPaint(stream);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -