【问题标题】:How to add images as an option in a combo box in Java FX如何在 Javafx 的组合框中添加图像作为选项
【发布时间】:2019-10-20 12:57:45
【问题描述】:

我尝试将图像添加到组合框中以将它们显示为选项,但是一旦我选择了图像,当下拉菜单再次打开以选择它们时它们会变成白色。

ImageView img1 = new ImageView(getClass().getResource("item1.png").toExternalForm());
ImageView img2 = new ImageView(getClass().getResource("item2.jpg").toExternalForm());
ImageView img3 = new ImageView(getClass().getResource("item3.jpg").toExternalForm());
img1.setFitHeight(60);
img1.setFitWidth(60);
img1.setPreserveRatio(true);
img2.setFitHeight(60);
img2.setFitWidth(60);
img2.setPreserveRatio(true);
img3.setFitHeight(60);
img3.setFitWidth(60);
img3.setPreserveRatio(true);
combobox.getItems().addAll(img1,img2,img3);

这些选项只工作一次,当我再次尝试选择它们时它们会变成白色。

【问题讨论】:

  • 有什么选择?另外,combobox 是什么?
  • java fx 中的组合框
  • 不要将节点(此处:imageView)添加为数据,永远不要添加,尤其是不要用于组合。相反,将图像添加为数据并实现一个自定义 ListCell,该 ListCell 将 ImageView 作为其图形,并将其图像设置为 updateItem 中的给定项目 .. 并阅读基本的 fx 教程现在
  • 好的,我会的,我想我搞砸了,谢谢大家

标签: java javafx


【解决方案1】:

您没有正确设置元素。您需要使用组合框的 setCellFactory() 方法才能正确生成列表项,因为项应该是相关数据的列表,而不是节点。然后 ListCell 对象可以在 itw 上调用 setGraphic(ImageView),并将列表中的元素更新为指定的图像。

这是我的一个旧项目的一些示例代码,它实际上是为 ListView 设计的,但与 ComboBox 的工作方式完全相同:

pieceData = FXCollections.observableArrayList("Boot", "Car", "Dog", "Hat", "Iron",
                                                  "Ship", "Thimble", "Wheelbarrow");
pieceSelection.setItems(pieceData);

pieceSelection.setCellFactory(e -> new ListCell<String>() {
    private ImageView view = new ImageView();
    @Override
    public void updateItem(String name, boolean empty) {
        super.updateItem(name, empty);
        if(empty) {
            setGraphic(null);
        }
        else {
            view.setImage(new Image("whatever the filepath to your image is"));
            // Add other set up for ImageView dimensions etc
            setGraphic(view);
        }
    }
});

请记住,这仅显示图像,因为需要调用方法 setText(String) 才能显示任何文本。

正如 kleopatra 所说,您应该阅读基本的 JavaFX 教程,因为这类东西有据可查且相对简单。

【讨论】:

  • 好答案 :) 只是一个小小的误解:项目应该是字符串列表 - 不一定,它们可以是任何类型(节点除外 - 甚至是可能的对于除组合之外的所有虚拟化控件),只要单元实现可以处理它。因此,可以考虑预先加载图像并将它们作为数据(而不是在每次调用 updateItem 时重新加载它们,这是非常频繁的)
  • 实际上像这样在每个updateItem 调用上创建图像可能是个坏主意。如果这些图像很大(使用fitWidth/fitHeight)或者它们的数量足够多,那么滚动时会降低性能。为这些图像创建缓存可能会更好......(一般代码将保持不变,您只需使用更复杂的代码来获取 Image 的实例即可使用)
  • 完全同意,此代码使用 100x100 图像,但缓存图像肯定比不断创建新对象更好
猜你喜欢
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2015-01-08
相关资源
最近更新 更多