グリッド内にアーティストとアルバムを表示するこの音楽再生アプリがあります。私はListViewとカスタムListCellを使ってこのグリッドを作成しました。ただし、高さが画面のサイズに応じて3行または4行をレンダリングするのに十分な場合でも、ListViewは初期化されたときに2つ以上のセルを表示しません。リストビューは、最初の2つのセルのうちの1つが上にホバリングされたとき、残りのセルをレンダリングします。下のリンクを見て、実際の問題を見てください。JavaFX ListViewがビューポートを埋めるのに十分なセルを表示しない
私は、リストビューの高さを確認したのだが、確かにその親を埋めるために拡大しているので、私はListViewコントロールは、細胞をレンダリングする必要があることを決定する方法で起こっているファンキーなものがあると信じて。私は、それが根本的な問題である場合、ListViewに正しい数のセルを描画させる方法を発見したいと思っています。あるいは、コードに間違いがあると、それにも少し光を当てるのは素晴らしいことです。私は私のコントローラと私のカスタムListCellのコードを以下に掲載しました。
リストビューを初期化コントローラ:
public class ArtistsController implements Initializable {
@FXML
private ListView<ArrayList<Artist>> grid;
@Override
public void initialize(URL location, ResourceBundle resources) {
List<Artist> artists = Library.getArtists();
Collections.sort(artists);
grid.setCellFactory(x -> new ArtistListCell<>());
ObservableList<ArrayList<Artist>> rows = FXCollections.observableArrayList();
ArrayList<Artist> row = new ArrayList<>();
int col;
for (int i = 0; i < artists.size(); i++) {
col = i % 5;
if (col == 0) {
row = new ArrayList<>();
rows.add(row);
}
row.add(artists.get(i));
}
grid.setItems(rows);
}
}
カスタムのlistcell:
public class ArtistListCell<T extends ArrayList<Artist>> extends ListCell<T> {
private T item;
public ArtistListCell() {
this.getStyleClass().setAll("artist-list-cell");
}
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else if (!item.equals(this.item)) {
this.item = item;
HBox row = new HBox();
item.forEach(artist -> {
VBox cell = createCell(artist);
row.getChildren().add(cell);
});
setGraphic(row);
}
}
private VBox createCell(Artist artist) {
VBox cell = new VBox();
Label title = new Label(artist.getTitle());
ImageView image = new ImageView(artist.getArtistImage());
image.imageProperty().bind(artist.artistImageProperty());
VBox imageBox = new VBox();
title.setTextOverrun(OverrunStyle.CLIP);
title.setWrapText(true);
title.setPadding(new Insets(10, 0, 10, 0));
title.setAlignment(Pos.TOP_LEFT);
title.setPrefHeight(66);
title.prefWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
image.fitWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
image.fitHeightProperty().bind(this.widthProperty().subtract(102).divide(5));
image.setPreserveRatio(true);
image.setSmooth(true);
imageBox.prefWidthProperty().bind(this.widthProperty().subtract(102).divide(5));
imageBox.prefHeightProperty().bind(this.widthProperty().subtract(102).divide(5));
imageBox.setAlignment(Pos.CENTER);
imageBox.getChildren().add(image);
cell.getChildren().addAll(imageBox, title);
cell.setPadding(new Insets(10, 10, 0, 10));
cell.getStyleClass().add("artist-cell");
cell.setAlignment(Pos.CENTER);
cell.setOnMouseClicked(event -> {
// do something
});
cell.setOnDragDetected(event -> {
// do something
});
return cell;
}
}
イメージの大きさはどのくらいですか、どのようにイメージを読み込みますか? – fabian
これらは300x300ピクセルの.jpgで、それぞれ約20KBです。それらは次のようにロードされています:Image image = new Image( "file path goes here"); – naquilleosheal
それにもかかわらず、イメージを読み込むことに問題があります。シーンを表示する前に画像がロードされていることを確認してください。それらをマップに格納し、 'createCell'でそれらを取得し、これが動作を変更するかどうかをチェックします。 (私は 'createCell'でイメージを作成していると思います)。さらに、' createCell'メソッドが大きくない場合は、それを追加するか(問題を再現するための単純化されたバージョン)、質問? – fabian