Почему getTableRow (). GetItem () возвращает пустую ссылку даже на непустые строки? - PullRequest
3 голосов
/ 05 августа 2020

Итак, я создал это маленькое приложение с панелью поиска и табличным представлением. Когда экран инициализируется, я использую tableView.setItems(), чтобы добавить фиксированный список элементов в мою таблицу. Позже, когда пользователь выполняет запрос, создается отфильтрованный список, и я снова вызываю tableView.setItems(). Когда список визуализируется, мой код вызывает методы для getRowTable().getItem(), чтобы добавить поведение кнопке в каждой строке. Все отображается правильно, однако кажется, что updateItem() вызывается больше раз, чем следует, а getRowTable().getItem() возвращает ссылку null, заставляя программу генерировать исключение.

Что это вызывает? Код ниже.

Приложение. java

public class App extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        URL url = getClass().getResource("/com/lib/fxml/search-movies.fxml");

        try {
            Parent root = FXMLLoader.load(url);
            Scene scene = new Scene(root, 1024, 768);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}

SearchMovies. java

public class SearchMovies {
    @FXML TextField searchField;
    @FXML TableView<Movie> tableView;
    @FXML TableColumn<Movie, String> titleColumn;
    @FXML TableColumn<Movie, String> directorColumn;
    @FXML TableColumn<Movie, Void> likeColumn;

    private ArrayList<Movie> movieList = new ArrayList<>(Arrays.asList(
        new Movie("Persona", "Ingmar Bergman"),
        new Movie("City of God", "Fernando Meirelles"),
        new Movie("Pulp Fiction", "Quentin Tarantino"),
        new Movie("Gone Girl", "David Fincher"),
        new Movie("Fight Club", "David Fincher"),
        new Movie("Perfect Blue", "Satoshi Kon"),
        new Movie("Prisoners", "Denis Villeneuve"),
        new Movie("Sin City", "Frank Miller"),
        new Movie("Mean Girls", "Mark Waters"),
        new Movie("Breakfast Club", "John Hughes"),
        new Movie("Sixteen Candles", "John Hughes"),
        new Movie("Reservoir Dogs", "Quentin Tarantino")
    ));

    private ObservableList<Movie> observableMovieList = FXCollections.observableArrayList(movieList);

    @FXML
    public void initialize() {
        titleColumn.setCellValueFactory(item -> item.getValue().titleProperty());
        directorColumn.setCellValueFactory(item -> item.getValue().directorProperty());

        likeColumn.setCellFactory(col -> new TableCell<Movie, Void>() {
            private final Button button = new Button("LIKE");

            @Override
            public void updateItem(Void item, boolean empty) {
                super.updateItem(item, empty);

                if (empty) {
                    setGraphic(null);
                } else {
                    Movie movie = getTableRow().getItem();
                    button.setOnAction(e -> System.out.println("Someone liked " + movie.getTitle() + " " + movie.getDirector()));
                    System.out.println("Rendering row for " + movie.getTitle() + " by " + movie.getDirector());
                    setGraphic(button);
                }
            }
        });

        tableView.setItems(observableMovieList);
    }

    @FXML
    public void search() {
        String query = searchField.getText();

        if (query == null || query.isBlank() || query.isEmpty()) {
            return;
        }

        observableMovieList = FXCollections.observableArrayList(filterMovies(query));
        tableView.setItems(observableMovieList);
    }

    private ArrayList<Movie> filterMovies(String query) {
        ArrayList<Movie> filteredMovies = new ArrayList<>();

        for (Movie movie : movieList) {
            if (movie.getTitle().contains(query) || movie.getDirector().contains(query)) {
                filteredMovies.add(movie);
            }
        }

        return filteredMovies;
    }

    private class Movie {
        private final StringProperty title;
        private final StringProperty director;

        public Movie(String title, String director) {
            this.title = new SimpleStringProperty(title);
            this.director = new SimpleStringProperty(director);
        }

        public String getTitle() {
            return title.get();
        }

        public StringProperty titleProperty() {
            return title;
        }

        public void setTitle(String title) {
            this.title.set(title);
        }

        public String getDirector() {
            return director.get();
        }

        public StringProperty directorProperty() {
            return director;
        }

        public void setDirector(String director) {
            this.director.set(director);
        }
    }
}

search-movies.f xml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="610.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.lib.controllers.SearchMovies">
   <children>
      <TextField fx:id="searchField" prefHeight="49.0" prefWidth="734.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="192.0" AnchorPane.topAnchor="35.0" />
      <Button mnemonicParsing="false" onAction="#search" prefHeight="49.0" prefWidth="155.0" text="SEARCH" AnchorPane.leftAnchor="844.0" AnchorPane.rightAnchor="25.0" AnchorPane.topAnchor="35.0" />
      <TableView fx:id="tableView" layoutX="50.0" layoutY="120.0" prefHeight="627.0" prefWidth="974.0" AnchorPane.bottomAnchor="21.0" AnchorPane.leftAnchor="25.0" AnchorPane.rightAnchor="25.0" AnchorPane.topAnchor="120.0">
        <columns>
          <TableColumn fx:id="titleColumn" prefWidth="75.0" text="Title" />
          <TableColumn fx:id="directorColumn" prefWidth="433.0" text="Director" />
            <TableColumn fx:id="likeColumn" prefWidth="215.0" text="Like" />
        </columns>
         <columnResizePolicy>
            <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
         </columnResizePolicy>
      </TableView>
   </children>
</AnchorPane>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...