2

I have a thread that does display updates on my JFrame by using SwingUtilities.invokeLater. The thread's speed is adjustable, and when it set to full speed (no sleeping between updates), my program gets slowed down badly. I guess the problem is my thread is generating too much SwingUtilities.invokeLater events that JFrame's thread can not consume. So is there anything I can do on my thread to remove previously added but not consumed events? Or should I use some other ways to update JFrame without using SwingUtilities.invokeLater?

Thanks in advance.

4

3 回答 3

4

这可能是一个完美的工作SwingWorker。您可以发布增量更新,并将SwingWorker它们批处理以解决性能问题:

因为流程方法是在事件调度线程上异步调用的,所以在流程方法执行之前可能会发生对发布方法的多次调用。出于性能目的,所有这些调用都合并为一个带有串联参数的调用。

你想在 EDT 上运行的代码,你通过实现process(). 更新列表在参数中传递给您。

于 2012-10-28T23:31:53.600 回答
3

听起来您想避免使事件调度线程饱和。类javax.swing.Timer,在如何使用 Swing Timers中讨论,包括setCoalesce()“合并多个挂起ActionEvent的触发”。它可能是您更新更新速度的另一种方式。

如此处所述,SwingWorker仅限于 33 Hz。

于 2012-10-29T01:24:18.457 回答
1

你可以使用一个简单的 repaint() 吗?这样做的好处是多个调用合并为一个。

(添加了详细说明)

假设您不断更新 GPS 位置并将其显示在两个文本字段中。您进行更新的线程:

run() {
  while (keepGoing) {
    Point myLocation = computeMyLocation();
    locationModel.setLocation(myLocation);
    locationComponent.repaint();
  }
}

然后,在 MyLocationComponent

@Override
public void paintComponent(Graphics g) {
   Point myLocation = locationModel.getLocation();

   // you'd really want a NumberFormat
   latitudeTextArea.setText(String.valueOf(myLocation.y));
   longitudeTextArea.setText(String.valueOf(myLocation.x));

   super.paintComponent(g);
}

优点是这将模型与视图分开(如果您将线程视为控制器,这就是 MVC),并且所有线程都应该工作 - 不需要任何 invokeLater()。一个缺点是您的线程需要知道所有需要更新的 JComponent。在“真实”场景中,您可能会从“控制器”(您的线程)或模型中向触发重绘的侦听器触发事件​​。

注意:正如@trashgod 所指出的,在 LocationModel 中,getLocation()andsetLocation()方法应该是synchronized更新立即出现。

于 2012-10-29T01:57:06.867 回答