javafx中的Scrollpane在显示大量项目和视图时会给RAM带来负担

javafx中的Scrollpane在显示大量项目和视图时会给RAM带来负担,java,listview,javafx,javafx-8,scrollview,Java,Listview,Javafx,Javafx 8,Scrollview,我正在使用javafx开发一个库应用程序,用户可以在其中导入epub文件,他得到一个带书架的库,每个书架最多包含6本书。我使用的是一个滚动窗格,里面有一个VBox,其中包含其他VBox(每个类似于一个书架),每个VBox包含一个图像(即书架),上面有一个HBox,其中包含书籍封面的图像。我尝试使用listview,但它不起作用,因为listview列出了您单击其中一本书的项目列表,在我的情况下,该项目将是包含多本书的整个书架(我希望单独处理单击每本书的操作)。对不起,描述得太长了。 这方面有很多

我正在使用javafx开发一个库应用程序,用户可以在其中导入epub文件,他得到一个带书架的库,每个书架最多包含6本书。我使用的是一个滚动窗格,里面有一个VBox,其中包含其他VBox(每个类似于一个书架),每个VBox包含一个图像(即书架),上面有一个HBox,其中包含书籍封面的图像。我尝试使用listview,但它不起作用,因为listview列出了您单击其中一本书的项目列表,在我的情况下,该项目将是包含多本书的整个书架(我希望单独处理单击每本书的操作)。对不起,描述得太长了。

这方面有很多选择;但最好的方法可能是按照评论的建议使用
列表视图

下面的示例应用程序将演示一种方法。然而,我还没有做过任何关于设置
列表视图样式的工作。主要是因为我自己对CSS不是很精通(我欢迎编辑和建议),但也因为这超出了这个相当模糊的问题的范围

列表视图
与自定义的
CellFactory
相结合,您可以为库中的每个“书架”构建布局;
列表视图将使用该布局显示每一行

下面的代码中还有其他注释

库示例MCVE:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.util.List;

public class LibraryExample extends Application {

    // Our list of shelves that will be displayed in the ListView
    private final ObservableList<Shelf> shelves = FXCollections.observableArrayList();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Build a list of 100 sample books. This list could come from a database or other outside source, of course
        List<Book> books = FXCollections.observableArrayList();
        for (int i = 0; i < 100; i++) {
            books.add(new Book("Book #" + i, new ImageView("sample/generic-cover.png")));
        }

        // We will now create our shelves for the books. We will limit the number of books to 6 per shelf. This uses
        // the subList method of our List to grab every 6 books until we run out.
        int index = 0;
        while (index < books.size()) {

            // Make sure there are at least 6 books remaining, otherwise, we need to get the subList up to the size of
            // the original list.
            final int numToAdd = (index + 6 <= books.size() ? index + 6 : books.size());
            shelves.addAll(new Shelf(books.subList(index, numToAdd)));
            index += 6;
        }

        // Now, let's create our ListView that will hold our shelves.
        ListView<Shelf> listView = new ListView<>();
        VBox.setVgrow(listView, Priority.ALWAYS);

        // Now for the magic. We will override the CellFactory for the ListView so we can provide our own layout
        // for each row
        listView.setCellFactory(new Callback<ListView<Shelf>, ListCell<Shelf>>() {
            @Override
            public ListCell<Shelf> call(ListView<Shelf> param) {
                return new ShelfListCell();
            }
        });

        listView.setItems(shelves);

        root.getChildren().add(listView);

        // Show the Stage
        primaryStage.setWidth(700);
        primaryStage.setHeight(600);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

class ShelfListCell extends ListCell<Shelf> {

    @Override
    protected void updateItem(Shelf shelf, boolean empty) {
        super.updateItem(shelf, empty);

        if (shelf == null || empty) {
            setGraphic(null);
        } else {

            // Here, we will build our layout for each shelf
            VBox root = new VBox(5);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(5));

            HBox hBox = new HBox(20);
            hBox.setAlignment(Pos.CENTER);
            hBox.setPadding(new Insets(5));

            // Add image for each each book on this shelf to the layout
            for (Book book : shelf.getBooks()) {

                // Get the image of the book and add a simple click listener
                ImageView cover = book.getCoverImage();
                cover.setPreserveRatio(true);
                cover.setFitHeight(100);
                cover.setOnMouseClicked(event -> System.out.println("Clicked " + book.getTitle()));

                hBox.getChildren().add(book.getCoverImage());
            }

            root.getChildren().addAll(hBox, new Separator(Orientation.HORIZONTAL));

            // Set the cell to display our layout
            setGraphic(root);

        }
    }
}
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.ImageView;

