Изображение в ComboBox исчезает после выбора элемента - PullRequest
3 голосов
/ 21 января 2020

Я создал ComboBox и добавил к нему ярлыки, чтобы у меня был текст со значком, но значки исчезают после выбора элемента. Что я сделал не так?

Перед выделением:

enter image description here

После выбора:

enter image description here

ObservableList<Label> booruChoices = FXCollections.observableArrayList();
booruChoices.add(new Label("Gelbooru", new ImageView("https://gelbooru.com/favicon.ico")));
booruChoices.add(new Label("Danbooru", new ImageView("https://i.imgur.com/7ek8bNs.png")));
booruSelector.getItems().addAll(booruChoices);
booruSelector.setCellFactory(param -> {
    return new ListCell<Label>() {
        @Override
        public void updateItem(Label item, boolean empty) {
            super.updateItem(item, empty);

            if (item != null) {
                setGraphic(item.getGraphic());
                setText(item.getText());
            }
        }
    };
});

Ответы [ 2 ]

4 голосов
/ 21 января 2020

Первый ответ был не тем, что вы просите, моя ошибка. Вы используете один и тот же ImageView для ячейки в ComboBox и для кнопки ComboBox. ImageView может отображаться только в одном месте. Вам необходимо создать графический узел c для каждой ячейки в ComboBox. Label не является хорошим типом элемента для ComboBox, поскольку он представляет узел пользовательского интерфейса, а не объект данных. Вот пример класса, который содержит ваши данные:

public class MyData {
    private String name;
    private Image image;

    public MyData(String name, String imageUrl) {
        this.name = name;
        this.image = new Image(imageUrl);
    }

    public String getName() {
        return name;
    }

    public Image getImage() {
        return image;
    }
}

Затем вы можете создать ComboBox, используя этот класс:

ComboBox<MyData> comboBox = new ComboBox<>();
MyData data1 = new MyData("Gelbooru", "https://gelbooru.com/favicon.ico");
MyData data2 = new MyData("Danbooru", "https://i.imgur.com/7ek8bNs.png");
comboBox.getItems().addAll(data1, data2);
comboBox.setCellFactory(param -> new ListCell<>() {
    final ImageView graphicNode = new ImageView();

    @Override
    protected void updateItem(MyData item, boolean empty) {
        super.updateItem(item, empty);
        if (item == null || empty) {
            setText(null);
            setGraphic(null);
            graphicNode.setImage(null);
        } else {
            setText(item.getName());
            graphicNode.setImage(item.getImage());
            setGraphic(graphicNode);
        }
    }
});
0 голосов
/ 21 января 2020

Проблема в том, что вы помещаете Node (метки) непосредственно в список элементов комбинированного окна. Из Javadocs :

Предупреждение о вставке узлов в список элементов ComboBox

ComboBox позволяет списку элементов содержать элементы любого типа, включая экземпляры Node. Помещать узлы в список элементов настоятельно не рекомендуется . Это связано с тем, что фабрика ячеек по умолчанию просто вставляет элементы Node непосредственно в ячейку, в том числе и в область «кнопки» ComboBox. Поскольку граф сцены допускает одновременное размещение узлов только в одном месте, это означает, что при выделении элемента он удаляется из списка ComboBox ...

Рекомендуемое решение: 1016 *

поместите соответствующую информацию в ComboBox, а затем укажите настраиваемую фабрику ячеек

В вашем случае это будет означать, возможно, простой список строк для меток, и какая-то карта для получения ваших ярлыков.

В качестве простого автономного примера:

Map<String, String> listItems = new HashMap<>();
listItems.put("Gelbooru", "https://gelbooru.com/favicon.ico");
listItems.put("Danbooru", "https://i.imgur.com/7ek8bNs.png");

ComboBox<String> booruSelector = new ComboBox<>();
booruSelector.getItems().addAll(listItems.keySet());
Callback<ListView<String>, ListCell<String>> cellFactory = 
    param -> new ListCell<String>() {
        @Override
        protected void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (listItems.containsKey(item)) {
                setGraphic(new ImageView(listItems.get(item)));
            }
            setText(item);
        }
    };

booruSelector.setButtonCell(cellFactory.call(null));
booruSelector.setCellFactory(cellFactory);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...