提问者:小点点

此用于在GridPane中查找节点位置的代码如何导致NullPointerException?


我正在为JavaFX中的一个简单调度应用程序创建一个周视图。该视图由一个8x49GridPane组成。第一列显示时间,第一行显示一周中的日子,类似于谷歌日历和其他日历软件上的周视图。当用户更改日期时,我想清除除第一列和第一行之外的网格。我从另一个SO问题的答案中借用了一个方法。它在我的天视图面板中完美地工作(完全相同的代码,除了是一个2x49的网格),但在我的周视图面板中抛出一个NullPointerException

我添加了两个System. out.println()语句来查看是否有任何东西实际上是null。据我所知,什么都不是。我删除了GridPane.getRowIndex(node)==row,看看这是否可能是问题所在,并且异常不再发生,这让我相信这个语句以某种方式导致了异常。

这是从Shreyas Dave借用的违规方法。我添加了行号以与下面的堆栈跟踪相关联:

130: private Node getNodeFromGridPane(GridPane gridPane, int col, int row) {
131:     System.out.println("Gridpane: " + gridPane.getChildren().toString());
132:     for (Node node : gridPane.getChildren()) {
133:         System.out.println("Node: " + node.toString());
134:         if (GridPane.getColumnIndex(node) == col && GridPane.getRowIndex(node) == row) {
135:             return node;
136:         }
137:     }
138:     return null;
139: }

这是调用getNodeFromGridPane的方法:

    private void clearAppointmentsColumn(){
        for(int i = 0; i < 49; i++){
            Node node = getNodeFromGridPane(grid, 1, i+1);
            if(node != null){
                grid.getChildren().remove(node);
            }
        }
    }

这是System. out.println()语句的输出和堆栈跟踪的相关部分:

Gridpane: [Label@4b093381[styleClass=label]'Monday', Label@44994e49[styleClass=label]'Tuesday', Label@6f3b59bb[styleClass=label]'Saturday', Label@61dea913[styleClass=label]'Sunday', Label@2f46425[styleClass=label]'Thursday', Label@37370341[styleClass=label]'Wednesday', HBox@3b64a2ab, HBox@3031ce6e, HBox@2e8b5a86, HBox@7d2748fa, HBox@1f40aa1b, HBox@46404c48, HBox@6b829580, HBox@131fffd9, HBox@5a3e3d63, HBox@2f889183, HBox@5d56c9f0, HBox@5f2d13f2, HBox@37bf973, HBox@145f557e, HBox@6db9d36a, HBox@738a8500, HBox@49655482, HBox@75505497, HBox@5b1abd8b, HBox@557f1cad, HBox@223c3dd1, HBox@4d317b8e, HBox@3b093ec, HBox@1183928c]
Node: Label@4b093381[styleClass=label]'Monday'
Node: Label@44994e49[styleClass=label]'Tuesday'
Node: Label@6f3b59bb[styleClass=label]'Saturday'
Node: Label@61dea913[styleClass=label]'Sunday'
Caused by: java.lang.NullPointerException
    at appointmentcalendar.WeekViewController.getNodeFromGridPane(WeekViewController.java:134)
    at appointmentcalendar.WeekViewController.clearAppointmentsColumn(WeekViewController.java:108)
    at appointmentcalendar.WeekViewController.setDate(WeekViewController.java:74)
    at appointmentcalendar.MainWindowController.refreshWeekView(MainWindowController.java:467)
    at appointmentcalendar.MainWindowController.datePicked(MainWindowController.java:455)
    at appointmentcalendar.AppointmentCalendar.switchToMainWindow(AppointmentCalendar.java:90)
    at appointmentcalendar.LoginFormController.loginClicked(LoginFormController.java:71)
    ... 75 more

第134行是getNodeFromGridPane中的if语句。

正如我所说的,这个方法在我的DayViewController中完美地工作,这实际上是相同的代码(WeekViewController.javaQueView. fxml是直接复制和粘贴副本,到目前为止唯一的区别是GridPane中的列数)。当在BritViewController上运行时,该方法在抛出异常之前正好处理了4个节点。它们每次都是相同的4个节点。我尝试从GridPane中删除第5个节点,结果没有改变。窗口显示正常,应用程序中的其他所有功能。我看不出这会抛出NullPointerException的任何原因。你们能发现我遗漏的东西吗?

UPDATE
问题实际上是getRowIndex()方法正在为某些节点返回null,正如Bastida所指出的那样。将该方法修改为以下代码后,问题消失了:

    private Node getNodeFromGridPane(GridPane gridPane, int col, int row) {
        System.out.println("Gridpane: " + gridPane.getChildren().toString());
        for (Node node : gridPane.getChildren()) {
            System.out.println("Node: " + node.toString());
            Integer c = GridPane.getColumnIndex(node);
            c = c == null ? 0 : c;
            Integer r = GridPane.getRowIndex(node);
            r = r == null ? 0 : r;
            if (c == col && r  == row) {
                return node;
            }
        }
        return null;
    }

谢谢你。


共1个答案

匿名用户

我认为你的问题是将int与Integer进行比较(它可以处理可能的空值)。

在我看来,你可以这样做来解决你的问题:

验证GridPane. getColumnIndex(node)GridPane.getRowIndex(node)都是另一个值而不是null,如下所示:

private Node getNodeFromGridPane(GridPane gridPane, int col, int row) {
System.out.println("Gridpane: " + gridPane.getChildren().toString());
for (Node node : gridPane.getChildren()) {
    System.out.println("Node: " + node.toString());
    if (GridPane.getColumnIndex(node) != null && GridPane.getRowIndex(node) != null &&
        GridPane.getColumnIndex(node) == col && GridPane.getRowIndex(node) == row) {
        return node;
    }
}
return null;}

希望这对你有帮助:)