我有一个java应用程序,它流式传输原始数据并相应地绘制实时图形。这是通过调用我编写的使用Graphics对象的类中的方法来处理的。我在一个重写的paintComponent方法中实现了算法,从最近的数据中生成所有的图。我在我的类中有其他方法来更新paintComponent方法中使用的变量来绘制图形。
在我的主类中,我在计时器事件处理程序中定期更新我的图表。在事件处理程序中,我从我的图形类中调用更新某些变量的方法,做一些计算,然后调用repaint()(这显然是调用paintComponent方法的正确方法)。
我的问题是,我在paintComponent方法中使用的算法可能需要(相对)较长的时间来完成,这取决于我的情节的数量和分辨率。(我还没有完全遇到这个问题,但我正在努力解决它)。当然,我不希望所有这些图形占用我的应用程序的所有处理时间,所以我想知道是否有可能让"paintComponent"在一个单独的线程中执行。
如果我在main中创建一个子类,在一个单独的线程中运行,并简单地调用我描述的图形方法,会发生什么?这会自动使所有这些方法(包括paintComponent)在新线程中执行吗?还是我需要修改我的图形类本身?理想情况下,我想避免修改我的图形类,因为我已经把它设计成在NetBeans GUI构建器中作为JPanel工作,我想避免破坏该功能。
有几个选项
一种方法是使用两个BufferedImages,其中您在单独的线程中绘制其中一个,并从另一个绘制,并在绘制完成时切换(对于我假设的快照)。
一个更好的解决方案是拥有一个直接可渲染数据的模型(因为它所保存的数据可以在不执行任何进一步的算法工作的情况下绘制)。
这意味着你将在一个单独的线程上执行你的算法,计算将用于绘制的值,调用swingutility。invokeLater更新模型。然后,模型将只在Swing线程上得到更新,并且当您重新绘制时,您可以访问您需要绘制的数据(并且没有多余的数据)。
如果这个数据仍然是如此之多,绘画需要很长时间(即:如果你正在绘制具有大量数据点的图表),你将发送计算窗口的哪些部分需要重新绘画,并对其进行repaint()。然而,这一块应该是最后的手段。99%的性能将来自于将算法移动到一个单独的线程中,并允许画家直接访问可渲染的数据。
如果你看看用外部数据更新TableModel的最佳实践,你所拥有的是在后台线程(通常是SwingWorker)中获得数据的工作,然后通过invokeLater()发布到实际模型(这是这样的数据不会被修改,而你的paint()试图读取它),然后从模型更新中触发适当的事件,告诉表哪些单元格发生了变化。然后,表就会知道它的视口的哪个部分需要重新绘制,并触发相应的repaint()方法。在此期间,后台线程可以继续检索数据,并通过invokeLater向事件队列添加新的更新。
您必须将绘制方法重定向到SwingWorker
或Runnable#Thread
(所有输出到GUI必须包装到invokeLater
),例如这里或这里
如果你想提高GUI的响应速度,你可以在SwingWorker中完成冗长的工作,尽管我不知道这样做是否会提高应用程序的速度。
我有一个java应用程序,它可以传输原始数据并实时绘制相应的情节。这是通过调用类I中的方法来处理的
完成别人的回答:你应该考虑使用JFreeChart。它是一个很好的绘制图表的库,您可以动态修改显示的数据集(以及做更多的事情)。