什么是TextArea的良好可观察可附加基础?

时间:2018-01-21 17:19:47

标签: javafx

我有Found at position: 4,偶尔会附上新信息。

在一个单独的模块中,我有一个显示StringBuffer的JavaFX TextArea

现在,每次修改基础数据时,我都必须手动更新StringBuffer

是否有类似TextArea(我用于TableViews)的内容,我可以将其用作ObservableList的后端数据,因此我不必手动管理将更改推送到显示器?

我不喜欢使用TextArea。我很高兴使用任何可附加的数据结构来保存文本。

1 个答案:

答案 0 :(得分:3)

您可以考虑这样简单的事情:

import javafx.beans.binding.StringBinding;

public class ObservableStringBuffer extends StringBinding {

    private final StringBuffer buffer = new StringBuffer() ;

    @Override
    protected String computeValue() {
        return buffer.toString();
    }


    public void set(String content) {
        buffer.replace(0, buffer.length(), content);
        invalidate();
    }

    public void append(String text) {
        buffer.append(text);
        invalidate();
    }

    // wrap other StringBuffer methods as needed...

}

这样可以轻松编码绑定到文本区域。你可以简单地做

TextArea textArea = new TextArea();
ObservableStringBuffer buffer = new ObservableStringBuffer();
textArea.textProperty().bind(buffer);

// ...

buffer.append("Hello world");

但是,在此需要注意的是,您不必将缓冲区API的效率传输到文本区域:文本区域只有textProperty()代表其文本,可以仍然只能由set(...)setValue(...)进行修改。换句话说,当你附加到缓冲区时,你最终会得到textArea.setText(textArea.getText() + "Hello world")(而非textArea.appendText("Hello world")。如果你只是在寻找一个干净的API,那么这应该对你有用;如果你正在寻找有效率的东西,你必须自己拨打电话appendText,因为文本区textProperty()根本不支持}。

这是使用上述课程的SSCCE:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ObservableStringBufferTest extends Application {

    private int counter ;

    @Override
    public void start(Stage primaryStage) {
        ObservableStringBuffer buffer = new ObservableStringBuffer();

        TextArea textArea = new TextArea();
        textArea.setEditable(false);
        textArea.textProperty().bind(buffer);

        buffer.set("Item 0");

        Timeline timeline = new Timeline(new KeyFrame(
                Duration.seconds(1), 
                e -> buffer.append("\nItem "+(++counter))));

        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play();

        primaryStage.setScene(new Scene(new StackPane(textArea)));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}