Gridpane中的JavaFx图像大大降低了性能 [英] JavaFx Images in Gridpane slowing down performance drastically

查看:922
本文介绍了Gridpane中的JavaFx图像大大降低了性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个GridPane(嵌套在ScrollPane中),我将动态单元格添加到GridPane。每个单元格都包含一个带有BackgroundImage的VBox,一些标签和一个复选框。问题是,GridPane可以包含几百个VBox,在我的例子中有大约300个VBox,并且有很多VBox,Gridpane的响应时间变得非常糟糕。当我在CheckBox上单击时,它需要几秒钟,直到选中/取消选中CheckBox,这使得我的程序几乎无法使用。没有BackgroundImage,GridPane的响应时间是完美的,所以我知道这里的问题是图像



这是我创建VBox的代码:

 私人VBox createAlbumVBox(专辑专辑){
VBox container = new VBox();
container.setAlignment(Pos.BOTTOM_LEFT);
CheckBox checkBox = new CheckBox();
Label labelAlbum = new Label(album.getName());
Label labelArtist = new Label(album.getArtistName());
labelAlbum.setStyle( - fx-text-fill:#272727);
labelArtist.setStyle( - fx-text-fill:#272727);
背景背景;

if(album.getCover()!= null)
{
byte [] coverData = album.getCover();
Image image = new Image(new ByteArrayInputStream(coverData));
BackgroundSize bg = new BackgroundSize(100,100,true,true,true,false);
BackgroundImage backgroundImage = new BackgroundImage(image,BackgroundRepeat.NO_REPEAT,BackgroundRepeat.NO_REPEAT,BackgroundPosition.CENTER,bg);
background = new Background(backgroundImage);
}
其他
{
图片图片=新图片(/ ressources / covers / default-cover.png);
BackgroundSize bg = new BackgroundSize(100,100,true,true,true,false);
BackgroundImage backgroundImage = new BackgroundImage(image,BackgroundRepeat.NO_REPEAT,BackgroundRepeat.NO_REPEAT,BackgroundPosition.CENTER,bg);
background = new Background(backgroundImage);
}
checkBox.setOnMouseClicked(e - > {
if(checkBox.isSelected()){
album.getTitles()。forEach(t - > t.setReadyToSync (true));
} else {
album.getTitles()。forEach(t - > t.setReadyToSync(false));
}
});
container.setBackground(background);
HBox hBox = new HBox();
hBox.getChildren()。addAll(labelAlbum,labelArtist,checkBox);
hBox.setPrefHeight(30);
hBox.setStyle( - fx-background-color:rgba(255,255,255,0.4));
container.getChildren()。addAll(hBox);
返回容器;
}

我已经尝试使用ImageView而不是BackgroundImage。不幸的是,使用ImageView的性能与使用BackgroundImage一样差。

解决方案

这不是一个真正的答案,而是更多的一套你可以试试的建议。如果没有完整的 mcve ,很难对性能问题发表评论,这样可以在最小的应用程序中轻松地在本地重现这些问题。 / p>




您可以尝试的一些事情是:


  1. 使用背景加载图像

  2. 在LRU缓存中缓存加载的图像

  3. 使用虚拟控件,例如 ControlsFX GridView

另请参阅相关答案中的一些性能优化建议(其中一些可能不适用于您的情况):








此外,你的问题可能在您未显示的代码中。您的例程正在传递一个Album实例,其中包括专辑数据,包括二进制形式的图像数据。如果您动态地从数据库加载相册数据和图像,则该过程可能会降低或冻结您的应用程序,具体取决于您的操作方式。


I want to create a GridPane (which is nested in a ScrollPane) where I add dynamically cells to the GridPane. Each cell contains a VBox with a BackgroundImage, a few Labels and a Checkbox. The Problem is, that the GridPane can contain several hundreds VBoxes, in my case there are about 300 VBoxes and with this many VBoxes the response time of the Gridpane gets really poor. When I click for instance on a CheckBox it takes a few seconds until the CheckBox is selected/unselected, which makes my program pretty much unusable. Without the BackgroundImage the response time of the GridPane is perfect, so I know that the problem here are the Images

This is my Code to create a VBox:

private VBox createAlbumVBox(Album album) {
    VBox container = new VBox();
    container.setAlignment(Pos.BOTTOM_LEFT);
    CheckBox checkBox = new CheckBox();
    Label labelAlbum = new Label(album.getName());
    Label labelArtist = new Label(album.getArtistName());
    labelAlbum.setStyle("-fx-text-fill: #272727");
    labelArtist.setStyle("-fx-text-fill: #272727");
    Background background;

    if(album.getCover() != null)
    {
        byte[] coverData = album.getCover();
        Image image = new Image(new ByteArrayInputStream(coverData));
        BackgroundSize bg = new BackgroundSize(100,100,true,true,true,false);
        BackgroundImage backgroundImage = new BackgroundImage(image,BackgroundRepeat.NO_REPEAT,BackgroundRepeat.NO_REPEAT,BackgroundPosition.CENTER,bg);
        background = new Background(backgroundImage);
    }
    else
    {
        Image image = new Image("/ressources/covers/default-cover.png");
        BackgroundSize bg = new BackgroundSize(100,100,true,true,true,false);
        BackgroundImage backgroundImage = new BackgroundImage(image,BackgroundRepeat.NO_REPEAT,BackgroundRepeat.NO_REPEAT,BackgroundPosition.CENTER,bg);
        background = new Background(backgroundImage);
    }
    checkBox.setOnMouseClicked(e -> {
        if (checkBox.isSelected()) {
            album.getTitles().forEach(t -> t.setReadyToSync(true));
        } else {
            album.getTitles().forEach(t -> t.setReadyToSync(false));
        }
    });
    container.setBackground(background);
    HBox hBox = new HBox();
    hBox.getChildren().addAll(labelAlbum, labelArtist, checkBox);
    hBox.setPrefHeight(30);
    hBox.setStyle("-fx-background-color: rgba(255, 255, 255, 0.4)");
    container.getChildren().addAll(hBox);
    return container;
}

I already tried to use an ImageView instead of a BackgroundImage. Unfortunately the performance with an ImageView is as poor as with a BackgroundImage.

解决方案

This is not really an answer but more a set of suggestions you can try. It's hard to comment on performance issues without a complete mcve, which would allow the issues to be easily reproduced locally in a minimal application.


Some things you could try are:

  1. Use background loading for your images.
  2. Cache loaded images in a LRU cache.
  3. Use a virtualized control, such as a ControlsFX GridView.

See also some of the performance optimization suggestions in a related answer (some of which may not be applicable to your situation):


Also, your issue could be in code that you don't show. Your routine is being passed an Album instance which includes album data, including image data in binary form. If you load up your album data and images from a database dynamically, then that process could slow or freeze your application, depending upon how you do it.

这篇关于Gridpane中的JavaFx图像大大降低了性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