问题
I need to update my GUI based on client input. Calling my controller class method, from the background task works. But it can't update the GUI, because it is not the JavaFX application thread..please help.
I tried many of the related Q & A, but I am still confused.
Should I use Platform. runLater
or Task
?
Here's my class where I create an instance of controller
class
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 class
@FXML
Button B1 = new Button();
@FXML
public void handleButton1() {
B1.setDisable(true);
}
Application class
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);
}
}
I want to call ExcessFromOutside()
method from another thread.
I got a null pointer exception while trying to update the GUI Here's my application class
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);
}
}
and this is the class from where i tried to update the 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();
}
}
回答1:
To disable your button
in a different thread you can use Task's
updateValue.
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());
If you want to use a new thread to call a method, which alters the scene graph, the best chance you have is to use Platform.runLater()
in it.
//code inside Thread
...
// code to run on the JavaFX Application thread
Platform.runLater(new Runnable() {
@Override
public void run() {
handleButton1();
}
});
...
回答2:
You should get a NullPointerException when you run this program.
The problem is, the member of MainApp_Gui1
Controller_Gui1 cGui;
never gets a value.
Remove line "Controller_Gui1 cGui;" from this code:
public Scene getScene(Stage primaryStage) {
// Hudai hudai = new Hudai(primaryStage);
// return hudai.getScene();
Controller_Gui1 cGui;
cGui = FactoryClass.createGUI();
return cGui.getScene();
}
来源:https://stackoverflow.com/questions/29252167/update-javafx-scene-graph-from-a-thread