这个问题与我在这里提出的问题有些相关。现在,我有一个“控制器”类,它由主要方法和所有摆动组件组成。有一个名为“ 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。所以我宣布它为易失性的(我不知道这是否是一个好习惯)
其次,在Controller类中有一个名为“ lblAltitude”的jLabel,我希望在此线程中更改其值后对其进行更新,但是这并没有发生。我怎样才能做到这一点?
一种解决方案是使用SwingPropertyChangeSupport对象,使高度成为此支持对象的“绑定”属性,让您的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); } }