Что ж, это исключение ясно показывает, что вы хотите привести String к Object. Значением по умолчанию Property является String, поэтому вы не можете привести его по умолчанию. Есть два варианта, чтобы справиться с этим.
Сначала вы можете настроить конвертер для этой особой коробки, как этот пример:
combo.setConverter(new StringConverter <Country>() {
@Override
public String toString(Country object) {
if(object == null) {
return "";
}
return object.toString();
}
@Override
public Country fromString(String string) {
return combo
.getItems()
.stream()
.filter(country -> country.toString().equals(string))
.findFirst()
.orElseGet(()-> combo.getSelectionModel().getSelectedItem());
}
});
Второй вариант - выбрать позицию этого объекта:
public static<T> T getComboBoxValue(ComboBox<T> comboBox){
if (comboBox.getSelectionModel().getSelectedIndex() < 0) {
return null;
} else {
return comboBox.getItems().get(comboBox.getSelectionModel().getSelectedIndex());
}
}
У меня также есть очень хорошая реализация списка автозаполнения здесь:
public class AutoCompleteComboBox {
public interface AutoCompleteComparator<T> {
boolean matches(String typedText, T objectToCompare);
}
public static<T> void autoCompleteComboBoxPlus(ComboBox<T> comboBox, AutoCompleteComparator<T> comparatorMethod) {
ObservableList<T> data = comboBox.getItems();
comboBox.setEditable(true);
comboBox.getEditor().focusedProperty().addListener(observable -> {
if (comboBox.getSelectionModel().getSelectedIndex() < 0) {
comboBox.getEditor().setText(null);
}
});
comboBox.addEventHandler(KeyEvent.KEY_PRESSED, t -> comboBox.hide());
comboBox.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
private boolean moveCaretToPos = false;
private int caretPos;
@Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.UP) {
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if (event.getCode() == KeyCode.DOWN) {
if (!comboBox.isShowing()) {
comboBox.show();
}
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if (event.getCode() == KeyCode.BACK_SPACE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if (event.getCode() == KeyCode.DELETE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if (event.getCode() == KeyCode.ENTER) {
return;
}
if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT || event.getCode().equals(KeyCode.SHIFT) || event.getCode().equals(KeyCode.CONTROL)
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
ObservableList<T> list = FXCollections.observableArrayList();
for (T aData : data) {
if (aData != null && comboBox.getEditor().getText() != null && comparatorMethod.matches(comboBox.getEditor().getText(), aData)) {
list.add(aData);
}
}
String t = comboBox.getEditor().getText();
comboBox.setItems(list);
comboBox.getEditor().setText(t);
if (!moveCaretToPos) {
caretPos = -1;
}
moveCaret(t.length());
if (!list.isEmpty()) {
comboBox.show();
}
}
private void moveCaret(int textLength) {
if (caretPos == -1) {
comboBox.getEditor().positionCaret(textLength);
} else {
comboBox.getEditor().positionCaret(caretPos);
}
moveCaretToPos = false;
}
});
}
public static<T> T getComboBoxValue(ComboBox<T> comboBox){
if (comboBox.getSelectionModel().getSelectedIndex() < 0) {
return null;
} else {
return comboBox.getItems().get(comboBox.getSelectionModel().getSelectedIndex());
}
}
}
Вы можете сделать автозаполнение вашего комбинированного списка следующим образом:
AutoCompleteComboBox.autoCompleteComboBoxPlus(combo, (typedText, itemToCompare) -> itemToCompare.toString().toLowerCase().contains(typedText.toLowerCase()) || itemToCompare.toString().equals(typedText));
И получите свою ценность следующим образом:
Country searchedCountry = AutoCompleteComboBox.getComboBoxValue(combo);
Надеюсь, это вам очень помогло, но это только из моих собственных проектов. Приветствия:)