我想在JPanel
上画一些东西,并阅读和摘录表演自定义绘画课程。当涉及到使用repaint
更新正方形时,我觉得使用这种结构
private void moveSquare(int x, int y) {
if ((squareX != x) || (squareY != y)) {
squareX = x;
squareY = y;
repaint();
}
}
与推荐的示例相比,为该特定示例提供了更好的油漆性能
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX != x) || (squareY != y)) {
repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
squareX = x;
squareY = y;
repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
}
}
如果我使用后者,则在拖动过程中,正方形看起来有些"压扁"。
我知道,这是一个非常基本的例子,但它总体上有点害怕Java图形的性能。
进行两次重绘是不自然的。
当只重新粉刷新旧广场的结合时?
private void moveSquare(int x, int y) {
if (squareX != x || squareY != y) {
final int OFFSET = 1;
int minx = Math.min(x, squareX);
int miny = Math.min(y, squareY);
int dx = Math.abs(x - squareX);
int dy = Math.abs(y - squareY);
squareX = x;
squareY = y;
repaint(minx, miny, squareW + dx + OFFSET, squareH + dy + OFFSET);
}
}
当正方形相对较小或超出显示区域(剪切)时,这应该更平滑。
no-argpaint()
和带参数的 之间的区别在于,带参数的 将在后续调用中设置剪切区域paint()
.绘画性能的差异(如果有的话)将取决于paint()
方法是否实际考虑了剪切区域,或者只是绘制整个绘图区域并让平台来确定该区域是否需要更新。
许多Java AWT/Spring组件忽略了剪切区域,而只是绘制整个区域。这样做有时比弄清楚如何重新绘制显示区域的非常特定的部分要快。如果组件是您自己编写的组件,并且您知道您没有在paint()
中测试剪切区域,那么您就知道无论您是否使用参数调用repaint()
都不会有任何不同。
另一方面,如果您在paint()
实现方面遇到了很多麻烦,要弄清楚如何重新绘制子区域,那么您就应该尝试找出如何最好地调用repaint()
。
如果您没有编写组件,那么可能知道是否最好指定重绘区域,除非通过测试或仔细检查源代码(如果有的话)。
如果将repaint()
与参数一起使用会导致绘制扭曲的图像,则可能表明paint()
实现有缺陷。