ComboBox中的图像在选择项目后消失

问题描述 投票:3回答:2

我创建了一个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());
                   }
               }
           };
       });


java javafx
2个回答
2
投票

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

public class MyData {
    private String name;
    private String imageUrl;

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

    public String getName() {
      return name;
    }

    public String getImageUrl() {
      return imageUrl;
    }
}

然后您可以使用该类创建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 -> {
    return new ListCell<MyData>() {
        @Override
        protected void updateItem(MyData item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                setText(item.getName());
                setGraphic(new ImageView(item.getImageUrl()));
            }
        }
    };
});

0
投票

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

关于将节点插入ComboBox项目列表的警告

ComboBox允许项目列表包含任何类型的元素,包括Node实例。 强烈不推荐将节点放入项目列表。这是因为默认单元格工厂只是将Node项直接插入到单元格中,包括在ComboBox'button'区域中。因为场景图一次只允许一个节点位于一个位置,所以这意味着当选择一项时,它会从组合框列表中删除...

推荐的解决方案是:

将相关信息放入组合框,然后提供自定义单元工厂

在您的情况下,这意味着可能需要简单的标签字符串列表,以及用于检索标签的某种映射。

作为一个简单的独立示例:

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);
© www.soinside.com 2019 - 2024. All rights reserved.