2015-03-25 166 views
0

我需要根據客戶端輸入更新我的GUI。調用我的控制器類的方法,從後臺任務的作品。但它不能更新GUI,因爲它不是JavaFX應用程序線程。請幫助。從線程更新JavaFX場景圖形

我嘗試了許多相關的Q & A,但我仍然感到困惑。

我應該使用Platform. runLater還是Task

這裏是我的課,我創建controller

public class FactoryClass { 

    public static Controller_Gui1 createGUI() { 
     FXMLLoader fxLoader = new FXMLLoader(); 
     fxLoader.setLocation(MainApp_Gui1.class.getResource("/com/Gui_1.fxml")); 
     AnchorPane anchorPane = null; 
     try { 
      anchorPane = (AnchorPane) fxLoader.load(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     Controller_Gui1 controller_Gui1 = (Controller_Gui1) fxLoader 
       .getController(); 
     Scene scene = new Scene(anchorPane); 
     //System.out.println(scene); 
     controller_Gui1.setScene(scene); 
     return controller_Gui1; 
    } 
} 

Controller類

@FXML 
Button B1 = new Button(); 
@FXML 
public void handleButton1() { 
    B1.setDisable(true); 
} 

應用類

public class MainApp_Gui1 extends Application { 
    Controller_Gui1 cGui; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     initScene(primaryStage); 
     primaryStage.show(); 
     System.out.println("asdasd"); 
     SceneSetting sceneSetting = new SceneSetting(); 
     //handleEvent(); 
     System.out.println("after"); 
     sceneSetting.setSceneAfter(); 
     System.out.println("after2"); 

    } 

    // creating scene 
    private void initScene(Stage primaryStage) throws IOException { 
     primaryStage.setScene(getScene(primaryStage)); 

    } 

    public Scene getScene(Stage primaryStage) { 
     Controller_Gui1 cGui; 
     cGui = FactoryClass.createGUI(); 
     return cGui.getScene(); 
    } 

    public void ExcessFromOutside() { 
     Platform.runLater(new Runnable() { 
      public void run() { 
       System.out.println(Platform.isFxApplicationThread()); 
       cGui.handleButton1(); 
      } 
     }); 

    } 

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

我的一個實例想從另一個線程調用ExcessFromOutside()方法。

我試圖更新的GUI 這是我的應用程序類

public class MainAppGui1 extends Application { 
Controller_Gui1 controller_Gui1; 
@Override 
public void start(Stage primaryStage) throws Exception { 
    initScene(primaryStage); 
    primaryStage.show(); 

} 
// creating scene 
public void initScene(Stage primaryStage) throws IOException { 
    FXMLLoader fxLoader = new FXMLLoader(); 
    fxLoader.setLocation(MainApp_Gui1.class.getResource("/com/Gui_1.fxml")); 
    AnchorPane anchorPane=new AnchorPane(); 
    anchorPane = (AnchorPane) fxLoader.load(); 
    Controller_Gui1 controller_Gui1 = (Controller_Gui1) fxLoader.getController(); 
    Scene scene = new Scene(anchorPane); 
    primaryStage.setScene(scene); 
} 
@FXML 
public void ExcessFromOutside() 
{ 
    Platform.runLater(new Runnable() {  
     @Override 
     public void run() { 

      System.out.println("called atleast"); 
      controller_Gui1.handleButton1(); 

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


} 

一個空指針異常,這是從那裏我試圖更新GUI類

public class Hudai { 
public static void main(String args[]) throws InterruptedException 
{ 
    new Thread() 
    { 
     public void run() 
     { 
      MainAppGui1.main(null); 
     } 
    }.start(); 
    Thread.sleep(5000); 
    MainAppGui1 m = new MainAppGui1(); 
    m.ExcessFromOutside();  
} 

} 
+0

你可以添加一些代碼來告訴我們什麼不適合你嗎? – ItachiUchiha 2015-03-25 09:51:55

+0

我應該使用任務嗎?這是我的第一篇文章..所以考慮... – xoxis 2015-03-25 10:29:32

+0

你爲什麼使用'MainAppGui1.main(null);'? – ItachiUchiha 2015-03-30 08:32:05

回答

0

你應該當你運行這個程序時得到一個NullPointerException異常。

的問題是,MainApp_Gui1

Controller_Gui1 cGui; 

從來沒有得到一個數值的成員。

刪除行「Controller_Gui1 cGui;」從這個代碼:

public Scene getScene(Stage primaryStage) { 
    // Hudai hudai = new Hudai(primaryStage); 
    // return hudai.getScene(); 
    Controller_Gui1 cGui; 
    cGui = FactoryClass.createGUI(); 
    return cGui.getScene(); 

} 
+0

我刪除this.but它dosent工作,因爲我想 – xoxis 2015-03-25 11:43:30

+0

另一件事,如果您使用@FXML初始化一個按鈕,不得不稱呼新的。所以@ FXML Button B1; //沒有新的按鈕 – gaRos 2015-03-25 11:52:20

+0

謝謝,,我剛開始javafx ..這就是爲什麼...和所有我想要更新我的gui使用這種方法 – xoxis 2015-03-25 11:56:11

1

要在不同的線程禁用button可以使用Task'supdateValue

Task<Boolean> task = new Task<Boolean>() { 
    @Override 
    public Boolean call() { 
     ... // The task that this thread needs to do 
     updateValue(true); 
     ... 
     return null; 
    } 
}; 
button.disableProperty().bind(task.valueProperty()); 

如果您想使用一個新的線程調用一個方法,它改變了場景圖,你有最好的機會是在它使用Platform.runLater()

//code inside Thread 
... 
// code to run on the JavaFX Application thread 
Platform.runLater(new Runnable() { 
    @Override 
    public void run() { 
     handleButton1(); 
    } 
}); 
... 
+0

如果你想調用'updateValue(true)',你需要一個'任務'。 – 2015-03-26 16:39:19

+0

哦,是的,對。編寫代碼段時出現錯字,感謝您指出:) – ItachiUchiha 2015-03-26 16:46:28

+0

非常感謝.Platform.runlater對我的項目更好..但它仍然無法工作。我不知道爲什麼..我的GUI從鼠標點擊改變..但我不能通過應用程序線程使用platform.runlater.My項目的方法更新它是一個雙人遊戲。我需要禁用從一個按鈕基於客戶端消息的網格。因此,我想從接收輸入流的線程中更改我的GUI。謝謝 – xoxis 2015-03-29 21:01:27