【问题标题】:How to implement correct doubleclick-to-edit in TableView如何在 TableView 中实现正确的双击编辑
【发布时间】:2015-04-18 14:56:04
【问题描述】:

问题

一旦您单击已选择的单元格,TableView 似乎会进入编辑模式。这是不需要且不一致的行为,因为如果您在当前选择之外单击,则选择会发生变化。当您在当前选择内单击时,它不会改变。

如果有的话,应该需要真正的双击才能进入编辑模式,至少在您在桌面上工作时是这样。

复制:

使用这种选择模式创建一个 TableView:

// cell selection mode instead of row selection
table.getSelectionModel().setCellSelectionEnabled(true);

// allow selection of multiple cells
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

现在选择多个单元格(通过 shift 键)。然后单击当前选定单元格中的单个单元格。

当前行为:

  • 表格进入编辑模式

问题

请求的行为:

  • 只有选择应该改变,即。 e.应选择单个单元格;编辑模式只能在双击时发生

你如何做到这一点?

代码

这是一个完整的例子。我从 Oracle 示例网站获取代码,添加了上述行并预选了所有单元格。当您在程序启动后单击单个单元格时,表格将直接进入编辑模式:

public class TableViewSample extends Application {

    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data =
            FXCollections.observableArrayList(
            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"));
    final HBox hb = new HBox();

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(550);

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(
            new PropertyValueFactory<Person, String>("firstName"));
        firstNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
        firstNameCol.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>() {
                @Override
                public void handle(CellEditEvent<Person, String> t) {
                    ((Person) t.getTableView().getItems().get(
                            t.getTablePosition().getRow())
                            ).setFirstName(t.getNewValue());
                }
            }
        );


        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(
            new PropertyValueFactory<Person, String>("lastName"));
        lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
        lastNameCol.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>() {
                @Override
                public void handle(CellEditEvent<Person, String> t) {
                    ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())
                        ).setLastName(t.getNewValue());
                }
            }
        );

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(
            new PropertyValueFactory<Person, String>("email"));
        emailCol.setCellFactory(TextFieldTableCell.forTableColumn());
        emailCol.setOnEditCommit(
            new EventHandler<CellEditEvent<Person, String>>() {
                @Override
                public void handle(CellEditEvent<Person, String> t) {
                    ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())
                        ).setEmail(t.getNewValue());
                }
            }
        );

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        final TextField addFirstName = new TextField();
        addFirstName.setPromptText("First Name");
        addFirstName.setMaxWidth(firstNameCol.getPrefWidth());
        final TextField addLastName = new TextField();
        addLastName.setMaxWidth(lastNameCol.getPrefWidth());
        addLastName.setPromptText("Last Name");
        final TextField addEmail = new TextField();
        addEmail.setMaxWidth(emailCol.getPrefWidth());
        addEmail.setPromptText("Email");

        final Button addButton = new Button("Add");
        addButton.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent e) {
                data.add(new Person(
                        addFirstName.getText(),
                        addLastName.getText(),
                        addEmail.getText()));
                addFirstName.clear();
                addLastName.clear();
                addEmail.clear();
            }
        });

        hb.getChildren().addAll(addFirstName, addLastName, addEmail, addButton);
        hb.setSpacing(3);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table, hb);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();

        // cell selection mode instead of row selection
        table.getSelectionModel().setCellSelectionEnabled(true);

        // allow selection of multiple cells
        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

        // select all for demo purposes
        table.getSelectionModel().selectAll();
    }

    public static class Person {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;
        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }
}

【问题讨论】:

    标签: javafx tableview


    【解决方案1】:

    您可以尝试清除鼠标按下事件的选择:

    table.addEventFilter( MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>()
            {
                @Override
                public void handle( MouseEvent event )
                {
                    if( event.isControlDown()) {
                        return;
                    }
    
                    if ( table.getEditingCell() == null) {
                        table.getSelectionModel().clearSelection();
                    }
                }
            });
    

    【讨论】:

    • 谢谢你,成功了。我修改了你的代码来处理控制键。由于某种原因,当您按下控制键时,选择不再起作用。
    • @Roland,在Java8u40上,问题中的代码按下控制键没有问题。
    • 我在 Java8u40,Win7 上。您是否尝试在按下控制键的情况下选择多个单元格?对我来说,它总是只选择 1 个单元格而不是添加到选择中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2018-10-02
    • 2014-06-05
    • 1970-01-01
    相关资源
    最近更新 更多