如何更改 TableView 的选择行为?

How to change selection behavior of TableView?

我已经为我的 TableView 设置了多个 selection 模式,我希望多行 select 使用 Lclick,而不是 Ctrl + Lclick。有没有简单的方法可以做到这一点。

我尝试 table.setOnMouseClicked() 使用空实现,但它不会阻止目标行被 selected 和之前 selected 的行被取消 selected, setOnMousePressed()setOnMouseReleased().

我真的不想重新实现TableView.TableViewSelectionModel。点击和调用之间应该有一层 TableView.TableViewSelectionModel.clearAndSelect()

更新 我刚刚发现 few questions 有类似的问题,但不完全相同。那些家伙想拖 select 多个,而我想 select 一个接一个,但没有键盘。

一般来说,更改 JavaFX UI 控件的行为很困难(或不可能),通常我建议只接受默认行为(即使它们不是您的用户真正想要的) .

在这种情况下,我认为您可以通过向 table 行添加事件过滤器、实现所需的选择行为并使用事件(以防止调用默认行为)来完成这项工作。

这是一个例子:

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.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class MultipleSelectTable extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Person> table = new TableView<>();

        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        table.setRowFactory(tv -> {
            TableRow<Person> row = new TableRow<>();
            row.addEventFilter(MouseEvent.MOUSE_PRESSED, e-> {
                if (! row.isEmpty() && e.getClickCount() == 1) {
                    Person person = row.getItem() ;
                    if (table.getSelectionModel().getSelectedItems().contains(person)) {
                        int index = row.getIndex() ;
                        table.getSelectionModel().clearSelection(index);
                    } else {
                        table.getSelectionModel().select(person);
                    }
                    e.consume();
                }
            });
            return row ;
        });

        table.getColumns().add(column("First Name", Person::firstNameProperty));
        table.getColumns().add(column("Last Name", Person::lastNameProperty));
        table.getColumns().add(column("Email", Person::emailProperty));

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

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

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

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

        public Person(String firstName, String lastName, String email) {
            setFirstName(firstName);
            setLastName(lastName);
            setEmail(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);
    }
}