public class Book {

    private final StringProperty title = new SimpleStringProperty();
    private final ObjectProperty<ImageView> coverImage = new SimpleObjectProperty<>();

    public Book(String title, ImageView coverImage) {
        this.title.set(title);
        this.coverImage.set(coverImage);
    }

    public String getTitle() {
        return title.get();
    }

    public StringProperty titleProperty() {
        return title;
    }

    public void setTitle(String title) {
        this.title.set(title);
    }

    public ImageView getCoverImage() {
        return coverImage.get();
    }

    public ObjectProperty<ImageView> coverImageProperty() {
        return coverImage;
    }

    public void setCoverImage(ImageView coverImage) {
        this.coverImage.set(coverImage);
    }
}
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.List;

public class Shelf {

    // Set max number of books per shelf
    private final static int MAX_BOOKS = 6;

    // Our observable list of books
    private final ListProperty<Book> books = new SimpleListProperty<>(FXCollections.observableArrayList());

    public Shelf(List<Book> books) {
        this.books.addAll(books);
    }

    public void addBooks(Book... books) {
        this.books.addAll(books);
    }

    public static int getMaxBooks() {
        return MAX_BOOKS;
    }

    public ObservableList<Book> getBooks() {
        return books.get();
    }

    public ListProperty<Book> booksProperty() {
        return books;
    }

    public void setBooks(ObservableList<Book> books) {
        this.books.set(books);
    }
}
LibraryExample.java:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.util.List;

public class LibraryExample extends Application {

    // Our list of shelves that will be displayed in the ListView
    private final ObservableList<Shelf> shelves = FXCollections.observableArrayList();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Build a list of 100 sample books. This list could come from a database or other outside source, of course
        List<Book> books = FXCollections.observableArrayList();
        for (int i = 0; i < 100; i++) {
            books.add(new Book("Book #" + i, new ImageView("sample/generic-cover.png")));
        }

        // We will now create our shelves for the books. We will limit the number of books to 6 per shelf. This uses
        // the subList method of our List to grab every 6 books until we run out.
        int index = 0;
        while (index < books.size()) {

            // Make sure there are at least 6 books remaining, otherwise, we need to get the subList up to the size of
            // the original list.
            final int numToAdd = (index + 6 <= books.size() ? index + 6 : books.size());
            shelves.addAll(new Shelf(books.subList(index, numToAdd)));
            index += 6;
        }

        // Now, let's create our ListView that will hold our shelves.
        ListView<Shelf> listView = new ListView<>();
        VBox.setVgrow(listView, Priority.ALWAYS);

        // Now for the magic. We will override the CellFactory for the ListView so we can provide our own layout
        // for each row
        listView.setCellFactory(new Callback<ListView<Shelf>, ListCell<Shelf>>() {
            @Override
            public ListCell<Shelf> call(ListView<Shelf> param) {
                return new ShelfListCell();
            }
        });

        listView.setItems(shelves);

        root.getChildren().add(listView);

        // Show the Stage
        primaryStage.setWidth(700);
        primaryStage.setHeight(600);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

class ShelfListCell extends ListCell<Shelf> {

    @Override
    protected void updateItem(Shelf shelf, boolean empty) {
        super.updateItem(shelf, empty);

        if (shelf == null || empty) {
            setGraphic(null);
        } else {

            // Here, we will build our layout for each shelf
            VBox root = new VBox(5);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(5));

            HBox hBox = new HBox(20);
            hBox.setAlignment(Pos.CENTER);
            hBox.setPadding(new Insets(5));

            // Add image for each each book on this shelf to the layout
            for (Book book : shelf.getBooks()) {

                // Get the image of the book and add a simple click listener
                ImageView cover = book.getCoverImage();
                cover.setPreserveRatio(true);
                cover.setFitHeight(100);
                cover.setOnMouseClicked(event -> System.out.println("Clicked " + book.getTitle()));

                hBox.getChildren().add(book.getCoverImage());
            }

            root.getChildren().addAll(hBox, new Separator(Orientation.HORIZONTAL));

            // Set the cell to display our layout
            setGraphic(root);

        }
    }
}
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.ImageView;

