选择项目后,组合框中的图像消失

时间:2020-01-21 13:09:32

标签: java javafx

我创建了一个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 个答案:

答案 0 :(得分:4)

第一个答案不是您的要求,我的错误。 您正在为ImageView中的单元格和ComboBox的按钮使用相同的ComboBoxImageView只能显示在一个地方。 您需要为ComboBox中的每个单元创建一个图形节点。 Label对于ComboBox而言不是很好的项目类型,因为它表示UI节点而不是数据对象。 这是保存数据的类的示例:

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);
        }
    }
});

答案 1 :(得分:0)

问题是您将Node(标签)直接放入了组合框的项目列表中。来自Javadocs

关于将节点插入组合框项目列表的警告

ComboBox允许项目列表包含任何类型的元素,包括Node实例。 强烈不建议,将节点放入项目列表。这是因为默认单元格工厂仅将Node项直接插入到单元格中,包括在ComboBox'button'区域中。因为场景图仅允许节点是在一个地方的时间,这意味着,当一个项目被选中它变得与组合框列表中删除...

推荐的解决方案是:

将相关信息放入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);
相关问题