2

我有一个用于显示的简单Person对象列表TableView

class Person {

    private final StringProperty name = new SimpleStringProperty();
    private final StringProperty emailAddress = new SimpleStringProperty();
    private final StringProperty phoneNumber = new SimpleStringProperty();

    public Person(String name, String emailAddress, String phoneNumber) {

        this.name.set(name);
        this.emailAddress.set(emailAddress);
        this.phoneNumber.set(phoneNumber);

    }
}

我在此示例中的目标是同时显示emailAddress和。这不仅仅是在我为此列实现自定义时简单地连接值(实际应用程序更复杂):phoneNumberTableColumnTableCell

private TableCell<Person, Person> buildContactCell() {

    return new TableCell<Person, Person>() {

        final VBox root = new VBox();
        final Label lblEmailAddress = new Label();
        final Label lblPhoneNumber = new Label();

        {
            root.getChildren().addAll(lblEmailAddress, lblPhoneNumber);
        }

        @Override
        protected void updateItem(Person person, boolean empty) {

            super.updateItem(person, empty);
            if (person != null && !empty) {
                lblEmailAddress.setText(person.getEmailAddress());
                lblPhoneNumber.setText(person.getPhoneNumber());
                setGraphic(root);
            } else {
                setGraphic(null);
            }
        }
    };
}

我假设这工作正常,但我不确定如何配置CellValueFactoryTableColumn以接受整个Person对象。

是否有另一种方法可以设置TableCell能够访问多个属性Person?我在实现多个属性时看到的其他问题仅涉及连接,这不是我想要的。


完整代码:

import javafx.application.Application;
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.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TableCellSample extends Application {

    public static void main(String[] args) {

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

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

        root.getChildren().add(getTableView());

        // Show the stage
        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("Sample");
        primaryStage.show();
    }

    private TableView<Person> getTableView() {

        TableView<Person> tableView = new TableView<>();

        TableColumn<Person, String> colName = new TableColumn<>("Name");
        colName.setCellValueFactory(cellData -> cellData.getValue().nameProperty());

        TableColumn<Person, Person> colContact = new TableColumn<>("Contact");
        colContact.setCellFactory(cell -> buildContactCell());

        // **********************************************************************************************
        // Need to set the CellValueFactory for colContact here
        // **********************************************************************************************

        tableView.getColumns().addAll(colName, colContact);
        tableView.setItems(getSampleData());
        return tableView;

    }

    private TableCell<Person, Person> buildContactCell() {

        return new TableCell<Person, Person>() {

            final VBox root = new VBox();
            final Label lblEmailAddress = new Label();
            final Label lblPhoneNumber = new Label();

            {
                root.getChildren().addAll(lblEmailAddress, lblPhoneNumber);
            }

            @Override
            protected void updateItem(Person person, boolean empty) {

                super.updateItem(person, empty);
                if (person != null && !empty) {
                    lblEmailAddress.setText(person.getEmailAddress());
                    lblPhoneNumber.setText(person.getPhoneNumber());
                    setGraphic(root);
                } else {
                    setGraphic(null);
                }
            }
        };
    }

    private ObservableList<Person> getSampleData() {

        ObservableList<Person> persons = FXCollections.observableArrayList();
        persons.addAll(
                new Person("Jack", "jack@outlook.com", "123-456-7890"),
                new Person("Jenny", "goodtime@yahoo.com", "555-867-5309"),
                new Person("Jesse", "mygirl@hotmail.com", "846-989-9988"));
        return persons;
    }
}

class Person {

    private final StringProperty name = new SimpleStringProperty();
    private final StringProperty emailAddress = new SimpleStringProperty();
    private final StringProperty phoneNumber = new SimpleStringProperty();

    public Person(String name, String emailAddress, String phoneNumber) {

        this.name.set(name);
        this.emailAddress.set(emailAddress);
        this.phoneNumber.set(phoneNumber);

    }

    public String getName() {

        return name.get();
    }

    public StringProperty nameProperty() {

        return name;
    }

    public String getEmailAddress() {

        return emailAddress.get();
    }

    public StringProperty emailAddressProperty() {

        return emailAddress;
    }

    public String getPhoneNumber() {

        return phoneNumber.get();
    }

    public StringProperty phoneNumberProperty() {

        return phoneNumber;
    }
}
4

2 回答 2

4

