Как этот код для поиска местоположения узла в GridPane вызывает исключение NullPointerException? - PullRequest
0 голосов
/ 26 апреля 2019

Я создаю недельное представление для простого приложения планирования в JavaFX.Вид состоит из 8x49 GridPane.В первом столбце показано время, а в первой строке - дни недели, аналогично представлению недели в календаре Google и другом программном обеспечении календаря.Когда пользователь меняет дату, я хочу очистить сетку, за исключением первого столбца и первой строки.Я заимствовал метод из ответа в другом вопросе 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 - это оператор if в getNodeFromGridPane.

Как я уже говорил, этот метод отлично работает в моем DayViewControllerкоторый в буквальном смысле представляет собой один и тот же код (WeekViewController.java и WeekView.fxml представляют собой прямое копирование и вставку дубликатов, единственное отличие до сих пор заключается в количестве столбцов в GridPane).При запуске на WeekViewController метод обрабатывает ровно 4 узла, прежде чем выдать исключение.Это одни и те же 4 узла каждый раз.Я попытался удалить 5-й узел из GridPane, и результаты не изменились.Окно отображается правильно и все остальное в функциях приложения.Я не вижу причин, по которым это может привести к NullPointerException.Ребята, вы в состоянии определить, чего мне не хватает?

ОБНОВЛЕНИЕ
На самом деле проблема в том, что метод getRowIndex() возвращает 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());
            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 Ответ

1 голос
/ 26 апреля 2019

Я думаю, что ваша проблема заключается в сравнении int с целым числом (оно может обрабатывать возможное нулевое значение).

На мой взгляд, вы можете сделать это, чтобы решить вашу проблему:

Убедитесь, что GridPane.getColumnIndex(node) и GridPane.getRowIndex(node) являются и другими значениями, отличными от нуля, например:

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;}

Надеюсь, это помогло вам:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...