在屏幕上绘制 8x8 矩形变成 9x9 矩形?

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

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

这很好地填充了一个 8x8 的矩形。

但是当我尝试绘制 8x8 矩形边框时发生了奇怪的事情:

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

这会绘制一个 9x9 矩形。

但是我指定应该是8宽8高。

我有一个默认的笔划宽度 1。

我是不是忽略了什么?也许更好的问题是:我可以关闭它以便在调用 draw 时得到一个 8x8 的矩形吗?

drawRect的文档告诉你Graphics2D如何绘制矩形:

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.

所以基本上,如果 x = 0width = 8,左边的线将在 0,右边的线在 8。因此,总宽度来自0 ... 8,等于8 - 0 + 1 = 9.

如果你想画一个既有宽又有高的矩形8,你可以把它缩小一个像素:

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

Graphics2D class 的文档,在标题为 "Rendering Compatibility Issues" 的部分中说:

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.

接着说:

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,

所以基本上,这意味着如果 Java 渲染一条从 (0,0)(0,8) 的线,它将在 下方 的像素中绘制它] 0坐标。从 (0,8) 到 (8,8) 的线将在 8 x 坐标的 右边 的像素中。

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

因此,在 8x8 矩形周围使用 draw 在矩形内部绘制两条线,在矩形外部绘制两条线。

以下代码两次渲染矩形,首先是填充,然后是边框(绘制)。这就是它的工作原理。

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