JavaFX-瘦图像以防止heapspace过载?

JavaFX-瘦图像以防止heapspace过载?,javafx,imageview,heap-memory,Javafx,Imageview,Heap Memory,由于使用JavaFX编程图像查看器,我实现了具有以下结构的图像库: HBox-滚动窗格-VBox 这是基本结构,库对象的构造如下: 堆叠窗格-图像视图-标签 因为没有setAlignment方法用于ScrollPane,所以我将整个内容放在HBox中,尽管我不需要它的其他功能 这些方法负责库的生成和初始化: private HBox createScrollableLibrary() { libraryContent = new VBox(); libraryContent.se

由于使用JavaFX编程图像查看器,我实现了具有以下结构的图像库:

HBox-滚动窗格-VBox

这是基本结构,库对象的构造如下:

堆叠窗格-图像视图-标签

因为没有
setAlignment
方法用于
ScrollPane
,所以我将整个内容放在
HBox
中,尽管我不需要它的其他功能

这些方法负责库的生成和初始化:

private HBox createScrollableLibrary()
{
    libraryContent = new VBox();
    libraryContent.setPadding(new Insets(10));
    libraryContent.setAlignment(Pos.CENTER);
    libraryContent.setStyle("-fx-background-color: transparent");
    libraryContent.setSpacing(10);

    libraryScroll = new ScrollPane();
    libraryScroll.setHbarPolicy(ScrollBarPolicy.NEVER);
    libraryScroll.setStyle("-fx-background: rgb(0, 0, 0, 0.3);"
                  + "-fx-background-color: rgb(0, 0, 0, 0.3);");
    libraryScroll.setMinWidth(135);
    libraryScroll.setMaxWidth(135);
    libraryScroll.setContent(libraryContent);

    HBox root = new HBox();
    root.setPickOnBounds(false);
    root.getChildren().add(libraryScroll);
    return root;
}
以及:

public void initLibrary()
{   
可运行工作=()->
{
ObservableList previewList=FXCollections.observableArrayList();
图像视图预览;
标签;
StackPane标签;
对于(int i=0;iGUI.getLibraryContent().getChildren().addAll(预览列表));
};
加载=新螺纹(工作);
if(加载.isAlive())
loading.interrupt();
加载.start();
}
信息:
图片路径
是一个
可观察列表
,其中包含所有选定图像的路径,这些图像依次由
文件选择器
选择

现在我的问题是:

我知道使用大尺寸图片作为预览图片效率很低。 尽管我将堆空间增加到1GB,但当我添加更多图片时,堆速度会减慢,并引发
java.lang.OutOfMemoryError
异常,我猜限制大约是20-25个大尺寸图片。 如何“瘦身”普通图片,例如分辨率为1920x1080到1024x720?还是有其他机会让我的图书馆使用小而“快速”的图像?我可以缓冲我已经“计算”过的图像以使我的图像查看器更快吗


谢谢你的建议和帮助。如果需要,请批评我的代码

可以尝试在图像构造期间而不是之后设置预览图片的大小限制。

您是否尝试在图像构造期间而不是之后设置预览图片的大小限制?太棒了!我是个白痴,不知道requestedWidth和requestedHeight属性对此负责。用这些方法作为答案,我会把它标记为有用的。谢谢:)@JoseMartinez的建议将节省大量内存。另一个优化是为您的库使用
列表视图
(列表中的项目是映像的文件系统路径),并使用自定义单元格工厂来显示文件中的映像。有一个例子。这里的优点是,列表单元格在用户滚动和按需加载图像时被重用,因此,当图像滚动到屏幕外时,可以进行垃圾收集。(当然,你可以把这两个建议结合起来。)谢谢你,詹姆斯!
public void initLibrary()
{   
    Runnable work = () -> 
    {
        ObservableList<StackPane> previewList = FXCollections.observableArrayList();
        ImageView preview;
        Label label;
        StackPane previewAndLabel;

        for(int i = 0; i < picturePaths.size(); i++)
        {
            String path = picturePaths.get(i).toURI().toString();
            preview = new ImageView(new Image(path));
            preview.setPreserveRatio(true);
            preview.setFitWidth(100);
            //label = new Label(new File(path).getName());
            label = new Label("IMAGE");
            StackPane.setAlignment(label, Pos.CENTER_LEFT);
            previewAndLabel = new StackPane();
            previewAndLabel.getChildren().addAll(preview, label);
            previewList.add(previewAndLabel);
        }

        Platform.runLater(() -> GUI.getLibraryContent().getChildren().addAll(previewList));
    };
    loading = new Thread(work);
    if(loading.isAlive())
        loading.interrupt();
    loading.start();
}