【问题标题】:Sliding viewport over a JPanel在 JPanel 上滑动视口
【发布时间】:2010-08-03 04:32:04
【问题描述】:

我正在使用drawLine() 和朋友在JPanel 上绘制图表。有数万个点要绘制,所以需要 3-5 秒。我想在图表上方有一个视口,如下图所示的蓝色。

graph http://cl.ly/1qvN/content

我希望这个视口是可更新的,因为我在图表所在的JPanel 上有一个MouseMotionListener。问题是,如果我像现在一样重绘视口(正方形)(使用drawRect()),我必须重绘整个图形,这是不可取的。

我读过一些关于 GlassPanes 的文章,这可能有助于解决这个问题,但它们显然是 JFrames 的一部分,而不是 JPanels 的一部分。 (我已经在 JFrame 中拥有了这个面板以及其他组件。)

什么是处理这个问题的好方法,保持在 Swing 中并保持高效?

不管怎样,我实际上是在 Clojure 中编码,但这不应该改变任何东西。

非常感谢!

艾萨克

【问题讨论】:

    标签: java user-interface swing


    【解决方案1】:

    我解决这类问题的方法是考虑数据的波动性。除非图表实时变化,否则从paint 到paint 的唯一变化是蓝色框的位置。减少绘制时间的一种方法是不要重复您已经执行的工作。例如:

    protected void paintComponent(Graphics g) {
        // paint chart
        if (dirty || buffer == null) {
            buffer = new BufferedImage(getWidth(), getHeight(),
                                       BufferedImage.TYPE_ING_ARGB);
            // Paint the chart onto the buffered image
            dirty = false;
        }
        b.drawImage(0, 0, buffer);
        // Draw blue box
        ...
    }
    

    第一次调用paintComponent 会初始化缓冲区并完成绘制图形的繁重工作。此后,缓冲区只是被绘制。如果您需要处理重新绘制显示以显示数据的不同部分的情况,您只需使缓冲区无效。

    public void invalidateBuffer() {
        dirty = true;
        repaint();
    }
    

    【讨论】:

    • 有趣——我会试试看,谢谢!我什至没有考虑使用 BufferedImage。在 Clojure 中尝试会很有趣。
    【解决方案2】:

    从您发布的屏幕截图来看,绘制应该不需要 3-5 秒。您不应该使用图层来完成您正在谈论的内容。我有一个应用程序,其数据与您描述的一样多,但可视化更复杂。它还具有您讨论的相同类型的视口功能。画图没问题,大部分时候画图3-5毫秒。

    确保以绘制线程可以快速访问数据的方式存储数据。绘制线程应该把所有时间都花在绘制上,如果它必须搜索数据来找到它需要的东西,那么它就是在浪费时间。

    在paint方法中收集计时信息并将其写入控制台。跟踪方法的每个部分花费了多少时间,并找出导致延迟的代码行。弄清楚如何摆脱这种延迟。绘制方法只需要 3-5 毫秒即可运行。你偏离了 1,000 倍 - 可以优化一些东西。

    确保您只绘制屏幕上实际可见的内容。不要浪费时间画那些会出现在屏幕外的东西。还要确保您没有绘制在屏幕上仅部分可见的很长的线条。 (就像,如果你放大很多,即使是最小的线现在也很大。)整个东西都必须被画出来,无论它是否可见。

    我很惊讶,根据屏幕截图,您必须使用任何类型的分层来完成此操作。 3-5 秒对于一个油漆周期来说都太长了。

    【讨论】:

    • 上面屏幕截图中的蓝色框是供用户拖动的:它应该/将把它拥有的坐标连同视口的宽度一起发送到它上面的图表,以秒为单位(稍后实现),因此上图可以根据需要重新绘制。 (cl.ly/1rDa 获取整个设置的图片,这需要 3-5 秒才能完成!)谢谢!
    • 例如,使用如图所示的视口,数据在上图中可能看起来像这样 (cl.ly/1qhc)。这是底部的图表,我基本上想成为一个静态图像,我可以在上面绘制和重绘视点。问题是,我必须在一开始就绘制一个图形,所以我不想将它保存为图像然后立即再次绘制图像。
    • 这看起来很像我正在开发的应用程序 - 几乎是可怕的。我提供了相同的功能,底部的概述和突出显示在顶部的视口。我允许人们缩小到足够远以显示与您显示的一样多的数据。我没有任何速度问题。因此,请在绘制例程中检查您的数据检索例程。确保您的绘制线程没有花费大量时间来获取它需要显示的数据。优化绘制方法!
    • 你能总结一下底部图表的数据,这样你就不必在上面画出每一点了吗?即使你只画一次,你也不应该花 3-5 秒来画。每次调整窗口大小时都必须重新绘制,这太荒谬了。
    • 我一定会那样做的——我今天早上刚把它弄坏了,所以它肯定有一些粗糙的边缘,但是有一个更好的方法来画一点 got框在 JPanel 上,而不是重绘整个 JPanel 和 drawRect()ing 在其之上,每次有人想要移动!
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2011-07-01
    • 2013-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-05-07
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多