我正在用Java swing创建一个简单的下载管理器...!
我在下载管理器中为不同的任务使用了不同的线程。

线程1->主
Thread2->下载SpeedTracker
线程3-> SwingUIRendrer

在此应用程序中,我正在通过在类downloadSpeedTracker中创建一个线程来计算下载速度,并且每秒都会重新计算该速度。我在SwingUIRendrer类中创建了Thread3。现在,我想将此计算出的速度发送到我的SwingUIRendrer类。

我想在SwingUI上不断更新此计算速度。
我该如何实现...?

@穆罕默德:

public void setUI(int speed)
{
    JLabel l1= new JLabel("Speed :"+speed);
    wind.add(l1);
    wind.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    wind.setSize(200, 60);
}

我在while循环中调用SetUI方法。每次调用该方法时,都会向其发送一个新的速度值。但是当我运行该程序时,速度被先前显示的速度所覆盖。我想从用户界面中清除较早的速度值,然后编写新的速度值。

最佳答案

不需要第三线程,因为必须在事件分发线程中完成UI的更新。

一种解决方案可能是:

  • 定义接口(interface)ISpeedListener,如下所示:
    public interface ISpeedListener {
      public void onSpeedChange(long newSpeed);
    }
    
  • 在DownloadSpeedTracker中,创建一个列表(ArrayList)来保存监听器,并添加方法以允许其添加/删除速度监听器。当速度改变时,通过调用onSpeedChange方法通知监听器。
    private List<ISpeedListener> listeners = new ArrayList<ISpeedListener>();
    
    public void addSpeedListener(ISpeedListener l) {
      listeners.add(s)
    }
    
    public void removeSpeedListener(ISpeedListener l) {
      listeners.remove(s)
    }
    
    // call this method when the speed changes
    private void notifyListeners(long newspeed) {
      foreach (ISpeedListener l : listeners) {
        l.onSpeedChange(newspeed);
      }
    }
    
  • 在SwingUIRendrer类中,使其实现ISpeedListener类,在onSpeedChange方法中,使用SwingUtilites.invokeLater更新相关的UI组件,以在事件分发线程上对UI组件进行操作。
    public class SwingUIRendrer implements ISpeedListener {
      public void onSpeedChange(final long newSpeed) {
    
        SwingUtilites.invokeLater(new Runnable() {
          public void run() {
            //TODO.... update the label with new speed.
          }
        }
        );
      }
    }
    

  • 在运行DownloadSpeedTracker之前,请创建SwingUIRendrer的实例并将其作为监听器添加到DownloadSpeedTracker。
    SwingUIRendrer render = new SwingUIRendrer(<other parameter>);
    DownloadSpeedTracker tracker = new DownloadSpeedTracker();
    tracker.addSpeedListener(render);
    render.start();
    

    09-10 10:25