Gridpane中的JavaFx图像大大降低了性能

Gridpane中的JavaFx图像大大降低了性能,java,image,performance,javafx,gridpane,Java,Image,Performance,Javafx,Gridpane,我想创建一个GridPane(嵌套在滚动窗格中),在其中动态地向GridPane添加单元格。每个单元格包含一个VBox,其中包含一个背景图像、几个标签和一个复选框。问题是,GridPane可以包含数百个VBox,在我的例子中,大约有300个VBox,有了这么多的VBox,GridPane的响应时间变得非常差。例如,当我点击一个复选框时,需要几秒钟才能选中/取消选中该复选框,这使得我的程序几乎无法使用。如果没有背景图像,GridPane的响应时间是完美的,所以我知道这里的问题是图像 这是我创建VB

我想创建一个GridPane(嵌套在滚动窗格中),在其中动态地向GridPane添加单元格。每个单元格包含一个VBox,其中包含一个背景图像、几个标签和一个复选框。问题是,GridPane可以包含数百个VBox,在我的例子中,大约有300个VBox,有了这么多的VBox,GridPane的响应时间变得非常差。例如,当我点击一个复选框时,需要几秒钟才能选中/取消选中该复选框,这使得我的程序几乎无法使用。如果没有背景图像,GridPane的响应时间是完美的,所以我知道这里的问题是图像

这是我创建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;
}

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

这并不是一个真正的答案,而是一组您可以尝试的建议。如果没有完整的解决方案,就很难对性能问题进行评论,这将允许在最小的应用程序中轻松地在本地重现这些问题


您可以尝试以下几点:

  • 使用虚拟化控件,例如
  • 另请参阅相关答案中的一些性能优化建议(其中一些可能不适用于您的情况):


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