public class Book {

    private final StringProperty title = new SimpleStringProperty();
    private final ObjectProperty<ImageView> coverImage = new SimpleObjectProperty<>();

    public Book(String title, ImageView coverImage) {
        this.title.set(title);
        this.coverImage.set(coverImage);
    }

    public String getTitle() {
        return title.get();
    }

    public StringProperty titleProperty() {
        return title;
    }

    public void setTitle(String title) {
        this.title.set(title);
    }

    public ImageView getCoverImage() {
        return coverImage.get();
    }

    public ObjectProperty<ImageView> coverImageProperty() {
        return coverImage;
    }

    public void setCoverImage(ImageView coverImage) {
        this.coverImage.set(coverImage);
    }
}
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.List;

public class Shelf {

    // Set max number of books per shelf
    private final static int MAX_BOOKS = 6;

    // Our observable list of books
    private final ListProperty<Book> books = new SimpleListProperty<>(FXCollections.observableArrayList());

    public Shelf(List<Book> books) {
        this.books.addAll(books);
    }

    public void addBooks(Book... books) {
        this.books.addAll(books);
    }

    public static int getMaxBooks() {
        return MAX_BOOKS;
    }

    public ObservableList<Book> getBooks() {
        return books.get();
    }

    public ListProperty<Book> booksProperty() {
        return books;
    }

