JavaFX TableColumn:有没有办法生成列 header 事件?

JavaFX TableColumn: is there a way to generate a column header event?

我通过在整个 table 上设置一个比较器解决了我正在寻找的基本问题,但我最初试图做的是找到一种方法 "click" header 生成排序事件。

我仍然想知道如何做到这一点,因为我目前不知道有什么方法可以处理列的排序方法,只有 table 本身。

TableView 上调用 getSortOrder():returns 表示行排序顺序的 TableColumn 列表:

An empty sortOrder list means that no sorting is being applied on the TableView. If the sortOrder list has one TableColumn within it, the TableView will be sorted using the sortType and comparator properties of this TableColumn (assuming TableColumn.sortable is true). If the sortOrder list contains multiple TableColumn instances, then the TableView is firstly sorted based on the properties of the first TableColumn. If two elements are considered equal, then the second TableColumn in the list is used to determine ordering. This repeats until the results from all TableColumn comparators are considered, if necessary.

然后根据需要添加、删除、设置、清除等列表。

SSCCE:

import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableViewProgrammaticSort extends Application {

    @Override
    public void start(Stage primaryStage) {

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

        TableColumn<Person, String> firstNameCol = column("First Name", Person::firstNameProperty);
        TableColumn<Person, String> lastNameCol = column("Last Name", Person::lastNameProperty);
        TableColumn<Person, String> emailCol = column("Email", Person::emailProperty);

        table.getColumns().add(firstNameCol);
        table.getColumns().add(lastNameCol);
        table.getColumns().add(emailCol);

        table.getItems().addAll(
            new Person("Jacob", "Smith", "jacob.smith@example.com"),
            new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
            new Person("Ethan", "Williams", "ethan.williams@example.com"),
            new Person("Emma", "Jones", "emma.jones@example.com"),
            new Person("Michael", "Brown", "michael.brown@example.com")
        );

        ComboBox<TableColumn<Person, ?>> sortCombo = new ComboBox<>();
        sortCombo.getItems().add(firstNameCol);
        sortCombo.getItems().add(lastNameCol);
        sortCombo.getItems().add(emailCol);

        sortCombo.setCellFactory(lv -> new ColumnListCell());
        sortCombo.valueProperty().addListener((obs, oldColumn, newColumn) -> {
            table.getSortOrder().clear();
            if (newColumn != null) {
                table.getSortOrder().add(newColumn);
            }
        });
        sortCombo.setButtonCell(new ColumnListCell());

        BorderPane root = new BorderPane(table, sortCombo, null, null, null);
        BorderPane.setMargin(table, new Insets(10));
        BorderPane.setMargin(sortCombo, new Insets(10));
        BorderPane.setAlignment(sortCombo, Pos.CENTER);

        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static class ColumnListCell extends ListCell<TableColumn<Person, ?>> {
        @Override
        public void updateItem(TableColumn<Person, ?> column, boolean empty) {
            super.updateItem(column, empty);
            if (empty) {
                setText(null);
            } else {
                setText(column.getText());
            }
        }
    }

    private static <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> col = new TableColumn<>(title);
        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return col ;
    }

    public static class Person {
        private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
        private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
        private final StringProperty email = new SimpleStringProperty(this, "email");

        public Person(String firstName, String lastName, String email) {
            this.firstName.set(firstName);
            this.lastName.set(lastName);
            this.email.set(email);
        }

        public final StringProperty firstNameProperty() {
            return this.firstName;
        }

        public final java.lang.String getFirstName() {
            return this.firstNameProperty().get();
        }

        public final void setFirstName(final java.lang.String firstName) {
            this.firstNameProperty().set(firstName);
        }

        public final StringProperty lastNameProperty() {
            return this.lastName;
        }

        public final java.lang.String getLastName() {
            return this.lastNameProperty().get();
        }

        public final void setLastName(final java.lang.String lastName) {
            this.lastNameProperty().set(lastName);
        }

        public final StringProperty emailProperty() {
            return this.email;
        }

        public final java.lang.String getEmail() {
            return this.emailProperty().get();
        }

        public final void setEmail(final java.lang.String email) {
            this.emailProperty().set(email);
        }

    }

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