TinusSky
TinusSky

Reputation: 1737

Drawing a 8x8 rectangle becomes a 9x9 rectangle on screen?

g2.fill(new Rectangle2D.Double(0, 0, 8, 8));

This nicely fills a 8x8 rectangle.

But strange things happen when I try to draw a 8x8 rectangle border:

g2.draw(new Rectangle2D.Double(0, 0, 8,8));

This draws a rectangle 9x9 rectangle.

enter image description here

But I specified that it should be 8 width and 8 height.

I have a default stroke width 1.

Am I overlooking something? Maybe a better question is: can I turn this off so that I get a 8x8 rectangle when calling draw?

Upvotes: 2

Views: 118

Answers (3)

RealSkeptic
RealSkeptic

Reputation: 34638

The documentation of the Graphics2D class, in the section titled "Rendering Compatibility Issues", says:

The JDK(tm) 1.1 rendering model is based on a pixelization model that specifies that coordinates are infinitely thin, lying between the pixels. Drawing operations are performed using a one-pixel wide pen that fills the pixel below and to the right of the anchor point on the path. The JDK 1.1 rendering model is consistent with the capabilities of most of the existing class of platform renderers that need to resolve integer coordinates to a discrete pen that must fall completely on a specified number of pixels.

It goes on to say:

Java 2D API maintains compatibility with JDK 1.1 rendering behavior, such that legacy operations and existing renderer behavior is unchanged under Java 2D API. Legacy methods that map onto general draw and fill methods are defined,

So basically, this means that if Java renders a line from (0,0) to (0,8), it will draw it in the pixels under the 0 coordinate. The line from (0,8) to (8,8) will go in the pixl to the right of the 8 x coordinate.

0┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
 │ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │
1├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
2├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
3├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
4├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
5├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
6├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
7├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │   │   │   │   │   │   │   │ █ │
8├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 │ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │ █ │
 └───┴───┴───┴───┴───┴───┴───┴───┴───┘
 0   1   2   3   4   5   6   7   8      

Thus, using draw around an 8x8 rectangle draws two lines inside the rectangle, and two outside it.

Upvotes: 6

Zeus
Zeus

Reputation: 1555

The following code renders the rectangle twice, first the fill and then the border (draw). That's how it works.

Rectangle2D rect = new Rectangle2D.Double(...);
g2.setColor(Color.white);
g2.fill(rect);
g2.setColor(Color.black);
g2.draw(rect);

Upvotes: 0

Bubletan
Bubletan

Reputation: 3863

The documentation of drawRect tells you how Graphics2D draws rectangles:

Draws the outline of the specified rectangle. The left and right edges of the rectangle are at x and x + width. The top and bottom edges are at y and y + height. The rectangle is drawn using the graphics context's current color.

So basically, if x = 0 and width = 8, the left line will be at 0 and the right line at 8. Therefore, the total width is from 0 ... 8, which equals 8 - 0 + 1 = 9.

If you want to draw a rectangle which has both width and height 8, you can just make it smaller by one pixel:

g2.draw(new Rectangle2D.Double(0, 0, 7, 7));

Upvotes: 3

Related Questions