Выдающаяся стоимость 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);
Другие вопросы по тегам