Связывание свойств JavaFx с несколькими объектами на экране - PullRequest
0 голосов
/ 14 декабря 2018

Я использую JavaFx со связыванием свойств.Я получил объект «Персона» со свойствами «имя» и возраст.Эти объекты хранятся в ObservableList.

Свойства привязаны к меткам в графическом интерфейсе.Когда я меняю человека в ListBox, данные также меняются с правой стороны.

GUI со списком людей: GUI with person list

И теперь это касается моей проблемы.Я хочу отобразить всех людей в одном окне, как показано на следующем рисунке.

Графический интерфейс с несколькими людьми в одном представлении: GUI with multiple persons on one view

Как я могу справиться с этим.Я думал о HBox, но привязка не работает.

К вашему сведению: здесь вы можете найти учебник, который я использовал.https://code.makery.ch/library/javafx-tutorial/part1/

1 Ответ

0 голосов
/ 14 декабря 2018

Это выглядит как идеальное время для использования ListView с пользовательскими ListCell реализациями.

В приведенном ниже примере приложения показано очень простое приложение, которое отображает каждый Person объект в ListView.Мы предоставим свои ListCell, чтобы мы могли точно контролировать отображение каждого Person.

Я также добавил фотографию профиля просто для удовольствия:)


import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
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.Label;
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.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewDetailSample extends Application {

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

        // First, let's create our list of Persons
        ObservableList<Person> persons = FXCollections.observableArrayList();
        persons.addAll(
                new Person("John", 34),
                new Person("Cheyenne", 24),
                new Person("Micah", 17),
                new Person("Katelyn", 28)
        );

        // Create a ListView
        ListView<Person> listView = new ListView<>();

        // Bind our list to the ListView
        listView.setItems(persons);

        // Now, for the magic. We'll create our own ListCells for the ListView. This allows us to create a custom
        // layout for each individual cell. For this sample, we'll include a profile picture, the name, and the age.
        listView.setCellFactory(new Callback<ListView<Person>, ListCell<Person>>() {
            @Override
            public ListCell<Person> call(ListView<Person> param) {
                return new ListCell<Person>() {
                    @Override
                    protected void updateItem(Person person, boolean empty) {
                        super.updateItem(person, empty);

                        // Set any empty cells to show nothing
                        if (person == null || empty) {
                            setText(null);
                            setGraphic(null);
                        } else {
                            // Here we can build our layout. We'll use a HBox for our root container
                            HBox cellRoot = new HBox(5);
                            cellRoot.setAlignment(Pos.CENTER_LEFT);
                            cellRoot.setPadding(new Insets(5));

                            // Add our profile picture
                            ImageView imgProfilePic = new ImageView("/sample/user.png");
                            imgProfilePic.setFitHeight(24);
                            imgProfilePic.setFitWidth(24);
                            cellRoot.getChildren().add(imgProfilePic);

                            // A simple Separator between the photo and the details
                            cellRoot.getChildren().add(new Separator(Orientation.VERTICAL));

                            // Now, create a VBox to hold the name and age
                            VBox vBox = new VBox(5);
                            vBox.setAlignment(Pos.CENTER_LEFT);
                            vBox.setPadding(new Insets(5));

                            // Add our Person details
                            vBox.getChildren().addAll(
                                    new Label("Name: " + person.getName()),
                                    new Label("Age: " + person.getAge())
                            );

                            // Add our VBox to the cellRoot
                            cellRoot.getChildren().add(vBox);

                            // Finally, set this cell to display our custom layout
                            setGraphic(cellRoot);
                        }
                    }
                };
            }
        });

        // Now, add our ListView to the root layout
        root.getChildren().add(listView);

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

// Simple Person class
class Person {

    private final StringProperty name = new SimpleStringProperty();
    private final IntegerProperty age = new SimpleIntegerProperty();

    public Person(String name, int age) {
        this.name.set(name);
        this.age.set(age);
    }

    public String getName() {
        return name.get();
    }

    public StringProperty nameProperty() {
        return name;
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public int getAge() {
        return age.get();
    }

    public IntegerProperty ageProperty() {
        return age;
    }

    public void setAge(int age) {
        this.age.set(age);
    }
}

Результат:

screenshot


Без ListView:

Если вы не хотите использовать ListView для этого дисплея, вы можете сохранить другой список ваших Person дисплеев и привязать его к списку детейкакой контейнер вы хотите:

    // Create a list to hold our individual Person displays
    ObservableList<Node> personDisplays = FXCollections.observableArrayList();

    // Now add a new PersonDisplay to the list for each Person in the personsList
    persons.forEach(person -> personDisplays.add(new PersonDisplay(person)));

    // Bind our personsDisplay list to the children of our root VBox
    Bindings.bindContent(root.getChildren(), personDisplays);

Класс PersonDisplay:

class PersonDisplay extends HBox {

    public PersonDisplay(Person person) {
        // First, let's configure our root layout
        setSpacing(5);
        setAlignment(Pos.CENTER_LEFT);
        setPadding(new Insets(5));

        // Add our profile picture
        ImageView imgProfilePic = new ImageView("/user.png");
        imgProfilePic.setFitHeight(24);
        imgProfilePic.setFitWidth(24);
        getChildren().add(imgProfilePic);

        // A simple Separator between the photo and the details
        getChildren().add(new Separator(Orientation.VERTICAL));

        // Now, create a VBox to hold the name and age
        VBox vBox = new VBox(5);
        vBox.setAlignment(Pos.CENTER_LEFT);
        vBox.setPadding(new Insets(5));

        // Add our Person details
        vBox.getChildren().addAll(
                new Label("Name: " + person.getName()),
                new Label("Age: " + person.getAge())
        );

        // Add our VBox to the layout
        getChildren().add(vBox);
    }
}

Результат:

screenshot 2

...