从线程更新JavaFX场景图

时间:2015-03-25 09:44:50

标签: model-view-controller javafx javafx-8

我需要根据客户端输入更新我的GUI。从后台任务中调用我的控制器类方法。但它无法更新GUI,因为它不是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;
    }
}

控制器类

@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();      
}

}

2 个答案:

答案 0 :(得分:1)

要在其他帖子中停用button,您可以使用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());

如果你想使用一个新的线程来调用改变场景图的方法,你最好的机会就是使用Platform.runLater()

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

答案 1 :(得分: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();

}