2016-04-25 56 views
1

我想創建一個環境,在其中設置GUI,並且在用戶通過偵聽器修改其組件時,另一個線程每X秒向其添加新元素。 (這是一個遊戲,是的)從不同類中的不同線程修改JavaFX gui

我希望遊戲在一個類中,而在另一個類中是「元素加法器」線程 - 但是當然Java會抱怨我無法從另一個線程修改JavaFX GUI。

我見過使用Platform.runLater()的解決方案,但據我所見,所有這些解決方案都使用匿名內部類。我真的希望我的加法器在另一個(命名)類中。

任何提示將非常感激,這裏有一個最小版本的代碼,能重現問題:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 

public class DifferentThreadJavaFXMinimal extends Application { 

    private Thread t; 
    private GridPane gp; 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     gp = new GridPane(); 
     Scene gameScene = new Scene(gp, 600,500); 
     primaryStage.setScene(gameScene); 

     t = new Thread(new Thread2(instance())); 




     primaryStage.show(); 
     t.start(); 
    } 
    void addElement(int i) { 
     Button actualButton = new Button("TEST"); 
     gp.add(actualButton,i,i); 
    } 
    public DifferentThreadJavaFXMinimal instance(){ 
     return this; 
    } 

} 

class Thread2 implements Runnable { 
    private DifferentThreadJavaFXMinimal d; 

    Thread2(DifferentThreadJavaFXMinimal dt){ 
     d=dt; 
    } 

    @Override 
    public void run() { 
     for (int i=0;i<4;i++) { 
     d.addElement(i); 
     } 
    } 

} 

回答

1

你仍然可以使用獨立的類。

規則是UI的更改必須發生在FX應用程序線程上。您可以通過將來自其他線程的調用封裝在Runnable中來改變UI,通過Platform.runLater(...)

在您的示例代碼,d.addElement(i)改變UI,所以你會做:

class Thread2 implements Runnable { 
    private DifferentThreadJavaFXMinimal d; 

    Thread2(DifferentThreadJavaFXMinimal dt){ 
     d=dt; 
    } 

    @Override 
    public void run() { 
     for (int i=0;i<4;i++) { 
      final int value = i ; 
      Platform.runLater(() -> d.addElement(value)); 
      // presumably in real life some kind of blocking code here.... 
     } 
     System.out.println("Hahó"); 
    } 

} 
+0

非常感謝你James_D,我花了一段時間才能找出真正的,實際的解決方案,但您的建議被證明成爲謎題中缺失的一塊! 再次感謝! –