2016-09-07 82 views
1

我想更改文本我创建一个任务并增加i,但我想在此更改i时在同一位置设置新文本,但旧文本不会消失。这是我的代码。摇摆我会用repaint()JavaFX更新文本任务

Task task = new Task<Void>() { 
    @Override 
    public Void call() throws Exception { 
     int i = 0; 
     while (true) { 
      final int finalI = i; 
      Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 

       String a = "aaa"; 
       if(finalI>4){ 
        a = "sadsa"; 
       } 
       if(finalI>10){ 
        a = "sadsadsadsadsad"; 
       } 
       gc.fillText(a, 150, 250+10); 
      } 
      }); 
      i++; 
      Thread.sleep(1000); 
     } 
    } 
}; 
Thread th = new Thread(task); 
th.setDaemon(true); 
th.start(); 
+0

您是否使用了'Canvas'和图纸送到'GraphicContext'?因为在这种情况下,最后的文本仍然存在,因为'Canvas'实际上就像一个绘图板。如果你想存储引用,我会建议使用'Pane'并在其上放置'Shape'对象。 – DVarga

+0

JavaFX是事件驱动和单线程的。这意味着重绘和事件响应不能同时完成。长时间运行的任务应该在单独的线程上执行,这样它们不会阻塞UI的渲染,当任务完成时,它可以通过调用FX.deferAction()来同步回FX线程,FX.deferAction()将简单地执行主线程上的代码线。看这个http://stackoverflow.com/questions/528313/force-immediate-paint-in-javafx –

回答

2

正如我在我的评论中提到的问题是,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); 
    } 
} 

注:您也可以通过更新任务的messagePropertycall()那么TexttextProperty结合这消除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(); 
+0

Ooo谢谢你的帮助!我想点击该答案是有帮助的。感谢您的帮助 –

+0

我还有一个问题,我可以在一个窗格可能有三个不同的文本文本=新文本(“”)与不同的位置? –

+1

当然,尽可能多的你想要的。你可以像“Text text = new Text(”sample“)一样添加它们; 。pane.getChildren()加(文字);'。然后你可以用'text.relocate(100,100);'来设置位置。 – DVarga