Hello, I'm working on filling text to arbitrary shapes, where I hit the named problem. It's not easy to reproduce, as it depends on fontsize and shape ...
So using the attached code reproduces the attached image. I use the call Shape.contains(double x, double y, double w, double h) where the apidoc says: "Tests if the interior of the Shape entirely contains the specified rectangular area." reaching the last line, there should be no match at all, as most of the given rectangle is outside the shape (for all succeeding tests). To verify my understanding I draw the tested rectangle when the contains- method returns true. May be, my sample hits the insideness of a point (from Shape-apidocs), where the point lies on the shape boundary and the succeeding point is inside the shape. That might be true for the base point of the rectangle, but it is never true, for the entire rectangle. So this might be considered a bug. kind regards Gero
<<attachment: Java2DFailure-3.png>>
@Override public void paint(Graphics2D g) { super.paint(g); // draws the shape with border FontMetrics fm = g.getFontMetrics(); Vector<String> words = new Vector<String>(Arrays.asList(getText().split("\\s"))); int mx = getX() + getWidth(); int yMax = getY() + getHeight(); int curY = getY() + fm.getDescent(); int firstX = 0; int lastX = 0; Rectangle2D bounds; while (curY < yMax) { bounds = fm.getStringBounds(getText().substring(0, 1), g); for (int x = getX(); x < mx; x += bounds.getWidth()) { if (getShape().contains(x, curY, bounds.getWidth(), bounds.getHeight())) { firstX = x; break; } } for (int x = mx; x > getX(); x -= bounds.getWidth()) { if (getShape().contains(x, curY, bounds.getWidth(), bounds.getHeight())) { lastX = x; break; } } int lineLength = lastX - firstX; g.drawRect(firstX, curY, (int) bounds.getWidth(), (int) bounds.getHeight()); curY += fm.getAscent(); String line = null; StringBuilder check = new StringBuilder(words.remove(0)); check.append(" ").append(words.get(0)); bounds = fm.getStringBounds(check.toString(), g); while (bounds.getWidth() < lineLength) { words.remove(0); line = check.toString(); check = new StringBuilder(line); check.append(" ").append(words.get(0)); bounds = fm.getStringBounds(check.toString(), g); } if (line == null) break; g.drawString(line, firstX, curY); curY += fm.getHeight(); } }