Javafx2.2のComboboxesの問題に遭遇しました。これはシナリオです:
このペインには6つのコンボボックスがあります。それらの3つには固定項目があります:cboReport、cboSales、cboSend。それらの3つは、db(ObservableList)からデータを取得し、ペインが表示されたときに入力されます:cboFile、cboCustomer、cboVet
ウィンドウが閉じると、ペイン上のデータはresetGUI_editFilePane()メソッドを介してリセットされます。次のような行があります:
...
cboReport.getSelectionModel().clearSelection();
cboSales.getSelectionModel().clearSelection();
cboSend.getSelectionModel().clearSelection();
cboFile.getSelectionModel().clearSelection();
cboCustomer.getSelectionModel().clearSelection();
cboVet.getSelectionModel().clearSelection();
cboFile.getItems().clear();
cboCustomer.getItems().clear();
cboVet.getItems.clear();
...
ユーザーが「editFile」ボタンを押してペインを再度開くと、「固定アイテム」コンボボックスのみが選択をクリアしていることがわかります。動的に入力されたコンボボックスは、最後に選択されたアイテムを表示しますが、選択自体の値はnull
。これはグラフィックのバグのように見えますか、それとも何か問題がありますか?
この問題を回避する方法はありますか、またはコンボボックスをリセットする最良の方法は何ですか?
EDIT 2014/08/27:
これは正式にはバグではありません(clearSelection()は値をクリアしません):
https://bugs.openjdk.Java.net/browse/JDK-8097244
公式の「回避策」は、選択をクリアした後でComboBoxの値をクリアすることです。
cb.getSelectionModel().clearSelection();
// Clear value of ComboBox because clearSelection() does not do it
cb.setValue(null);
私はほぼ同じ状況に遭遇し、解決策を探している間にあなたの質問に出くわしました。幸い、私はComboBoxを強制的にリセットする回避策を考え出しました。ペインのデータをリセットすると、次のようなことをする代わりに:
cboVet.getSelectionModel().clearSelection();
cboVet.getItems.clear();
このようなことをする...
parentNode.getChildren().remove(cboVet);
cboVet = new ComboBox(); // do whatever else you need to format your ComboBox
parentNode.add(cboVet);
また、ComboBoxで再度setItems()を実行して、新しいものを入力する必要があります。これは理想的なソリューションではありませんが、提供されたclearSelection()メソッドが期待するとおりに機能しているようです。
とてもシンプルです。 ComboBoxのvalueプロパティを操作するだけです。どうぞ ....
ComboBox c;
c.valueProperty().set(null);
これがあなたのためにうまくいくことを願っています:-D
アイテムを取得して、すべて削除することができます。
cboVet.getItems().removeAll(cboVet.getItems());
Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
それが役に立てば幸い :)
ComboBoxスキンのbuttonCellフィールドを直接操作してリフレクションを使用します。
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void resetComboBox(ComboBox<T> combo) {
Skin<?> skin = combo.getSkin();
if(skin==null){
return;
}
combo.setValue(null);
Field buttonCellField;
try {
buttonCellField = skin.getClass().getDeclaredField("buttonCell");
buttonCellField.setAccessible(true);
ListCell buttonCell = (ListCell) buttonCellField.get(skin);
if(buttonCell!=null){
StringProperty text = buttonCell.textProperty();
text.set("");
buttonCell.setItem(null);
}
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
ButtonCellFactoryプロパティを介して独自のbuttonCell実装を提供することも可能だと思います
コンボボックスの選択を解除する必要があります。そして、このコードは私のために働きました:
List<Object> list = new ArrayList<>(comboBox.getItems());
comboBox.getItems().removeAll(list);
comboBox.getItems().addAll(list);
SelectionModelをクリアするには、Comboboxの新しいインスタンスを作成するよりも良い方法を見つけました(以前の回答の更新)。
myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);
しかし、このソリューションは他の問題を引き起こします。fxmlを使用すると、このコンボボックスは間違った場所に、間違ったパラメーターで配置されます。一部のfxmlパラメーターは、コントローラークラスのコードから直接再現するのが難しいため、コンボボックスをクリアする必要があるたびにこれを行うのはひどいです。
ソリューションは、メインのコントローラークラスコードで直接インスタンスを作成する代わりに、これらのコンポーネントが標準であっても、カスタムコンポーネントを使用します。これは、コンポーネント関連のイベントメソッドやその他のメソッドをメインのコントローラークラスへの参照を使用する別のクラスファイルに移動することで、メインのコントローラークラスの一部の行を解放するのにも役立ちます。
JavaFX FXMLアプリケーションでカスタムコンポーネントを作成する方法は、 http://docs.Oracle.com/javafx/2/fxml_get_started/custom_control.htm にあります。ただし、start(Satgeステージ)メソッドを使用したエントリポイントクラスがすでにある場合、アプリケーションのすべてのカスタムコンポーネントにCustomControlExampleクラスが必要なわけではないことに注意してください。
カスタムコンポーネントコントローラークラスからメインコントローラークラスへの参照で発生する可能性のあるエラーを解決する方法は、 JavaFxにあります:CustomComponentControllerクラスからメインコントローラークラスインスタンスを参照する方法
ComboBoxでも同じ問題が発生しました。 ComboBoxの項目を変更すると、ComboBoxのbuttonCellが正しく更新されません。これはグラフィックのバグのようです。
ComboBoxのbuttonCellフィールドを直接操作します。
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
これは、ComboBoxを再作成せずに見つけた最良のソリューションです。