首页 > 解决方案 > 如何在 JavaFX 中扩展 GridPane 以覆盖 add() 会导致 NPE、Scene Builder 中断

问题描述

似乎是一个很少被问到的问题,所以也许扩展 GridPane 是完全错误的方法。我确实查看了如何扩展使用 FXML等的自定义 JavaFX 组件。

我正在尝试创建一个扩展 GridPane 的 LawnGrid 类,原因是重写 add() 方法以在添加 ImageView 节点时调整它们的大小。我还需要根据计算 LawnGrid 的大小来调整大小,并确定草坪是否宽于高,以保持纵横比。我忽略了似乎无关紧要的实施细节。

问题是当我将 LawnGrid 放入 .fxml 文件时,它不会在 SceneBuilder(在 IntelliJ 中)中显示,我认为这是我做错了什么的症状。我收到此错误:

java.lang.NullPointerException / javafx.fxml.LoadException:

它指向我的 view.fxml: ...(在 BorderPane 内)

<center>
    <LawnGrid fx:id="lawnGridPane" style=" -fx-border-color:green; -fx-border-width: 10; -fx-border-style: solid;" BorderPane.alignment="CENTER">

    </LawnGrid>
</center>

我想以编程方式添加约束,也许我需要它们,但似乎我会得到一个不同的错误。根据上面的链接答案,我的 LawnGrid.java 以:

@DefaultProperty(value = "lawnGrid")
public class LawnGrid extends GridPane {

更新:根据 Slaw 的反馈,我看到将 FXML 注释放在错误位置的错误,将其移至我的 FXController.java:

// lawn representation for lawn display in GUI
    @FXML
    private LawnGrid lawnGridPane = new LawnGrid();

FWIW 当我尝试运行它时,我也得到了一个 NPE,应用程序出现但在我在 LawnGrid 中引用“this”的行上给出了 NPE。我假设我缺少有关 JavaFX 如何实例化对象的基本知识,并且需要在某处创建 LawnGrid,但我认为 .fxml 文件设置了它。

编辑:我确实将 super() 添加到我的构造函数中,认为这可能会产生一些影响,但事实并非如此,我相信只是使用extends它调用 super()?这是 LawnGrid.java 中的构造函数:

   public LawnGrid(){
        super();
        // uses default max 10 rows 15 columns
        setupLawnConstraints();
    }

    public LawnGrid(double rows, double columns){
        super();
        this.numRows = rows;
        this.numCols = columns;
        setupLawnConstraints();
    }

    public LawnGrid(double rows, double columns, DoubleProperty preferredSquareSizeProperty) {
        super();
        this.numRows = rows;
        this.numCols = columns;
        this.preferredSquareSizeProperty = preferredSquareSizeProperty;
    }

标签: javajavafx-8fxmlgridpanefxmlloader

解决方案


最后,我在 GridPane(或一个子类)上调用 getHeight。当我终于清醒过来并认真思考时,我在它破裂之前检查了它。

JavaFX 对象的某些属性如果之前未设置,则为空。使用 getHeight() 访问它们会导致(正确的)空指针异常。

“高度”就是其中之一,有一个“_height”,但我还没有弄清楚如何访问它。


推荐阅读