JavaFX Tableview 显示 Image@Hashcode 而不是显示模型中的图像本身

JavaFX Tableview displaying Image@Hashcode rather than the Image itself from display model

我正在尝试在 table 视图中显示对象的图像,我创建了一个 DisplayModel class 以便在 table 列中显示相关值从一个可观察的集合中,我有 2 列包含字符串值和一个整数,所有这些都显示正常,我还有一张我希望显示的汽车图像,但它只会显示 Image@Hashcode 而不是图像本身。

我目前的实现如下:

显示型号class:

private ObjectProperty<Image> image;

private SimpleStringProperty make;

private SimpleStringProperty model;

private SimpleDoubleProperty price;

public DisplayModel(Image image, String make, String model, Double price) {
    this.image = new SimpleObjectProperty<>(image);
    this.make = new SimpleStringProperty(make);
    this.model = new SimpleStringProperty(model);
    this.price = new SimpleDoubleProperty(price);
}

public Image getImage() {

    return image.get();
}

public void setImage(Image displayImage) {

    this.image = new SimpleObjectProperty<>(displayImage);
}

FXML 文件控制器初始化方法中的实现:

  try {
                OutputStream targetFile = new FileOutputStream(s + "\" + imageUrl);
                targetFile.write(fileBytes);
                targetFile.close();
                File f = new File(s + imageUrl);
                image = new Image(f.toURI().toString());
            } catch (IOException e) {
                e.printStackTrace();
            }

使用 ImageView 控制器并尝试显示相同的图像显示效果很好,所以我想知道它是否与 ObjectProperty 实现或 TableView 控件有关。我最近遇到了一个类似且更常见的问题需要将 toString 方法重写为 return 实际值而不是 String@HashValue,我想知道是否有类似的方法可以解决此问题。

任何建议将不胜感激,感谢您的宝贵时间。

这与默认 cellFactory 返回的 TableCellupdateItem 实现有关。这是按如下方式实现的(忽略空单元格):

  • 如果该项目是 Node,则使用 setGraphic 将其作为参数显示。这会将 Node 添加到 TableCell.
  • 内的场景
  • 否则使用它的 toString 方法将对象转换为文本,并使用 setTextTableCell.
  • 中将结果值显示为文本

Image 不是 Node 的子类;因此你会得到后一种行为。

要更改此行为,您需要使用可以正确处理项目类型的自定义 cellFactory

ItemImage.setCellFactory(col -> new TableCell<Item, Image>() { // assuming model class named Car here; type parameters match the TableColumn

    private final ImageView imageView = new ImageView();
    
    {
        // set size of ImageView
        imageView.setFitHeight(50);
        imageView.setFitWidth(80);
        imageView.setPreserveRatio(true);
    
        // display ImageView in cell
        setGraphic(imageView);
    }
    
    @Override
    protected void updateItem(Image item, boolean empty) {
        super.updateItem(item, empty);
        imageView.setImage(item);
    }

});

请注意,通常您不会保留空单元格的图形。我决定在这种情况下这样做以保持单元格大小一致。