Java重绘在某些情况下很慢
它们是几个 JPanel、mapgrid 和 JLayeredPane 内的覆盖层,mapgrid 位于底部。 Mapgrid 只是在初始化网格时绘制,其绘制方法是:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
g2d.setColor(new Color(128, 128, 128, 255));
g2d.drawRect(tileSize * j, i * tileSize, tileSize, tileSize);
}
}
在覆盖 JPanel 中,突出显示发生的地方,这就是当鼠标移动时重新绘制的内容:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 128, 255));
g2d.drawRect((pointerX/tileSize)*tileSize,(pointerY/ tileSize)*tileSize, tileSize, tileSize);
}
我注意到,即使基础层(mapgrid)在鼠标移动,只是透明叠加层,表现力有所欠缺。如果我给覆盖 JPanel 一个背景,它会更快。如果我删除地图网格抗锯齿功能,它也会快一点。
我不知道为什么为覆盖层提供背景(从而隐藏地图网格)或禁用地图网格中的抗锯齿功能会带来更好的性能。
有更好的方法吗?为什么会出现这种情况?
I'm doing a simple grid which each square is highlighted by the cursor:
They are a couple of JPanels, mapgrid and overlay inside a JLayeredPane, with mapgrid on the bottom. Mapgrid just draws on initialization the grid, its paint metodh is:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
g2d.setColor(new Color(128, 128, 128, 255));
g2d.drawRect(tileSize * j, i * tileSize, tileSize, tileSize);
}
}
In the overlay JPanel is where the highlighting occurs, this is what is repainted when the mouse is moved:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(new Color(255, 255, 128, 255));
g2d.drawRect((pointerX/tileSize)*tileSize,(pointerY/ tileSize)*tileSize, tileSize, tileSize);
}
I noticed that even though the base layer (mapgrid) is NOT repainted when the mouse moves, just the transparent overlay layer, the performance is lacking. If i give the overlay JPanel a background, its way faster. If i remove the mapgrid Antialiasing, its a bit faster too.
I don't know why giving a background to the overlay layer (and thus, hiding the mapgrid) or disabling antialiasing in the mapgrid leads to much better performance.
Is there a better way to do this? Why does this happen?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
drawLine
代替drawRect
。你应该得到相同的视觉结果,但我认为它会快得多。另外,如果背景始终相同,我建议在初始化时(或调整框架大小时)绘制到缓冲图像,然后绘制该图像。这应该可以加快绘图速度。
Instead of
drawRect
your coulddrawLine
. You should get the same visual result but I think it will be much faster.Also, if the background is always the same I would recommend drawing to a buffered image at initialization (or when the frame is resized) and then just draw that image. That should speed up the drawing.
如果所有 Mapgrid 的颜色相同,请将 setColor 从循环中拉出。现在每次调用paint都会创建新的Color对象。
If all of your Mapgrid is the same color, pull the setColor up out of the loop. Right now each call to paint is creating w*h new Color objects.
这对我来说没有意义。由于您的覆盖面板仅对鼠标当前所在的网格执行drawRect(...),那么如何重置先前的网格?我猜想当您重新绘制覆盖面板时它不是不透明的,对于地图网格来说,在您在覆盖面板上重新绘制网格之前必须先重新绘制整个网格。
跟踪最后绘制的网格。然后,您可以调用 repaint(Rectangle) 来仅在地图网格面板上重新绘制该网格。然后,您还可以在覆盖面板上调用 repaint(Rectangle) 来重绘覆盖面板上的网格。
如果您需要更多帮助,请发布说明问题的 SSCCE。
That doesn't make sense to me. Since your overlay panel only does a drawRect(...) for the grid the mouse is currently over, how does the previous grid get reset? I would guess when you repaint your overlay panel it is not opaque, to the mapgrid would have to repaint the entire grid first before you redraw the grid on your overlay panel.
Keep track of the last painted grid. Then you can invoke repaint(Rectangle) to only repaint that grid on the map grid panel. Then you can also invoke repaint(Rectangle) on your overlay panel to redraw the grid on the overlay panel.
If you need more help post your SSCCE that demonstrates the problem.