【问题标题】:javaFX cannot access Scene elementsjavaFX 无法访问场景元素
【发布时间】:2015-07-20 13:21:29
【问题描述】:

我是 javafX 的新手,已经阅读了各种教程,并在 Google 上进行了广泛搜索。我正在尝试编写一个多屏 javaFX 程序,其第二个屏幕有一个拆分窗格,其右窗格应显示一个网格和一个按钮。我用于多屏的框架是从 Angela Caiedo 的 MultipleScreens 框架教程 (https://github.com/acaicedo/JFX-MultiScreen/tree/master/ScreensFramework) 中复制而来的。

什么有效:屏幕框架在我的多个屏幕之间翻转方面是成功的。

我的问题:我点击屏幕 1 上的按钮移动到屏幕 2。屏幕 2 成功显示。在屏幕 2 上,我单击一个按钮以在我的 vBox 中填充数据。屏幕 2 的控制器类中的代码无法访问 vbox(或此屏幕上的任何其他已定义容器)。

我的主课设置了控制器屏幕。

public class FieldMapCreator extends Application {
    public static String mainID = "main";
    public static String mainFile = "MainMapFXMLDocument.fxml";
    public static String initialMapID = "initialMap";
    public static String initialMapFile = "FXMLMapPicture.fxml";
  @Override
  public void start(Stage stage) throws Exception {

    ScreensController mainContainer = new ScreensController();
    mainContainer.loadScreen(FieldMapCreator.mainID, FieldMapCreator.mainFile);
    mainContainer.loadScreen(FieldMapCreator.initialMapID, FieldMapCreator.initialMapFile);

    mainContainer.setScreen(FieldMapCreator.mainID);
    Group root = new Group();
    root.getChildren().addAll(mainContainer);
    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();
  }
}

我通过单击屏幕 1 上的按钮进入第二个屏幕。Button1 代码如下所示:

@FXML
private void initialMapButtonAction(ActionEvent event) {
    myController.setScreen(FieldMapCreator.initialMapID);
}

屏幕 2 有一个按钮,单击该按钮会执行一个为 vbox 创建数据的方法。屏幕 2 的 fxml 是这样的:

<AnchorPane id="AnchorPane" fx:id="mainAnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FieldMapCreator.FXMLMapPictureController">
   <children>
      <SplitPane fx:id="mapSplitPane" dividerPositions="0.29797979797979796" layoutX="3.0" layoutY="7.0" prefHeight="400.0" prefWidth="600.0">
        <items>
          <AnchorPane fx:id="anchorPaneLeft" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <Button fx:id="backButton" layoutX="14.0" layoutY="348.0" mnemonicParsing="false" onAction="#goToMainScreen" text="Back" />
               </children>
            </AnchorPane>
          <AnchorPane fx:id="anchorPaneRight" minHeight="0.0" minWidth="0.0" prefHeight="364.0" prefWidth="401.0">
               <children>
                  <Button fx:id="vBoxShowMap" layoutX="24.0" layoutY="346.0" mnemonicParsing="false" onAction="#buildMapFromNurseries" prefHeight="26.0" prefWidth="91.0" text="show map" />
                  <VBox fx:id="mapVBox" layoutX="24.0" layoutY="24.0" onMouseClicked="#vBoxMouseClicked" prefHeight="200.0" prefWidth="309.0" />
               </children></AnchorPane>
        </items>
      </SplitPane>
   </children>
</AnchorPane>

失败的代码在屏幕2的控制器类的“showInitialMap()”方法中。执行时,该方法的最后一行“mapVBox.getChildren().add(root)”,结果为null指针异常。我希望这可以通过 fxml 注入解决。我还尝试了注释掉的代码来使用场景查找检索“mapVBox”,但它也会导致空指针异常。控制器代码如下:

public class FXMLMapPictureController  implements Initializable, ControlledScreen  {

  ScreensController myController;
  static MyNode[][] mainField ;

  @FXML
  private AnchorPane mainAnchorPane;
  @FXML
  private static SplitPane mapSplitPane;
  @FXML
  private AnchorPane anchorPaneLeft;
  @FXML
  private static AnchorPane anchorPaneRight;
  @FXML
  private static VBox mapVBox;
  @FXML
  private Button vBoxShowMap;
  /**
   * Initializes the controller class.
   */
  @Override
  public void initialize(URL url, ResourceBundle rb) {
     // Should something be in here ??
  }

  public void goToMainScreen() {
    myController.setScreen(FieldMapCreator.mainID);
  }

  public void showInitialMap() {
    int row = userFieldMap.getNumRows();
    int col = userFieldMap.getNumCols();

    double gridWidth = 309/col;
    double gridHeight = 200/row;
    Group root = new Group();
    // initialize the field
    for (int idx = 0; idx < col; idx++) {
        for (int jdx = 0; jdx < row; jdx++) {
            // create plot
            Plot plot = new Plot(idx, jdx, "Plot" + idx + "/" + jdx);
            // Create node to hold the Plot
            MyNode node = new MyNode(idx*gridWidth, jdx*gridHeight, gridWidth, gridHeight, plot);
            // add plot to group
            root.getChildren().add(node);
        }
    }
    //Scene myScene = myController.getScene();
    //VBox mapVBox = (VBox)myScene.lookup("#mapVBox");
    mapVBox.getChildren().add(root);
  }

  @Override
  public void setScreenParent(ScreensController screenParent) {
    myController = screenParent;
  }

initialize() 方法中是否缺少某些内容?我想知道当我更改屏幕时是否设置不正确。我能够从包括初始化类在内的所有屏幕 1 方法毫无问题地访问初始屏幕的容器。当我在屏幕 2 中尝试相同操作时,我收到消息“屏幕尚未加载!!!”

感谢您提供的任何帮助。

【问题讨论】:

    标签: javafx


    【解决方案1】:

    您正在使用static 字段作为FXML 注入目标,这些目标在Java 8 中不起作用,并且不应该在任何其他版本中实现,因为静态UI 元素没有意义。这里有更详细的answer。大部分时间都使用static 字段意味着需要重新考虑应用程序的软件设计。

    【讨论】:

    • 谢谢!我不记得为什么我在字段中添加了“静态”(没有经验的新用户!),但删除它解决了问题。屏幕未正确加载,这就是我无法访问容器的原因。它现在加载。
    猜你喜欢
    • 2019-10-25
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多