私はJavaFXのアプリに取り組んでいると、次のようにGUIの一部としてテーブルビューを使用しています:
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に選択された行を追加すること以外、基本的には同じものではありませんか?
前もって感謝します。
選択モデルは、TableView
守らなければならないObservableList
でitems
適切にテーブルの状態を反映するために、プロパティを。要素がから削除された場合、他の言葉では、items
それも選択モデルの選択項目から削除する必要があります。
あなたのこの結果は、間接的に変更することselectedMeals
から含まれている要素削除するには、それを反復しながら、リストをmeals
リストします。多くのではjava.util
コレクションの反復子は、フェイルファストであり、これがもたらすであろうConcurrentModificationException
。私は、あなたは、単に(の形で不確定な振る舞いを見て選択モデルは、高速フェールとされていないと思いますNullPointerException
)。
あなたが最初のコピーを作成するため、2番目のオプションは働きselectedMeals
、その後、コピーを繰り返します。
あなたは、コピーを作成しないための方法のためのコメントで尋ねます。残念ながら、私は1つを考えることはできません。あなたは使用してコードビットを簡素化することができ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));