我打电话给一个听众重新打磨了一堆,但我设计我的油漆功能的方式只有一个需要重新绘制。我产生了一堆重绘,因为它钩到了我的鼠标移动侦听器中。如何在Swing中结合重绘?
有没有办法取消某个组件的所有未决重绘?我不能开始忽略重绘,因为有些是有效的,比如调整框架大小或从最小化中恢复框架。
为什么我在意?因为我的油漆代码非常沉重,而且我无法以非常高的FPS进行完全重新涂漆。
我打电话给一个听众重新打磨了一堆,但我设计我的油漆功能的方式只有一个需要重新绘制。我产生了一堆重绘,因为它钩到了我的鼠标移动侦听器中。如何在Swing中结合重绘?
有没有办法取消某个组件的所有未决重绘?我不能开始忽略重绘,因为有些是有效的,比如调整框架大小或从最小化中恢复框架。
为什么我在意?因为我的油漆代码非常沉重,而且我无法以非常高的FPS进行完全重新涂漆。
Swing将为您重新组合绘图:请参见Sun网站上的"Painting in AWT and Swing"。如果您快速连续安排大量重绘,他们将合并为一个调用立即()。
我的理解是,repaint()
只是通过向重绘队列中添加组件区域来安排重绘。如果组件上已经请求重新绘制,则新的重绘区域将与之前请求的区域建立联合。在处理事件队列中的所有其他事件之前,重新绘制并未实际执行。因此,您的额外重绘可能没有太大区别,即您的绘画代码只能执行一次。请参阅JComponent.repaint和RepaintManager.addDirtyregion。
经常重新绘制的请求会自动合并为一个。对此进行优化的最佳方式不是重新绘制整个事物,而是使用特定区域的坐标调用repaint。这意味着您只重绘实际更改的区域。
我已经黑客类似的东西在一起,以改善JFreechart如何在绘制大量调用重画的绘画时决定绘画。
基本上我做到以下几点:
ScheduledExecutorService
作为现场submit
它执行人在其上运行EDT中说50ms的找回了未来fut.isDone()
),如果是,则计划下一次重绘;否则什么都不做。这样你每秒最多应该得到20次重绘请求。
我已经完成了类似的事情,即当同时发生大量更改时,将调用数量分配到fireDataTableChanged
。
我听到你说的话。 您确实可以仅重绘一部分区域。 在Sun网站的“执行自定义绘画示例”中,我找到了一个有用的示例,显示如何绘制拖动的矩形,然后在鼠标移动或释放时仅重新绘制该区域。
这里是代码的相关部分...
public void mouseDragged(MouseEvent e) {
updateSize(e);
}
public void mouseReleased(MouseEvent e) {
updateSize(e);
}
/*
* Update the size of the current rectangle
* and call repaint. Because currentRect
* always has the same origin, translate it
* if the width or height is negative.
*
* For efficiency (though
* that isn't an issue for this program),
* specify the painting region using arguments
* to the repaint() call.
*
*/
void updateSize(MouseEvent e) {
int x = e.getX();
int y = e.getY();
currentRect.setSize(x - currentRect.x,
y - currentRect.y);
updateDrawableRect(getWidth(), getHeight());
Rectangle totalRepaint = rectToDraw.union(previousRectDrawn);
repaint(totalRepaint.x, totalRepaint.y,
totalRepaint.width, totalRepaint.height);
}
此代码是受版权保护(见here for full code and copyright notice)
见here for further example listings
说实话,我在FPS上一个类似的问题,但可能是由于我目前可怜的码!在过去的几个月中我学到了很多东西,现在我可以让我的代码更加高效。希望当超过2个“人”放慢我的图形速度时,我可以克服FPS问题! Hummmm ... 我只对我的代码中的相同部分实施了上述代码,而不是其他人,但通过一切手段试一试!