从线程更新JavaFX场景图形

问题描述:

我需要根据客户端输入更新我的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

你应该当你运行这个程序时得到一个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

要在不同的线程禁用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