如何在Swing中组合重绘?

时间:2009-08-10 18:58:37

标签: java swing graphics paint repaint

我从听众那里多次调用重绘,但我设计绘画功能的方式只需要一次重绘。我生成了一堆重绘,因为它挂钩了我的鼠标运动监听器。

有没有办法取消某个组件的所有待处理重绘?我不能只是开始忽略重绘,因为有些是有效的,就像你调整框架大小或从最小化恢复它。

我为什么在意?因为我的油漆代码非常重,我无法在非常高的FPS下完全重绘。

5 个答案:

答案 0 :(得分:2)

频繁的重绘请求会自动折叠为一个。优化这个的最好方法不是重绘整个事物,而是用特定区域的坐标调用重绘。这意味着您只重绘实际更改的区域。

答案 1 :(得分:2)

Swing将为您重新组合重拍:请参阅Sun网站上的"Painting in AWT and Swing"。如果你快速连续安排一些重绘,它们将合并为一次调用paintImmediately()。

答案 2 :(得分:1)

我的理解是repaint()只是通过将组件的一个区域添加到重绘队列来调度重绘。如果已在组件上请求重绘,则新重绘区域将仅与先前请求的区域联合。在处理事件队列中的所有其他事件之前,实际上不会执行重绘。因此,您的额外重绘可能没有多大区别,即您的绘画代码只会执行一次。请参阅JComponent.repaintRepaintManager.addDirtyregion

答案 3 :(得分:0)

我已经黑客攻击类似的东西,以改善JFreechart在大量调用重绘时决定绘制的内容。

基本上我会做以下事情:

  • 在班级
  • 中创建一个ScheduledExecutorService字段
  • 接收第一个重拍请求,然后submit给执行人在EDT上运行,比如50ms回到未来
  • 接收第二个请求 - 测试以查看先前的重绘是否已完成(fut.isDone()),如果是,则安排下一次重绘;否则什么都不做。

这样每秒最多可获得20个重绘请求。

当同时发生大量更改时,我已经完成了将fireDataTableChanged的调用次数批量化的相似内容。

答案 4 :(得分:0)

我听到你的意思。 你确实可以只重绘一部分区域。 在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 ... 我只在我的代码中为同一部分实现了上面的代码,而不是其他代码,但是请务必尝试一下!