无法在JavaFX应用程序中重置StringBuffer

时间:2019-01-06 13:44:46

标签: java javafx stringbuffer

我正在做一个大学课程项目,这是一个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方法,例如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'。

1 个答案:

答案 0 :(得分:2)

今天找到了答案。我的文字示例很简单,当我单击handleStartButton时,所有汽车都已经移动完毕并停在了车库中。

因为我在每次循环迭代中都会重置缓冲区,这意味着车库的状态不再更改,并且其String表示形式是相同的。因此,未触发更改侦听器,并且没有任何内容输出到TextArea。