我试图找到解决方案两天但仍然不知道该怎么做。
下面是这样的情况:我有一个runnable类,其中Calendar类型的变量随着时间的推移通过无限循环进行一些增量(在 source 1 中有一个简化的模型)。接下来我有一个GUI,我正在开始新的线程( source 2 )。
当变量'time'改变时,我想要一些数学并在我的GUI上更改一些标签。
据我所知,我应该创建PropertyChangeListener,这是一个我有问题的地方:我真的不明白该怎么做。我做了以下事情:将我的TimeLoop类更新为 Source 3 。我已经创建了 Source 4 上列出的监听器(也简化了)。这里有一个问题:我应该如何以及在哪里初始化监听器?或者我错在哪里?谢谢你的回答。
P.S。我唯一的想法是(来源5),那当然是行不通的。
来源1(我的可运行类的示例):
public class TimeLoop implements Runnable {
private Calendar time = Calendar.getInstance();
@Override
public void run() {
try {
time.set(1997, 11, 27, 00, 00, 00);
while (true) {
time.add(time.HOUR, 1);
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("Interrupted error");
}
}
}
来源2(来自我的GUI类的来源):
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
Thread trTime = new Thread(new TimeLoop());
trTime.setName("TimeLoop");
trTime.start();
}
来源3(已编辑的可运行课程):
public class TimeLoop implements Runnable {
private Calendar time = Calendar.getInstance();
private PropertyChangeSupport support = new PropertyChangeSupport(this);
public void updateTime() {
Calendar oldValue = time;
time.add(time.HOUR, 1);
Calendar newValue = time;
support.firePropertyChange("time", oldValue, newValue);
}
public void addListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
@Override
public void run() {
try {
while (true) {
time.set(1997, 11, 27, 00, 00, 00);
updateTime();
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("Interrupted error");
}
}
}
来源4(听众):
public class TimeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent pce) {
System.out.println(pce.getPropertyName() + " has new value);
}
}
来源5(错误的代码):
public static void main(String args[]) {
Thread trTime = new Thread(new TimeLoop());
trTime.setName("TimeLoop");
trTime.start();
TimeLoop tLoop = new TimeLoop();
TimeListener tTistener = new TimeListener();
tLoop.addListener(tTistener);
}
答案 0 :(得分:0)
你快到了。您只需遵循正确的顺序:
TimeLoop tLoop = new TimeLoop(); TimeListener tListener = new TimeListener(); tLoop.addPropertyChangeListener(tListener); Thread trTime = new Thread(tLoop); trTime.setName("TimeLoop"); trTime.start();
您的代码在#5中的问题是您在线程上运行的对象(新的TimeLoop())与您添加PropertyChangeListener(tLoop)的TimeLoop的实例不同。因此,在Thread中运行的实例不会触发任何事件。
答案 1 :(得分:0)
我认为使用MVC的Observer Patern非常有用。
答案 2 :(得分:0)
我用Observer Patern解决了这个问题。这是代码:
来源1(可运行的课程):
public class TimeLoop extends Observable implements Runnable{
private Calendar time = Calendar.getInstance();
@Override
public void run() {
try {
time.set(1997, 11, 27, 00, 00, 00);
while (true) {
time.add(time.HOUR, 1);
setChanged();
notifyObservers(time);
Thread.sleep(1000);
}
}
} catch (InterruptedException ex) {
System.out.println("Interrupted error");
}
}
}
来源2(处理程序):
public class Handler implements Observer{
private Calendar resp;
@Override
public void update(Observable o, Object o1) {
if (o1 instanceof Calendar) {
resp = (Calendar) o1;
System.out.println("Received response: " + resp);
}
}
}
来源3(GUI):
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new GUI().setVisible(true);
}
});
final TimeLoop tLoop = new TimeLoop();
final Handler responseHandler = new Handler();
tLoop.addObserver(responseHandler);
Thread trTime = new Thread(tLoop);
trTime.setName("TimeLoop");
trTime.start();
}