Выдающаяся стоимость Combobox
Я наткнулся на проблему с Comboboxes в javafx2.2. Это сценарий:
- Пользователи нажимают на кнопку "editFile".
- Другая панель становится видимой (с помощью метода setVisible).
Эта панель содержит 6 выпадающих списков. Три из них имеют фиксированные элементы: cboReport, cboSales, cboSend. Три из них получают свои данные из базы данных (ObservableList) и заполняются, когда панель становится видимой: cboFile, cboCustomer, cboVet
- Пользователь выбирает номер файла из cboFile. Остальные комбо-боксы установлены с правильными значениями.
- Пользователь нажимает кнопку сохранения, файл сохраняется как задумано.
- Затем пользователь нажимает кнопку закрытия.
Когда окно закрывается, данные на панели сбрасываются с помощью метода 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
, Для меня это похоже на графическую ошибку или я что-то не так делаю?
Есть ли способ обойти эту проблему или каков лучший способ сбросить комбинированный список?
РЕДАКТИРОВАТЬ 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);
8 ответов
Я столкнулся с почти такой же ситуацией и наткнулся на ваш вопрос, когда искал решение. К счастью, я нашел обходной путь, который заставляет 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);
Вам также нужно будет снова выполнить setItems() для вашего ComboBox, чтобы новый был заполнен. Это не идеальное решение, но, похоже, оно работает так, как я ожидаю, предоставленный метод clearSelection().
Это очень просто. Вам просто нужно поработать со свойством value ComboBox. Ну вот....
ComboBox c;
c.valueProperty().set(null);
Я надеюсь, что это работает для вас:-D
Вы можете получить элементы и удалить их все:
cboVet.getItems().removeAll(cboVet.getItems());
Я только что протестировал работающее решение с Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
Надеюсь, поможет:)
Я использую отражение с прямыми манипуляциями с полем buttonCell в скине ComboBox:
@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();
}
}
Я думаю, что это также возможно, предоставив свою собственную реализацию buttonCell через свойство buttonCellFactory
У меня была такая же проблема с ComboBox. Кнопка Ячейка ComboBox не обновляется правильно, когда я изменяю элементы ComboBox. Это похоже на графическую ошибку.
Я использую прямые манипуляции с полем buttonCell в ComboBox.
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
Это лучшее решение, которое я нашел без воссоздания ComboBox.
Чтобы очистить 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, но обратите внимание, что класс CustomControlExample не требуется для каждого пользовательского компонента в вашем приложении, если у него уже есть класс точки входа с методом start(Satge stage).
Как устранить возможные ошибки со ссылкой на класс контроллера пользовательских компонентов на класс основного контроллера можно найти в JavaFx: как ссылаться на экземпляр основного класса контроллера из класса CustomComponentController?
Мне нужно очистить выбор поля со списком. И этот код работал для меня:
List<Object> list = new ArrayList<>(comboBox.getItems());
comboBox.getItems().removeAll(list);
comboBox.getItems().addAll(list);