0

I'm quite new to graphics in java and I'm trying to create a shape that clips to the bottom of another shape. Here is an example of what I'm trying to achieve:

https://i.stack.imgur.com/g3jKJ.png

Where the white line at the base of the shape is the sort of clipped within the round edges. The current way I am doing this is like so:

g2.setColor(gray);
Shape shape = getShape(); //round rectangle
g2.fill(shape);
Rectangle rect = new Rectangle(shape.getBounds().x, shape.getBounds().y, width, height - 3);
Area area = new Area(shape);
area.subtract(new Area(rect));
g2.setColor(white);
g2.fill(area);

I'm still experimenting with the clip methods but I can't seem to get it right. Is this current method ok (performance wise, since the component repaints quite often) or is there a more efficient way?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Rustom
  • 11
  • 5
  • 1
    Post your [SSCCE](http://sscce.org/) that demonstrates the problem. – camickr Oct 26 '13 at 21:54
  • I suspect the more efficient way is to first pain the white and then the yellow on top of it instead of doing area substraction, you are still doing the same amount of paintcalls just one less (possibly expensive) operation with Area. – arynaq Oct 26 '13 at 22:05
  • 1
    The only way to make it more efficient is buffer the result onto a BufferedImage and simple paint that, only changing the buffer as needed... – MadProgrammer Oct 26 '13 at 22:20

2 Answers2

1

Is this current method ok (performance wise, since the component repaints quite often) ..

Subtracting shapes is how I'd go about it. The objects could be a few instances or (possibly) a single instance that is transformed as needed.

  1. A text demo., using scaling & fading.
  2. Here's one with simple lines (..and dots, ..and it is animated).

Of course, if the image is purely additive, use a BufferedImage as the canvas & display it in a JLabel/ImageIcon combo. As in both of those examples.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
1

I think your original idea about using the clip methods was the right way to do it. This works for me:

static void drawShapes(Graphics2D g, int width, int height,
    Shape clipShape) {

    g.setPaint(Color.BLACK);
    g.fillRect(0, 0, width, height);

    g.clip(clipShape);

    int centerX = width / 2;
    g.setPaint(new GradientPaint(
        centerX, 0, Color.WHITE,
        centerX, height, new Color(255, 204, 0)));

    g.fillRect(0, 0, width, height);

    g.setPaint(Color.WHITE);
    int whiteRectHeight = height * 4 / 5;
    g.fillRect(0, whiteRectHeight,
        width, height - whiteRectHeight);
}
VGR
  • 40,506
  • 4
  • 48
  • 63