无法在 JavaFX 应用程序中重置 StringBuffer
Cannot reset StringBuffer in JavaFX Application
我正在做一个大学课程项目,一个模拟车库的 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
对象引用了模型 class - garage
。 print()
Garage
class 的方法基本上是将内容附加到缓冲区。
完整的输出打印到控制台,工作正常。输出还用于设置 outputText
,一个 SimpleStringProperty
,它在 MainControllerClass
.
中附加了一个侦听器
outputText 成员:
public class Garage implements Externalizable {
...
public SimpleStringProperty outputText = new SimpleStringProperty();
...
}
通过单击按钮启动刷新 GUI。
主控制器class:
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'。
今天找到了答案。我的文本示例很简单,当我单击 handleStartButton
时,所有汽车都已完成移动并停在车库中。
因为我在每次循环迭代中都重置了缓冲区,这意味着车库的状态不再改变并且它的 String
表示是相同的。因此,没有触发更改侦听器,也没有向 TextArea 打印任何内容。
我正在做一个大学课程项目,一个模拟车库的 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
对象引用了模型 class - garage
。 print()
Garage
class 的方法基本上是将内容附加到缓冲区。
完整的输出打印到控制台,工作正常。输出还用于设置 outputText
,一个 SimpleStringProperty
,它在 MainControllerClass
.
outputText 成员:
public class Garage implements Externalizable {
...
public SimpleStringProperty outputText = new SimpleStringProperty();
...
}
通过单击按钮启动刷新 GUI。
主控制器class:
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'。
今天找到了答案。我的文本示例很简单,当我单击 handleStartButton
时,所有汽车都已完成移动并停在车库中。
因为我在每次循环迭代中都重置了缓冲区,这意味着车库的状态不再改变并且它的 String
表示是相同的。因此,没有触发更改侦听器,也没有向 TextArea 打印任何内容。