Удаление JavaFX из TableView - PullRequest
       6

Удаление JavaFX из TableView

0 голосов
/ 21 сентября 2018

Я работаю над приложением JavaFX и использую TableView как часть графического интерфейса следующим образом:

public TableView<Meal> meals;

И для него я назначил кнопку, которая должна удалять выбранные элементы.Чтобы сделать это, я использовал функцию, которая давала мне исключение NoSuchElementException

public void deleteMealButtonClicked()
{
    ObservableList<Meal> mealsSelected = meals.getSelectionModel().getSelectedItems();
    ObservableList<Meal> allMeals = meals.getItems();

    mealsSelected.forEach(allMeals::remove);
}

. Я отладил свой путь, чтобы выяснить, была ли проблема в последней строке метода.

После исследования довольноНекоторое время я случайно наткнулся на кусок кода, который решил проблему.Вот метод с кодом, который работает:

public void deleteMealButtonClicked()
{
    ObservableList<Meal> mealsSelected = meals.getSelectionModel().getSelectedItems();
    ObservableList<Meal> allMeals = meals.getItems();

    if (mealsSelected != null) {
        ArrayList<Meal> rows = new ArrayList<>(mealsSelected);
        rows.forEach(row -> meals.getItems().remove(row));
    }
}

Мой вопрос: почему работает второй метод, а не первый?Разве это не одно и то же, кроме добавления выбранных строк в ArrayList для второго метода?

Заранее спасибо.

1 Ответ

0 голосов
/ 21 сентября 2018

Модель выбора TableView должна соответствовать ObservableList в свойстве items, чтобы правильно отражать состояние таблицы.Другими словами, если элемент удаляется из items, он также должен быть удален из выбранных элементов модели выбора.

Это приводит к тому, что вы косвенно изменяете список selectedMeals, повторяя его, чтобы удалить содержащиеся в нем элементы из списка meals.Во многих коллекциях java.util итераторы работают быстро, и это приведет к ConcurrentModificationException;Я предполагаю, что модель выбора не очень быстрая, поэтому вы просто видите неопределенное поведение (в виде NullPointerException).

Второй вариант работает, потому что сначала вы делаете копию selectedMeals, а затемповторить копию.

Вы просите в комментарии способ не создавать копию;к сожалению, я не могу думать об этом.Однако вы можете немного упростить свой код, используя removeAll.

ObservableList<Meal> selected = ...;

// List.copyOf is a Java 10 method (and doesn't accept null elements)
table.getItems().removeAll(List.copyOf(selected));

// Pre Java 10 you can use toArray since ObservableList overloads removeAll
// with a version that takes a varargs parameter
table.getItems().removeAll(selected.toArray(new Meal[0]));

// or use the copy constructor of many collection classes
table.getItems().removeAll(new ArrayList<>(selected));

// In Java 11, toArray can be replaced with
table.getItems().removeAll(selected.toArray(Meal[]::new));
...