    public void setBooks(ObservableList<Book> books) {
        this.books.set(books);
    }
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.geometry.Insets;
导入javafx.geometry.Orientation;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.control.Separator;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.util.Callback;
导入java.util.List;
公共类LibraryExample扩展了应用程序{
//我们将在ListView中显示的工具架列表
私有最终ObservableList shelfs=FXCollections.observableArrayList();
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
//简单接口
VBox根=新的VBox(5);
根。设置填充(新插图(10));
根部设置对齐(位置中心);
//建立一个100本样本书的列表。当然,这个列表可以来自数据库或其他外部来源
List books=FXCollections.observearraylist();
对于(int i=0;i<100;i++){
books.add(新书(“Book#”+i,新图像视图(“sample/generic cover.png”));
}
//现在,我们将为这些书创建书架。我们将每个书架的书数限制为6本。这将使用
//我们列表的子列表方法是每6本书抓取一次,直到用完为止。
int指数=0;
而(索引final int numToAdd=(index+6有很多选项;但最好的方法可能是使用
ListView
,正如注释所示

下面的示例应用程序将演示一种方法。但是,我没有做过任何有关设置<代码>列表视图
样式的工作。主要是因为我自己对CSS不是很精通(我欢迎编辑和建议),但也因为这超出了这个相当模糊的问题的范围

列表视图
与自定义的
CellFactory
相结合,您可以为库中的每个“工具架”构建布局;
列表视图
将使用该布局显示每一行

下面的代码中还有其他注释

库示例MCVE:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.util.List;

public class LibraryExample extends Application {

    // Our list of shelves that will be displayed in the ListView
    private final ObservableList<Shelf> shelves = FXCollections.observableArrayList();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Build a list of 100 sample books. This list could come from a database or other outside source, of course
        List<Book> books = FXCollections.observableArrayList();
        for (int i = 0; i < 100; i++) {
            books.add(new Book("Book #" + i, new ImageView("sample/generic-cover.png")));
        }

        // We will now create our shelves for the books. We will limit the number of books to 6 per shelf. This uses
        // the subList method of our List to grab every 6 books until we run out.
        int index = 0;
        while (index < books.size()) {

            // Make sure there are at least 6 books remaining, otherwise, we need to get the subList up to the size of
            // the original list.
            final int numToAdd = (index + 6 <= books.size() ? index + 6 : books.size());
            shelves.addAll(new Shelf(books.subList(index, numToAdd)));
            index += 6;
        }

        // Now, let's create our ListView that will hold our shelves.
        ListView<Shelf> listView = new ListView<>();
        VBox.setVgrow(listView, Priority.ALWAYS);

        // Now for the magic. We will override the CellFactory for the ListView so we can provide our own layout
        // for each row
        listView.setCellFactory(new Callback<ListView<Shelf>, ListCell<Shelf>>() {
            @Override
            public ListCell<Shelf> call(ListView<Shelf> param) {
                return new ShelfListCell();
            }
        });

        listView.setItems(shelves);

        root.getChildren().add(listView);

        // Show the Stage
        primaryStage.setWidth(700);
        primaryStage.setHeight(600);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

class ShelfListCell extends ListCell<Shelf> {

    @Override
    protected void updateItem(Shelf shelf, boolean empty) {
        super.updateItem(shelf, empty);

        if (shelf == null || empty) {
            setGraphic(null);
        } else {

            // Here, we will build our layout for each shelf
            VBox root = new VBox(5);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(5));

            HBox hBox = new HBox(20);
            hBox.setAlignment(Pos.CENTER);
            hBox.setPadding(new Insets(5));

            // Add image for each each book on this shelf to the layout
            for (Book book : shelf.getBooks()) {

                // Get the image of the book and add a simple click listener
                ImageView cover = book.getCoverImage();
                cover.setPreserveRatio(true);
                cover.setFitHeight(100);
                cover.setOnMouseClicked(event -> System.out.println("Clicked " + book.getTitle()));

                hBox.getChildren().add(book.getCoverImage());
            }

            root.getChildren().addAll(hBox, new Separator(Orientation.HORIZONTAL));

            // Set the cell to display our layout
            setGraphic(root);

        }
    }
}
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.ImageView;

public class Book {

    private final StringProperty title = new SimpleStringProperty();
    private final ObjectProperty<ImageView> coverImage = new SimpleObjectProperty<>();

    public Book(String title, ImageView coverImage) {
        this.title.set(title);
        this.coverImage.set(coverImage);
    }

    public String getTitle() {
        return title.get();
    }

    public StringProperty titleProperty() {
        return title;
    }

    public void setTitle(String title) {
        this.title.set(title);
    }

    public ImageView getCoverImage() {
        return coverImage.get();
    }

    public ObjectProperty<ImageView> coverImageProperty() {
        return coverImage;
    }

    public void setCoverImage(ImageView coverImage) {
        this.coverImage.set(coverImage);
    }
}
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.List;

public class Shelf {

    // Set max number of books per shelf
    private final static int MAX_BOOKS = 6;

    // Our observable list of books
    private final ListProperty<Book> books = new SimpleListProperty<>(FXCollections.observableArrayList());

    public Shelf(List<Book> books) {
        this.books.addAll(books);
    }

    public void addBooks(Book... books) {
        this.books.addAll(books);
    }

    public static int getMaxBooks() {
        return MAX_BOOKS;
    }

    public ObservableList<Book> getBooks() {
        return books.get();
    }

    public ListProperty<Book> booksProperty() {
        return books;
    }

    public void setBooks(ObservableList<Book> books) {
        this.books.set(books);
    }
}
LibraryExample.java:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Separator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

import java.util.List;

public class LibraryExample extends Application {

    // Our list of shelves that will be displayed in the ListView
    private final ObservableList<Shelf> shelves = FXCollections.observableArrayList();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Build a list of 100 sample books. This list could come from a database or other outside source, of course
        List<Book> books = FXCollections.observableArrayList();
        for (int i = 0; i < 100; i++) {
            books.add(new Book("Book #" + i, new ImageView("sample/generic-cover.png")));
        }

        // We will now create our shelves for the books. We will limit the number of books to 6 per shelf. This uses
        // the subList method of our List to grab every 6 books until we run out.
        int index = 0;
        while (index < books.size()) {

            // Make sure there are at least 6 books remaining, otherwise, we need to get the subList up to the size of
            // the original list.
            final int numToAdd = (index + 6 <= books.size() ? index + 6 : books.size());
            shelves.addAll(new Shelf(books.subList(index, numToAdd)));
            index += 6;
        }

        // Now, let's create our ListView that will hold our shelves.
        ListView<Shelf> listView = new ListView<>();
        VBox.setVgrow(listView, Priority.ALWAYS);

        // Now for the magic. We will override the CellFactory for the ListView so we can provide our own layout
        // for each row
        listView.setCellFactory(new Callback<ListView<Shelf>, ListCell<Shelf>>() {
            @Override
            public ListCell<Shelf> call(ListView<Shelf> param) {
                return new ShelfListCell();
            }
        });

        listView.setItems(shelves);

        root.getChildren().add(listView);

        // Show the Stage
        primaryStage.setWidth(700);
        primaryStage.setHeight(600);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}

class ShelfListCell extends ListCell<Shelf> {

    @Override
    protected void updateItem(Shelf shelf, boolean empty) {
        super.updateItem(shelf, empty);

        if (shelf == null || empty) {
            setGraphic(null);
        } else {

            // Here, we will build our layout for each shelf
            VBox root = new VBox(5);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(5));

            HBox hBox = new HBox(20);
            hBox.setAlignment(Pos.CENTER);
            hBox.setPadding(new Insets(5));

            // Add image for each each book on this shelf to the layout
            for (Book book : shelf.getBooks()) {

                // Get the image of the book and add a simple click listener
                ImageView cover = book.getCoverImage();
                cover.setPreserveRatio(true);
                cover.setFitHeight(100);
                cover.setOnMouseClicked(event -> System.out.println("Clicked " + book.getTitle()));

                hBox.getChildren().add(book.getCoverImage());
            }

            root.getChildren().addAll(hBox, new Separator(Orientation.HORIZONTAL));

            // Set the cell to display our layout
            setGraphic(root);

        }
    }
}
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.image.ImageView;

public class Book {

    private final StringProperty title = new SimpleStringProperty();
    private final ObjectProperty<ImageView> coverImage = new SimpleObjectProperty<>();

    public Book(String title, ImageView coverImage) {
        this.title.set(title);
        this.coverImage.set(coverImage);
    }

    public String getTitle() {
        return title.get();
    }

    public StringProperty titleProperty() {
        return title;
    }

    public void setTitle(String title) {
        this.title.set(title);
    }

    public ImageView getCoverImage() {
        return coverImage.get();
    }

    public ObjectProperty<ImageView> coverImageProperty() {
        return coverImage;
    }

    public void setCoverImage(ImageView coverImage) {
        this.coverImage.set(coverImage);
    }
}
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.List;

public class Shelf {

    // Set max number of books per shelf
    private final static int MAX_BOOKS = 6;

    // Our observable list of books
    private final ListProperty<Book> books = new SimpleListProperty<>(FXCollections.observableArrayList());

    public Shelf(List<Book> books) {
        this.books.addAll(books);
    }

    public void addBooks(Book... books) {
        this.books.addAll(books);
    }

    public static int getMaxBooks() {
        return MAX_BOOKS;
    }

    public ObservableList<Book> getBooks() {
        return books.get();
    }

    public ListProperty<Book> booksProperty() {
        return books;
    }

    public void setBooks(ObservableList<Book> books) {
        this.books.set(books);
    }
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.geometry.Insets;
导入javafx.geometry.Orientation;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.control.Separator;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
导入javafx.util.Callback;
导入java.util.List;
公共类LibraryExample扩展了应用程序{
//我们将在ListView中显示的工具架列表
私有最终ObservableList shelfs=FXCollections.observableArrayList();
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
//简单接口
VBox根=新的VBox(5);
根。设置填充(新插图(10));
根部设置对齐(位置中心);
//建立一个100本样本书的列表。当然,这个列表可以来自数据库或其他外部来源
List books=FXCollections.observearraylist();
对于(int i=0;i<100;i++){
books.add(新书(“Book#”+i,新图像视图(“sample/generic cover.png”));
}
//现在,我们将为这些书创建书架。我们将每个书架的书数限制为6本。这将使用
//我们列表的子列表方法是每6本书抓取一次,直到用完为止。
int指数=0;
而(索引