这个问题与我问HERE的问题有些相关。
现在,我有一个“ Controller ”类,它由主要方法和所有摆动组件组成。有一个名为“VTOL”的类,它由一个名为“altitude”的变量组成(到目前为止,我已经将此变量声明为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();
}
}
}
}
首先,我最初面临的问题是我无法更新“altitude”的值,在整个程序执行过程中它始终保持为0。所以我宣布它为 volatile 的(我不知道这是否是一个好习惯)其次,在Controller类中有一个名为“lblAltitude”的jLabel,我希望在此线程中更改其值后对其进行更新,但是这并没有发生。
我怎样才能做到这一点?
最佳答案
一种解决方案是使用SwingPropertyChangeSupport对象,使高度成为此支持对象的“绑定(bind)”属性,让您的GUI监听器对此模型类进行通知,从而将高度变化通知给GUI。
例如。,
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
public class Gravity implements Runnable {
public static final String ALTITUDE = "altitude";
private SwingPropertyChangeSupport swingPcSupport = new SwingPropertyChangeSupport(this);
private volatile double altitude;
@Override
public void run() {
while (true) {
double temp = altitude + 10;
setAltitude(temp); // fires the listeners
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
Double oldValue = this.altitude;
Double newValue = altitude;
this.altitude = newValue;
// this will be fired on the EDT since it is a SwingPropertyChangeSupport object
swingPcSupport.firePropertyChange(ALTITUDE, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
swingPcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
swingPcSupport.removePropertyChangeListener(listener);
}
}
有关更完整的可运行示例:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class GravityTestGui extends JPanel {
private static final long ALT_SLEEP_TIME = 400;
private static final double ALT_DELTA = 5;
JLabel altitudeLabel = new JLabel(" ");
private Gravity gravity = new Gravity(ALT_SLEEP_TIME, ALT_DELTA);
public GravityTestGui() {
add(new JLabel("Altitude:"));
add(altitudeLabel);
gravity.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (Gravity.ALTITUDE.equals(pcEvt.getPropertyName())) {
String altText = String.valueOf(gravity.getAltitude());
altitudeLabel.setText(altText);
}
}
});
new Thread(gravity).start();
}
private static void createAndShowGui() {
GravityTestGui mainPanel = new GravityTestGui();
JFrame frame = new JFrame("GravityTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Gravity implements Runnable {
public static final String ALTITUDE = "altitude";
private SwingPropertyChangeSupport swingPcSupport = new SwingPropertyChangeSupport(this);
private volatile double altitude;
private long sleepTime;
private double delta;
public Gravity(long sleepTime, double delta) {
this.sleepTime = sleepTime;
this.delta = delta;
}
@Override
public void run() {
while (true) {
double temp = altitude + delta;
setAltitude(temp); // fires the listeners
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public double getAltitude() {
return altitude;
}
public void setAltitude(double altitude) {
Double oldValue = this.altitude;
Double newValue = altitude;
this.altitude = newValue;
// this will be fired on the EDT since it is a SwingPropertyChangeSupport object
swingPcSupport.firePropertyChange(ALTITUDE, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
swingPcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
swingPcSupport.removePropertyChangeListener(listener);
}
}