通过不同的线程访问变量和摆动组件 [英] accessing variables and swing components through different threads
问题描述
这个问题与我提出的问题有点相关此处。
现在,我有一个Controller类,它由main方法和所有swing组件组成。有一个名为VTOL的类,它由一个名为altitude的变量组成(我现在已声明此变量为volatile)。
This question is related somewhat to the one i asked HERE. Now, i have a class "Controller" which consists of the main method and all the swing components. there is a class named "VTOL" which consists of a variable named "altitude"(i have declared this variable volatile as of now).
这是一个包含的类在后台运行的线程:
here is a class that consists of a thread which runs in the background:
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。所以我宣称它是不稳定的(我不知道它是不是一个好习惯)
Firstly, the problem i was facing initially was that i couldnt update value of "altitude" it remained 0 throughout the execution of program. So i declared it as volatile (I dont know if its a good practice)
其次,在Controller类中有一个名为lblAltitude的jLabel,我想更新它的在这个帖子中改变了它的值,但不知怎的,这没有发生。
我该怎么做?
Secondly, there is a jLabel in Controller class named "lblAltitude", i wish to update its value as its changed in this thread, but somehow thats not happening. How can i do that?
推荐答案
解决方法是使用SwingPropertyChangeSupport对象,使海拔高度达到绑定 具有此支持对象的属性,让您的GUI监听器通知此模型类,从而通知GUI高度变化。
A solution is to use a SwingPropertyChangeSupport object, to make altitude a "bound" property with this support object, to have your GUI listener to this model class and to thereby notify the GUI of changes in altitude.
例如,
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);
}
}
了解更多完整的可运行示例:
For a more complete runnable example:
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);
}
}
这篇关于通过不同的线程访问变量和摆动组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!