Java重绘在某些情况下很慢

发布于 2024-08-26 19:36:43 字数 1341 浏览 6 评论 0原文

我正在做一个简单的网格,每个方块都由光标突出显示: 替代文本

它们是几个 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:
alt text

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

止于盛夏 2024-09-02 19:36:43

您可以使用drawLine代替drawRect。你应该得到相同的视觉结果,但我认为它会快得多。

另外,如果背景始终相同,我建议在初始化时(或调整框架大小时)绘制到缓冲图像,然后绘制该图像。这应该可以加快绘图速度。

Instead of drawRect your could drawLine. 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.

一瞬间的火花 2024-09-02 19:36:43

如果所有 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.

走走停停 2024-09-02 19:36:43

我注意到即使基地
图层(地图网格)在以下情况下不会重新绘制
鼠标移动,只是透明
覆盖层,性能为
缺乏。

这对我来说没有意义。由于您的覆盖面板仅对鼠标当前所在的网格执行drawRect(...),那么如何重置先前的网格?我猜想当您重新绘制覆盖面板时它不是不透明的,对于地图网格来说,在您在覆盖面板上重新绘制网格之前必须先重新绘制整个网格。

有更好的方法吗?

跟踪最后绘制的网格。然后,您可以调用 repaint(Rectangle) 来仅在地图网格面板上重新绘制该网格。然后,您还可以在覆盖面板上调用 repaint(Rectangle) 来重绘覆盖面板上的网格。

如果您需要更多帮助,请发布说明问题的 SSCCE

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.

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.

Is there a better way to do this?

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文