当前位置: 首页 > 知识库问答 >
问题:

切换FXML场景

汝志
2023-03-14

当我运行该程序时,它加载第一个和第二个fxml,但继续显示第一个fxml(当它应该显示第二个时)。我可以使用相同代码的输入(即按钮)从第一个屏幕到第二个屏幕。

我尝试使用不同的加载器,每次设置场景时都使用。show()方法,但这些(或它们的许多变体)都不起作用。

我在调用方法时进行打印--这就是我确定它们被加载的方式(printline):

    null
public class Main extends Application {

    private static final FXMLLoader loader = new FXMLLoader();
    private static Stage mainStage;

    @Override
    public void start(Stage primaryStage) throws Exception {
        System.out.println("START METHOD");
        mainStage = primaryStage; //Copy Reference
        primaryStage.setScene(new Scene(Main.getLoader().load(Main.class.getResource("/res/screenOne.fxml"))));
        primaryStage.show();
    }

    public static FXMLLoader getLoader() {
        return loader;
    }

    public static Stage getStage() {
        return mainStage;
    }
}

/**
 * FXML Controller class
 */
public class firstUI implements Initializable {

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        System.out.println("INIT1 METHOD");
        try {
            Parent root = Main.getLoader().load(getClass().getResource("/res/screenTwo.fxml"));
            Main.getStage().setScene(new Scene(root));
        } catch (Exception ex) {
            Logger.getLogger(mainUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

/**
 * FXML Controller class
 */
public class secondUI implements Initializable {

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        System.out.println("INIT2 METHOD");
        System.out.println("Loaded Input UI");
    }
}

相反,输出(在调试中,如果stage.show()出现在前面)似乎是:

  1. Firstui代码(从开始)运行并初始化(未显示)。
  2. 运行(从firstUI init)并初始化(未显示)SecondDUI代码
  3. 完成secondui initialize代码并显示firstUI。
  4. 只有当输入(具有相同的开关代码)被按下时,它才会从第一个开关切换到第二个开关。

共有1个答案

卫骏
2023-03-14

您不需要加载器的引用来改变场景。
您可以有一个简单的main,例如:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setScene(new Scene(new FXMLLoader().load(getClass().getResource("/res/screenOne.fxml"))));
        primaryStage.show();
    }

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

其中screenone.fxml可以是(请注意窗格的fx-id)。
(要进行测试,您需要使用正确的控制器路径进行编辑):

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane fx:id="main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FirstUI">
   <children>
      <Label layoutX="155.0" layoutY="132.0" text="Screen 1">
         <font>
            <Font size="24.0" />
         </font>
      </Label>
      <Button layoutX="264.0" layoutY="246.0" mnemonicParsing="false" onAction="#changeScene" prefHeight="26.0" prefWidth="102.0" text="Change Scene" />
   </children>
</AnchorPane>

Firstui使用main更新场景:

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.Pane;

public class FirstUI  {

    @FXML Pane main;

    public void changeScene(ActionEvent e) {
        try {
            main.getScene().setRoot(new FXMLLoader().load(getClass().getResource("/res/screenTwo.fxml")));
        } catch (Exception ex) {
          ex.printStackTrace();
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" 
prefHeight="300.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/10.0.1" 
xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label layoutX="155.0" layoutY="132.0" text="Screen 2">
         <font>
            <Font size="24.0" />
         </font>
      </Label>
   </children>
</AnchorPane>
 类似资料:
  • 开始一个新游戏,改变关卡,或结束游戏时,为了给用户不同的效果呈现,大多需要切换不同的场景。Cocos2d-x 提供了一系列方式去做这件事情 场景切换。 场景切换的方式 有很多场景切换的方式,每种都有特定的方法,让我们来看看: auto myScene = Scene::create(); runWithScene() 用于开始游戏,加载第一个场景。只用于第一个场景! Director::getI

  • 我在这里阅读了几个与我的问题相关的问题/解决方案。但似乎什么都不管用。 所以我有一个全屏模式的primarystage,比如说,如果我点击一个按钮,它会改变场景。但舞台似乎显示了任务栏。我还通过将此添加到所有场景方法中解决了此问题。。 但是,场景中的过渡不是那么流畅。首先,它进入桌面,然后回到全屏...这不是理想的解决方案。 以下是我的初级阶段代码: 这是我改变场景的代码: 我不知道这是虫子还是什

  • 在public void start(Stage primaryStage)中程序开始时,我制作了A的对象并将其传递给primary Stage,然后在每个类中我更改它,并且它工作得很好。但我对此没有什么疑问: 这是一个正确的方法吗? 有没有其他方法可以在保留类的同时完成它,或者我应该只在主类中完成所有操作? 传递场景然后更改根节点是否更好? 对不起,如果我问得有点多了,但我读了很多关于它仍然没有

  • 我在class1中创建了一个场景,然后在Class2中创建了一个scene2。如何在两者之间切换? 这是第二节课,我有另一个场景。

  • 在 Cocos Creator 中,我们使用场景文件名(不包含扩展名)来索引指代场景。并通过以下接口进行加载和切换操作: cc.director.loadScene("MyScene"); 通过常驻节点进行场景资源管理和参数传递 引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁。如果我们需要用一个组件控制所有场景的加载,或在场景之间传递参数数据,就需要将该组件所在节点