正如我在我的评论中提到的问题是,Canvas
真的就像一个绘图板。你已经在上面画了一些文字,然后你画了另一个文字而不删除以前的文字。
在你的情况下,当你想存储对文本的引用来更新它时,使用Pane
并在其上放置一个Text
实例会更合理。
我已经为您创建一个例子:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.text.Text;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
Pane pane = new Pane();
Text text = new Text("");
pane.getChildren().add(text);
Task<Void> task = new Task<Void>() {
String a = "Initial text";
@Override
public Void call() throws Exception {
int i = 0;
while (true) {
if (i > 4)
a = "I is bigger than 4";
if (i > 10)
a = "I is bigger than 10";
Platform.runLater(() -> {
text.setText(a);
// If you want to you can also move the text here
text.relocate(10, 10);
});
i++;
Thread.sleep(1000);
}
}
};
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
root.setCenter(pane);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
注:您也可以通过更新任务的messageProperty
内call()
那么Text
的textProperty
结合这消除Platform.runlater(...)
块属性。
例子:
Pane pane = new Pane();
Text text = new Text("");
text.relocate(10, 10);
pane.getChildren().add(text);
Task<Void> task = new Task<Void>() {
{
updateMessage("Initial text");
}
@Override
public Void call() throws Exception {
int i = 0;
while (true) {
if (i > 4)
updateMessage("I is bigger than 4");
if (i > 10)
updateMessage("I is bigger than 10");
i++;
Thread.sleep(1000);
}
}
};
text.textProperty().bind(task.messageProperty());
Thread th = new Thread(task);
th.setDaemon(true);
th.start();
您是否使用了'Canvas'和图纸送到'GraphicContext'?因为在这种情况下,最后的文本仍然存在,因为'Canvas'实际上就像一个绘图板。如果你想存储引用,我会建议使用'Pane'并在其上放置'Shape'对象。 – DVarga
JavaFX是事件驱动和单线程的。这意味着重绘和事件响应不能同时完成。长时间运行的任务应该在单独的线程上执行,这样它们不会阻塞UI的渲染,当任务完成时,它可以通过调用FX.deferAction()来同步回FX线程,FX.deferAction()将简单地执行主线程上的代码线。看这个http://stackoverflow.com/questions/528313/force-immediate-paint-in-javafx –