您的单元格值工厂需要返回ObjectProperty<Person>包含该行的元素。cellData.getValue()您可以在单元格值工厂中使用获取行数据,其中cellData是传递给call()方法的参数。所以:

colContact.setCellValueFactory(cellData -> 
    new SimpleObjectProperty<>(cellData.getValue()));
于 2021-08-22T21:15:41.010 回答
0

Model 应该真正满足 View 的需求,让 TableCell 在幕后窥视以查看整个 TableModel 是一种代码味道。组织模型可能更好,这样数据可以直接用于 TableCell。尝试组合,如下所示:

public class TableCellSample extends Application {

    public static void main(String[] args) {

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

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

        root.getChildren().add(getTableView());

        // Show the stage
        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("Sample");
        primaryStage.show();
    }

    private TableView<Person> getTableView() {

        TableView<Person> tableView = new TableView<>();

        TableColumn<Person, String> colName = new TableColumn<>("Name");
        colName.setCellValueFactory(cellData -> cellData.getValue().nameProperty());

        TableColumn<Person, ContactInfo> colContact = new TableColumn<>("Contact");
        colContact.setCellFactory(cell -> buildContactCell());
        colContact.setCellValueFactory(cellData -> cellData.getValue().contactInfoProperty());

        // **********************************************************************************************
        // Need to set the CellValueFactory for colContact here
        // **********************************************************************************************

        tableView.getColumns().addAll(colName, colContact);
        tableView.setItems(getSampleData());
        return tableView;

    }

    private TableCell<Person, ContactInfo> buildContactCell() {

        return new TableCell<Person, ContactInfo>() {

            final VBox root = new VBox();
            final Label lblEmailAddress = new Label();
            final Label lblPhoneNumber = new Label();

            {
                root.getChildren().addAll(lblEmailAddress, lblPhoneNumber);
            }

            @Override
            protected void updateItem(ContactInfo contactInfo, boolean empty) {

                super.updateItem(contactInfo, empty);
                if (contactInfo != null && !empty) {
                    lblEmailAddress.setText(contactInfo.getEmailAddress());
                    lblPhoneNumber.setText(contactInfo.getPhoneNumber());
                    setGraphic(root);
                } else {
                    setGraphic(null);
                }
            }
        };
    }

    private ObservableList<Person> getSampleData() {

        ObservableList<Person> persons = FXCollections.observableArrayList();
        persons.addAll(
                new Person("Jack", "jack@outlook.com", "123-456-7890"),
                new Person("Jenny", "goodtime@yahoo.com", "555-867-5309"),
                new Person("Jesse", "mygirl@hotmail.com", "846-989-9988"));
        return persons;
    }
}

class Person {
    private final StringProperty name = new SimpleStringProperty();
    private final ObjectProperty<ContactInfo> contactInfoProperty = new SimpleObjectProperty<>();

    public Person(String name, String emailAddress, String phoneNumber) {
        this.name.set(name);
        contactInfoProperty.set(new ContactInfo(emailAddress, phoneNumber));
    }

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

    public StringProperty nameProperty() {
        return name;
    }

    public String getEmailAddress() {
        return contactInfoProperty.get().emailAddressProperty().get();
    }

    public StringProperty emailAddressProperty() {
        return contactInfoProperty.get().emailAddressProperty();
    }

    public String getPhoneNumber() {
        return contactInfoProperty.get().getPhoneNumber();
    }

    public StringProperty phoneNumberProperty() {
        return contactInfoProperty.get().phoneNumberProperty();
    }

    public ObjectProperty<ContactInfo> contactInfoProperty() {
        return contactInfoProperty;
    }
}

class ContactInfo {
    private final StringProperty emailAddress = new SimpleStringProperty();
    private final StringProperty phoneNumber = new SimpleStringProperty();

    public ContactInfo(String emailAddress, String phoneNumber) {
        this.emailAddress.set(emailAddress);
        this.phoneNumber.set(phoneNumber);
    }

    public String getEmailAddress() {
        return emailAddress.get();
    }

    public StringProperty emailAddressProperty() {
        return emailAddress;
    }

    public void setEmailAddress(String emailAddress) {
        this.emailAddress.set(emailAddress);
    }

    public String getPhoneNumber() {
        return phoneNumber.get();
    }

    public StringProperty phoneNumberProperty() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber.set(phoneNumber);
    }
}
于 2021-08-23T15:28:45.130 回答