4

I want to fill a region using Graphics.fillRoundRect(), but I want a rectangle in the middle of it to not be filled.

Essentially, given a component of 100x30, I want to set clipping to be the rectangle at 10,10 of size 80x10 but have the fill only paint the area outside that 80x10 rectangle. The reason is that I want a border of n pixels with a curved outline painted without affecting the inside component area.

The best way I can see so far is to clip to 10,10 90x10 and do the fillRoundRect() and then clip to 90,10 10x10 and do a fillRect() to fill in the right hand side, below and above the corners.

If I simple repaint a single line rectangle then I end up with "spotting" on the corners because the curves don't quite abut (and/or because AA affects surrounding pixels).

EDIT: Caveat - I need a way to do it which will work with J2ME AWT (CDC with Personal Profile 1.1) as well as J2SE.


Edit: Another similar question has an an answer I was able to adapt. The code that works correctly for my situation is posted as a self-answer.

Community
  • 1
  • 1
Lawrence Dol
  • 63,018
  • 25
  • 139
  • 189
  • Don't know why this had an "objective-c" tag... – Quinn Taylor Aug 13 '09 at 19:00
  • @Quinn: Thanks for the correction - I *typed* "J2ME" in the Tags field, but I suspect that pressing tab from the Tags field to the Edit Summary switched the tag and I didn't notice! I find the tab behavior of the tags field very annoying/counter-intuitive. – Lawrence Dol Aug 13 '09 at 22:26

2 Answers2

2

I have a similar answer on the other question too, which is to use a polygon as an AWT clip. Maybe this is supported in J2ME? You'll need to know the bounds of the rectangle you want to exclude, and the outer bounds of your drawing area.

+-------------------+
| clip drawing area |
+---+-----------+   |
|   | excluded  |   |
|   |   area    |   |
|   +-----------+   |
|                   |
+-------------------+

EDIT FROM OP.

This answer worked for me and the API's are supported on J2ME. The answer of the other question appears to have one mistake - the set of coordinates needs to start a the point on the outer-left and inner top in order to create an enclosed polygon. My final code which worked follows:

To create a clipping Shape, I used this method:

static public Shape getOutsideEdge(Graphics gc, Rectangle bb, int top, int lft, int btm, int rgt) {
    int                                 ot=bb.y            , it=(ot+top);
    int                                 ol=bb.x            , il=(ol+lft);
    int                                 ob=(bb.y+bb.height), ib=(ob-btm);
    int                                 or=(bb.x+bb.width ), ir=(or-rgt);

    return new Polygon(
     new int[]{ ol, ol, or, or, ol, ol,   il, ir, ir, il, il },
     new int[]{ it, ot, ot, ob, ob, it,   it, it, ib, ib, it },
     11
     );
    }

which I set into the Graphics context and then filled my rectangle:

Rectangle tmp=new Rectangle(px,py,pw,ph);
gc.setClip(getOutsideEdge(gc,tmp,thickness,thickness,thickness,thickness));
gc.fillRoundRect(px,py,pw,ph,RADIUS,RADIUS);

and then I created the illusion of rounded inside corners by painting a single dot in each corner:

gc.setClip(px,py,pw,ph);
gc.drawLine((px   +thickness  ),(py   +thickness  ),(px   +thickness  ),(py   +thickness  ));
gc.drawLine((px+pw-thickness-1),(py   +thickness  ),(px+pw-thickness-1),(py   +thickness  ));
gc.drawLine((px   +thickness  ),(py+ph-thickness-1),(px   +thickness  ),(py+ph-thickness-1));
gc.drawLine((px+pw-thickness-1),(py+ph-thickness-1),(px+pw-thickness-1),(py+ph-thickness-1));
Community
  • 1
  • 1
banjollity
  • 4,490
  • 2
  • 29
  • 32
1

Please check my answer on this question. It is very similar.

EDIT: you might want to check if AlphaComposite is available in j2me. In Java you can simulate the clip by changing the alpha composite mode (i can't remember to which exactly i think its srcIn) and by painting on an image with black and white areas. You might want to check it out.

Community
  • 1
  • 1
Savvas Dalkitsis
  • 11,476
  • 16
  • 65
  • 104
  • Yes, it looks like that will work for J2SE, but the solution also needs to work for J2ME (which requirement I didn't include originally, sorry). J2ME PP 1.1 does not have the java.awt.geom package. Man! it's a pain having to support handhelds! – Lawrence Dol Aug 13 '09 at 18:38
  • yes you should change the tags and the title then. in the question i provided check out the answer not by me. Maybe that will work for you. – Savvas Dalkitsis Aug 13 '09 at 18:42
  • +1 for pointing me to a similar question which had an answer I was able to adapt into a working solution. – Lawrence Dol Aug 13 '09 at 22:46
  • Quick note: You used 1 extra point. The point (ol,it) is unnecessary because you can go from the top left outer corner to the top left inner corner no problem. – shieldgenerator7 Aug 21 '14 at 18:45