无法在 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 - garageprint() 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 方法,例如 deletesetLenght,但似乎没有任何效果。但是我尝试清理缓冲区,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 打印任何内容。