Проблема очистки полетов
Я наткнулся на проблему с Comboboxes в javafx2.2. Это сценарий:
- Пользователи нажимают кнопку "editFile".
- Открывается другая панель (с помощью метода setVisible).
Эта панель содержит 6 списков со списком.
Три из них имеют фиксированные элементы: cboReport, cboSales, cboSend. Три из них получают свои данные из db (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", я замечаю, что только выделенные поля "fixed item" очистили свой выбор, динамически заполненные comboboxes показывают последний выбранный элемент, хотя значение из самого выбора null
. Это похоже на графическую ошибку для меня, или я делаю что-то неправильно?
Есть ли способ обойти эту проблему или лучший метод для reset комбобокса?
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);
Ответы
Ответ 1
Я столкнулся с почти той же ситуацией и наткнулся на ваш вопрос, ища решение. К счастью, у меня появилось обходное решение, которое заставляет ComboBoxes reset. Когда вы reset данные на своей панели, вместо того, чтобы делать что-то вроде:
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() будет.
Ответ 2
Это очень просто. Вам просто нужно работать со значением value ComboBox. здесь вы идете....
ComboBox c;
c.valueProperty().set(null);
Я надеюсь, что это сработает для вас:-D
Ответ 3
Вы можете получить элементы и удалить их:
cboVet.getItems().removeAll(cboVet.getItems());
Ответ 4
Я использую отражение с прямой обработкой поля 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
Ответ 5
Я только что протестировал рабочее решение с Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
Надеюсь, это поможет:)
Ответ 6
У меня была такая же проблема с ComboBox. Кнопка ButtonCell ComboBox не обновляется правильно, когда я меняю элементы ComboBox. Это похоже на графическую ошибку.
Я использую прямое управление полем buttonCell в ComboBox.
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
Это лучшее решение, которое я нашел, не создавая ComboBox.
Ответ 7
Чтобы очистить SelectionModel, я не нашел ничего лучше, чем создать новый экземпляр Combobox (обновление предыдущих ответов):
myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);
Но это решение порождает другие проблемы: если вы используете fxml, это combobox будет помещено в неправильное место и с неправильными параметрами. Некоторые параметры fxml вряд ли воспроизводятся непосредственно из вашего кода класса контроллера, и это ужасно, чтобы делать это каждый раз, когда вам нужно очистить поле со списком.
Решение использует пользовательские компоненты вместо создания экземпляров непосредственно в коде класса основного контроллера, даже если эти компоненты являются стандартными. Это также помогает освободить некоторые строки в вашем основном классе контроллера, перемещая связанные с ним методы событий и другие методы в отдельный файл класса, где вы используете ссылку на свой основной класс контроллера.
Как создать пользовательские компоненты в приложении JavaFX FXML можно найти в http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm, но обратите внимание, что класс CustomControlExample не нужен для каждого пользовательский компонент в вашем приложении, если он уже имеет класс точки входа со стартом (этап Satge).
Как разрешить возможные ошибки со ссылкой от класса контроллера пользовательского компонента до основного класса контроллера можно найти в JavaFx: как ссылаться на основной экземпляр класса контроллера из класса CustomComponentController?