java通过不同的线程访问变量和swing组件
这个问题在某种程度上与我问的问题有关。 现在,我有一个类“Controller”,它由main方法和所有swing组件组成。有一个名为“VTOL”的类,它由一个名为“althip”的变量组成(我已经声明这个变量是volatile)
下面是一个由后台运行的线程组成的类:
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Vineet
*/
public class Gravity extends Thread {
String altStr;
double alt;
Controller ctrl = new Controller();
@Override
public void run() {
while (true) {
alt=VTOL.altitude;
System.out.println(alt);
alt = alt-0.01;
VTOL.altitude= (int) alt;
altStr=new Integer(VTOL.altitude).toString();
ctrl.lblAltitude.setText(altStr);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
首先,我最初面临的问题是,我无法更新“高度”的值,它在整个程序执行过程中保持为0。所以我宣布这是不稳定的(我不知道这是否是一个好的做法)
其次,在控制器类中有一个名为“lblAltitude”的jLabel,我希望在这个线程中随着它的更改而更新它的值,但不知何故,这并没有发生。 我该怎么做
# 1 楼答案
无论何时修改Swing组件,都需要确保该事件发生在事件分派线程(即EDT)中
# 2 楼答案
一种解决方案是使用SwingPropertyChangeSupport对象,使海拔高度成为此支持对象的“绑定”属性,让GUI侦听器访问此模型类,从而通知GUI海拔高度的变化
例如
有关更完整的可运行示例:
# 3 楼答案
第三种方法是让Swing组件了解模型VTOL
在重力中,你需要更新VTOL。高度,然后调用组件上的重新绘制。e、 g
然后,在paintComponent()方法中(或者在所有paint调用的其他地方,有一点可能需要在其他地方…)控制器,你知道它正在EDT上运行
这比SwingPropertyChangeSupport的耦合更紧密一些,但耦合都是在非常相关的类之间,所以它是“合理的”,在某些方面可能更“清晰”。事件调度队列将合并多个重绘,因此不会像最初出现的那样效率低下。如果多个线程正在更新内容并排队等待多个repait(),那么实际上只有最后一个repait()执行任何操作
一个缺点是,如果你的GUI有大量的小部件,并且你每次都更新它们,这可能会有点慢。但如今处理器的速度惊人