我正在Java swing中创建一个简单的下载管理器......! 我在下载管理器中为不同的任务使用了不同的线程。
Thread1->主要 Thread2-> downloadSpeedTracker Thread3-> SwingUIRendrer
在这个应用程序中,我通过在类downloadSpeedTracker中创建一个线程计算下载速度,我每秒钟后重新计算这个速度。我在SwingUIRendrer类中创建了Thread3。现在我想将这个计算出的速度发送到我的SwingUIRendrer类。
我想在SwingUI上不断更新这个计算出的速度。 我如何实现这一目标......?
@Mohamed:
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中清除速度的早期值,然后编写新的值。
答案 0 :(得分:0)
将计算出的速度保存在类别中,如“速度”。使该类是共享的,并且共享变量的读写应该是互斥的。我的意思是同步该变量访问点。
希望得到这个帮助。
答案 1 :(得分:0)
不需要第3个线程,因为必须在事件派发线程中更新UI。
一种解决方案可能是:
定义一个接口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();
答案 2 :(得分:0)
不更新gui是一个众所周知的问题,在tutorial中明确解释了它如何与明确的答案一起使用。