2016-07-24 14 views
0

Ich habe diese Musik spielende App, die Künstler und Alben in einem Gitter anzeigt. Ich habe dieses Raster mit einem ListView und benutzerdefinierten ListCells erstellt. Das ListView scheint jedoch nicht mehr als 2 Zellen zu rendern, wenn es initialisiert wird, obwohl seine Höhe groß genug ist, um 3 oder 4 Zeilen abhängig von der Größe Ihres Bildschirms zu rendern. Die ListView rendert jedoch die verbleibenden Zellen, wenn eine der ersten 2 Zellen über die Maus bewegt wird. Sehen Sie sich den folgenden Link an, um das Problem in Aktion zu sehen.JavaFX ListView rendert nicht genug Zellen, um sein Ansichtsfenster zu füllen

demo of the issue

Ich habe die Höhe des Listview überprüft und es expandiert in die Tat seiner Eltern zu füllen, so dass ich glaube, dass es etwas in der Art und Weise flippig los ist, dass der Listview entscheidet, welche Zellen gemacht werden müssen, . Ich hoffe, einen Weg zu finden, um ListView zu zwingen, die richtige Anzahl von Zellen zu rendern, wenn das das zugrunde liegende Problem ist, oder wenn es einen Fehler in meinem Code gibt, wäre es großartig, etwas Licht darüber zu haben. Ich habe den Code für meinen Controller und meine benutzerdefinierte ListCell unten veröffentlicht.

Controller, der das Listview initialisiert:

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); 
    } 
} 

Individuelles 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; 
    } 
} 
+0

Wie groß sind die Bilder und wie werden sie geladen? – fabian

+0

Sie sind 300x300 Pixel .jpg und sie sind etwa 20KB. Sie werden wie folgt geladen: Image image = new Image ("Dateipfad geht hier"); – naquilleosheal

+0

Könnte ein Problem mit dem Laden der Bilder trotzdem sein. Versichern Sie sich, dass die Bilder geladen sind, bevor Sie die Szene zeigen, z. indem Sie sie in einer Karte speichern und sie in 'createCell' laden und prüfen, ob sich dadurch das Verhalten ändert. (Ich nehme an, Sie erstellen die Bilder in 'createCell', indem Sie den Bildbaustein jetzt verwenden.) Wenn die' createCell'-Methode nicht zu groß ist, können Sie sie auch hinzufügen (oder eine vereinfachte Version, die das Reproduzieren des Problems ermöglicht) die Frage? – fabian

Antwort

0

ich für die Künstler zusammen einen Test und erleben dieses Problem mit einem einzigen statischen Bild. Wenn ich das Zeilengebäude in der ListCell durch ein einfaches Rechteck ersetzt habe, funktionierte es in Ordnung, also scheint der Engpass Ihre HBox/VBox-Zellen aufzubauen.

Verschieben des Aufrufs zu SetCellFactory nach Grid.setItems scheint es zu beheben.

grid.setItems(rows); 
grid.setCellFactory(x -> new ArtistListCell<>()); 

Ich würde sagen, es zu tun auf diese Weise für ein anderes Layout Pass ruft, während die andere Weise um sie nicht alle Informationen haben, es richtig berechnen muss?

Sie können unterschiedliche Ergebnisse mit Ihrem richtigen Bild laden, wenn es Zeit braucht. Wenn ja, vielleicht ein Platzhalterbild verwenden, wenn Sie es immer noch erleben?

+0

Das hat mein Problem nicht gelöst, aber ich habe das Problem auf die zwei Zeilen in createCell eingegrenzt, in denen die ImageViews fitWidthProperty und fitHeightProperty gebunden sind. Das Ersetzen dieser beiden durch eine setFitWidth oder setFitHeight scheint zu bewirken, dass die Listview mehr Zellen lädt. Aber diese Bindungen wurden hinzugefügt, so dass das Gitter in der Lage sein könnte, die Größe zu ändern – naquilleosheal

+0

Vielleicht versuchen, die Größe der HBox an die Größe der ArtistListCell, dann die VBox-Zelle an die Größe der HBox, die eine Kaskade von Größenaktualisierungen verursachen könnte? Es scheint so zu sein, dass man irgendwo in der Kette überspringt, damit die Werte in den Bindungen nicht aktualisiert werden. – Geoff