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

javaFX无法访问场景元素

鲁波光
2023-03-14

我是javafX的新手,通过了各种教程,并在Googles上进行了大量搜索。我正在尝试编写一个多屏幕javaFX程序,它的第二个屏幕有一个拆分窗格,其右窗格应该显示一个网格和一个按钮。我用于多屏幕的框架复制自Angela Caiedo的MultipleScreens框架教程(https://github.com/acaicedo/jfx-multiscreen/tree/master/screensframework)。

工作原理:screens框架在我的多个屏幕之间的翻转方面是成功的。

我的问题:我点击屏幕1上的按钮移动到屏幕2。屏幕2成功显示。在屏幕2上,我单击一个按钮来填充VBox中的数据。屏幕2的my controller类中的代码无法访问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的controller类的“showInitialMap()”方法中。执行时,此方法的最后一行“mapvbox.getChildren().add(root)”将导致空指针异常。我希望通过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()方法缺少什么吗?我想知道当我更换屏幕时是否没有正确设置某些内容。我能够从所有Screen1方法(包括initialize类)毫无问题地访问初始屏幕的容器。当我在屏幕2中尝试相同的操作时,我得到的消息是“screen have not been loaded!!!”

谢谢你能提供的任何帮助。

共有1个答案

林彬
2023-03-14

您正在使用static字段作为fxml注入目标,这在Java 8中不起作用,也不应该在任何其他版本中实现,因为静态UI元素根本没有意义。这里有一个更详细的答案。大多数时候使用static字段意味着需要重新考虑应用程序的软件设计。

 类似资料:
  • 我想像一个一个地改变页面,但无法访问元素。http://prntscr.com/o0f4mx我试了所有的办法,但都没用。拜托,我需要帮助。 代码: 下面是我得到的错误:

  • 我一直在谷歌搜索和跟随不同的教程来学习如何做各种事情,到目前为止,我的进展还不错。但现在我已经停滞不前了。 我想做的是,当我的应用程序启动和用户按下登录按钮时,将它们转发到管理员主页上。 这是login.java中的代码: 非常感谢任何帮助。 附注。当用户单击该按钮时,我不只是想打开任意场景,而是想打开一个已经应用了quizapp.fxml、quizapp.css和administratorlog

  • 我写信是为了获取有关JavaFX的一些信息。我使用SceneBuilder设计了一个应用程序,它有一个主要场景,由几个文本字段和用于浏览文件的按钮组成。程序运行后还有一个用于输出的文本区域。我在控制器的初始化方法中添加了更改侦听器,以便在更新输出文本区域时修改日志文件。 最初,我使用输出文本区域来显示日志文件,对其进行了测试。一旦我从主文件菜单中选择了“查看日志”菜单项,我就能够在这个输出文本区域

  • 我想在一个扩展场景的类中画一张画布。当我按下场景上的按钮时,这个场景应该显示出来,这个场景是在扩展的类“GUI”中创建的。 为设置图像(我不知道要将ImageView作为子节点添加到哪个节点{类似不起作用}) 试图在画布上画画。(与上面的问题相同。在哪里添加此画布?) 类: 和类: PS:Jeah!我在这个论坛上的第一个问题。你好世界!

  • 问题内容: 我有一个使用javafx Scene来渲染某些东西的应用程序,并且我想将该渲染结果放入我在Javafx中创建的某些GUI中。我该怎么做? 基本上,有一些容器可以放入场景,然后将其放入GUI。 抱歉,如果是新手问题,我是JavaFX的新手 问题答案: 该场景只有一个顶级父节点作为根。您可以获取它并放入另一个场景。

  • 我创建了一个游戏,我想给它添加一个开始屏幕,我使用FXML添加了它,还添加了两个按钮(开始和退出)。 按下开始按钮后,我希望游戏加载场景并切换到游戏开始。我对如何做有一个粗略的想法,但我有点挣扎,因为我的SampleController类不知道如何启动游戏等,因为所有代码(以及加载初始开始菜单的代码)都在我的主类中,所以我尝试了这样的事情: 我尝试使用一个函数来切换场景,但它不起作用,也试图使用获