我正在做一个大学课程项目,这是一个JavaFX应用程序,它正在模拟随车行驶的车库。在this answer之后,我创建了一种用于不断刷新GUI而不淹没JavaFX线程的机制。
可以找到整个代码here。
Observer
是一个守护程序线程,其任务是计算String
的值以供输出并将其发送到不断更新的TextArea
。
观察者运行方法:
@Override
public void run() {
while (true) {
synchronized (Garage.getLock()) {
try {
// buffer = new StringBuffer("");
buffer.append('\n');
garage.print(buffer);
buffer.append('\n');
garage.outputText.set(buffer.toString());
System.out.println(buffer.toString());
Garage.getLock().wait(3000);
} catch (InterruptedException exception) {
exception.printStackTrace();
} finally {
Garage.getLock().notifyAll();
}
}
}
}
Observer
对象具有对模型类-garage
的引用。 print()
类的Garage
方法基本上将内容附加到缓冲区。
将完整的输出打印到控制台,效果很好。输出还用于设置outputText
,一个SimpleStringProperty
,它在MainControllerClass
中附加了一个侦听器。
outputText成员:
public class Garage implements Externalizable {
...
public SimpleStringProperty outputText = new SimpleStringProperty();
...
}
通过单击按钮即可启动刷新GUI。
MainController类:
package garage.controller;
import java.util.concurrent.atomic.AtomicInteger;
import garage.model.*;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class MainController {
@FXML
private TextArea output;
@FXML
private Button startButton;
private Garage model;
public MainController() {
}
private AtomicInteger control = new AtomicInteger(-1);
@FXML
public void initialize() {
}
@FXML
private void handleStartButton() {
model.outputText.addListener(new ChangeListener<String>() {
@Override
public void changed(final ObservableValue<? extends String> observable, final String oldValue,
final String newValue) {
if (control.getAndSet(1) == -1) {
javafx.application.Platform.runLater(new Runnable() {
@Override
public void run() {
control.set(-1);
output.setText(newValue);
}
});
}
}
});
}
public void setModel(Garage model) {
this.model = model;
}
}
当我运行该应用程序并单击该按钮时,一切进展顺利。 TextArea
实时更新。由于输出一直不断地附加到StringBuffer
上,因此我想在每个周期中刷新它并得到类似仿真的结果。
这是问题开始的地方。
当我在Observer run
方法中取消注释该行
// buffer = new StringBuffer("");
没有任何内容打印到TextArea
上。控制台输出运行良好。
我也尝试了其他StringBuffer
方法,例如delete
和setLenght
,但似乎没有任何效果。但是,我尝试清理缓冲区,TextArea
不再更新。
我似乎无法重置 StringBuffer
。
我在这里想念什么?
编辑:print()
个方法
车库打印方法
public void print(StringBuffer buffer) {
synchronized (Garage.lock) {
synchronized (lock) {
for (int i = 0; i < platformCount; i++)
platforms.get(i).print(buffer);
}
}
}
GarageItem打印方法
package garage.model;
import java.io.*;
public interface GarageItem extends Serializable {
public void print(StringBuffer buffer);
}
泳道打印方法
package garage.model;
public class Lane implements GarageItem {
private static final long serialVersionUID = 5L;
@Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append('.');
}
}
}
ParkingSpot打印方法
package garage.model;
public class ParkingSpot implements GarageItem {
private static final long serialVersionUID = 4L;
@Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append('*');
}
}
}
车辆打印方法
@Override
public void print(StringBuffer buffer) {
synchronized (Garage.getLock()) {
buffer.append(symbol);
}
}
其中symbol
是'V'。
答案 0 :(得分:2)
今天找到了答案。我的文字示例很简单,当我单击handleStartButton
时,所有汽车都已经移动完毕并停在了车库中。
因为我在每次循环迭代中都会重置缓冲区,这意味着车库的状态不再更改,并且其String
表示形式是相同的。因此,未触发更改侦听器,并且没有任何内容输出到TextArea。