gpt4 book ai didi

JavaFX 需要多个 ImageView 节点而不是对一个节点的引用?

转载 作者:行者123 更新时间:2023-12-01 18:17:53 25 4
gpt4 key购买 nike

注意: 这里的一些代码并不是我在实践中的做法,而只是为了演示。我们假设资源始终存在并且不会引发错误。

为了在 TableView 中显示图像,我在测试 MVC 应用程序中从测试 POJO 中获得了一个原型(prototype),如下所示:

public Data(String name) {
this.nameProperty = new SimpleStringProperty(name);
this.imageProperty = new SimpleObjectProperty<ImageView>(new ImageView(new Image(Data.class.getResourceAsStream("img.png"))));
}

显然这效率不高,因为每个单元都需要流式传输资源、创建对象……等等。因此,我认为下一个合理的选择是将其移出并使其成为仅调用一次的静态对象。

private static final Image img = new Image(Data.class.getResourceAsStream("img.png"));

public Data(String name) {
this.nameProperty = new SimpleStringProperty(name);
this.imageProperty = new SimpleObjectProperty<ImageView>(new ImageView(img));
}

太棒了!仍然有效,我只需要阅读一次图像。图像也加载到单元格中,一切都很棒。我仍在创建大量 ImageView 对象,因此我也尝试将其移到外面。

private static final Image img = new Image(Data.class.getResourceAsStream("img.png"));

private static final ImageView imgView = new ImageView(img); // Assume loaded 2nd and properly always

public Data(String name) {
this.nameProperty = new SimpleStringProperty(name);
this.imageProperty = new SimpleObjectProperty<ImageView>(imgView);
}

上面是它停止工作的地方,正如我所期望的那样。在所有单元格中,只有最后一个单元格现在有图像,前面的单元格为空。我不明白为什么。

  • ImageView 节点是否应该只被引用一次?为什么我不能在多个单元格中引用该节点?

  • 是否有一些底层优化,只渲染一个节点一次?

  • 有没有一种方法可以让我只创建一个 ImageView 对象来做到这一点?

  • 使用 SimpleObjectProperty 是否会影响为什么我需要为同一个图像多次实例化 ImageView?

我宁愿只实例化一个对象,特别是因为我的应用程序只需要将单个静态图像放入单元格中(它不会被更改)。

最佳答案

一个节点只能在场景图中出现一次。来自 Javadocs :

A node may occur at most once anywhere in the scene graph. Specifically, a node must appear no more than once in all of the following: as the root node of a Scene, the children ObservableList of a Parent, or as the clip of a Node.

通常,ImageView 的几乎所有内存消耗都归结于 Image;因此,如果您在所有 ImageView 中共享相同的图像,您将使事情变得非常高效。

此外,一般来说,不同的单元格可能具有不同的大小,或者应用了不同的 CSS,因此在所有单元格之间共享单个 ImageView 根本行不通。 (如果 imgView.getParent() 显示在多个单元格中,您希望返回什么?)

您应该为您创建的每个单元格实例化一个ImageView(而不是为表中的每一项实例化一个)。然后,您可以在所有 ImageView 之间共享图像。创建的单元相对较少 - 它们根据需要重用以显示不同的项目。

因此,我认为您的问题实际上来自于您将 ImageView 放入模型(Data 类)中,而不是将其保留在 View (单元格)。

我会做这样的事情:

public class Data {
private final StringProperty name ;
public Data(String name) {
this.name = new SimpleStringProperty(name);
}
// getName/setName/nameProperty methods....
}

您没有在问题中显示您如何使用图像,但您会执行以下操作:

final Image img = new Image(Data.class.getResourceAsStream("img.png"));

// ...

TableView<Data> table = new TableView<>();
TableColumn<Data, String> column = new TableColumn<>("Name");
column.setCellValueFactory(cellData -> cellData.getValue().nameProperty());

column.setCellFactory(col -> new TableCell<Data, String>() {
private final ImageView imageView = new ImageView(img);

@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
setText(item);
setGraphic(imageView);
}
}
});

此解决方案只为每个单元格创建一个 Image 和一个 ImageView,而不是您创建 ImageView 的工作版本对于表的项目列表中的每个值。

关于JavaFX 需要多个 ImageView 节点而不是对一个节点的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28550779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com