2016-09-07 75 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