【问题标题】:How to change selection behavior of TableView?如何更改 TableView 的选择行为?
【发布时间】:2016-01-11 12:58:02
【问题描述】:

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

我尝试使用 null 实现 table.setOnMouseClicked(),但它不会阻止选择目标行和取消选择先前选择的行,setOnMousePressed()setOnMouseReleased()

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

UPD 我刚刚发现一个few questions 有类似的问题,但不完全相同。当我想一个一个地选择时,那些家伙想拖动并选择多个,但没有键盘。

【问题讨论】:

    标签: javafx tableview selection


    【解决方案1】:

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

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

    这是一个例子:

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

    【讨论】:

    • 天哪,为什么我总是在自己找到答案后 2 分钟后得到答案??
    • stackoverflow.com/questions/23622703/… - 这是帮助我的问题
    • 要禁用对按键向下/向上事件的更改选择,请使用带有 KeyEvent.KEY_PRESSED 的 addEventFilter 来处理该事件。要保持焦点行为,请在 addEventFilter 行中添加 tv.requestFocus
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    相关资源
    最近更新 更多