JavaFX 更新问题?

JavaFX Update Issue?

我正在使用 JavaFX 开发游戏,现在我正在尝试创建一个加载屏幕,因为加载资产需要一些时间。我创建了一个显示多个进度条的 LoadingPane class,我确信它可以正常工作。但是,在下面的代码中,加载窗格在 loadAssets 函数之后才可见,即使我事先添加了它。当我 运行 下面的代码时,我得到一个空白阶段,用于加载资产所需的时间,然后是一个带有完成进度条的屏幕。

我没能找到有类似问题的人,也找不到任何类型的刷新或更新功能来强制场景在继续执行程序之前显示加载窗格。

注意:我删除了一些设置键盘输入处理的不相关代码。

public class Main extends Application{
    Pane root = new Pane();
    Scene mainScene = new Scene(root, Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT, Color.BLACK);

    static LoadingPane loadingPane  = new LoadingPane(3);
    private static int loadingIndex = 0;

    public static void main(String[] args) {
        if(Constants.DEBUG_MODE)
            System.out.println("WARNING: Game has launched in debug mode!");
        launch(args);
    }

    public static void updateProgress(double percent){
        loadingPane.setBarLength(loadingIndex, percent);
    }

    public static void loadAssets(){
        RoomLoader.createRooms();
        updateProgress(1.0);
        loadingIndex++;

        ProjectileLoader.load("imgs/projectiles/");
        ProjectileLoader.load(Constants.BATTLE_IMAGES_FILEPATH);
        updateProgress(1.0);
        loadingIndex++;

        BattleLoader.createBattles();
        updateProgress(1.0);
        loadingIndex++;
    }
    public static void updateProgress(double percent){
        loadingPane.setBarLength(loadingIndex, percent);
    }

    @Override
    public void start(final Stage primaryStage) {

        //root.getChildren().add(new javafx.scene.image.ImageView(new Image("imgs/loading.png")));
        root.setLayoutX(0);

        primaryStage.setScene(mainScene);
        primaryStage.show();
        primaryStage.toFront();

        primaryStage.setTitle("Branch");
        primaryStage.setResizable(false);
        //primaryStage.getIcons().add(new Image("core/imgs/soul/red.png"));
        //This allows the closing of the primaryStage to end the program
        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>(){
            @Override
            public void handle(WindowEvent t) {
                System.exit(0);
            }
        });

        root.resize(Constants.WINDOW_WIDTH, Constants.WINDOW_HEIGHT);
        primaryStage.getIcons().add(new Image("imgs/icon.png"));

       //End GUI setup

        //The problem lines
        root.getChildren().add(loadingPane);
        //refresh root?
        loadAssets();
    }
}

编辑:工作代码 对于遇到类似问题的任何人,下面是我用来让它工作的代码:

我替换了这个:

//The problem lines
root.getChildren().add(loadingPane);
//refresh root?
loadAssets();

有了这个:

root.getChildren().add   (loadingPane);

Task<Integer> loadingTask = new Task<Integer>() {
    @Override protected Integer call() throws Exception {
        loadAssets();

        return 1;
    }
};

loadingTask.setOnSucceeded(new EventHandler<WorkerStateEvent>(){
    @Override
        public void handle(WorkerStateEvent t){
            loadingPane.setVisible(false);
            load(); //note: this function sets up the actual game
                    //updating the GUI, adding game elements, etc
        }
    });


new Thread(loadingTask).start();

我不能说这是解决此问题的最佳方法,但我可以说它很有效。祝你好运!

JavaFX 应用程序在称为应用程序线程的特定线程上运行,在其他线程上运行,以便在执行一些昂贵的操作时使 GUI 响应,例如在您加载资产的情况下,您需要在您创建的另一个 Thread 上加载资产您自己或者您可以使用 Task,这是 JavaFX 类 之一,旨在用于此类用例。

我建议您在 official javadocs

中阅读有关 Task 的内容

更新方法需要一个单独的线程。

代码 运行s 以线性方式,一位代码 运行s 然后是下一位。使用单独的线程,两“行”代码可以 运行 并排。进程 运行s 和 GUI 同时更新。