繁体   English   中英

TableView-编辑焦点单元格

[英]TableView - Edit focused cell

我有一个事件监听器,用于监听键盘事件。 当我尝试通过按键事件进入编辑模式时,由于某种奇怪的原因,一个不正确的单元格进入了编辑模式。

例如,我要编辑一个单元格。 我使用键盘箭头转到要编辑的单元格,即焦点所在的单元格。 通过单击键盘上的字母,聚焦的单元格应进入编辑模式。 当我尝试编辑聚焦的单元格时,错误的单元格进入编辑模式。

private final class EditCell extends TableCell<SimpleStringProperty, String> implements GenericTable
{

    public EditCell()
    {
        // Add event listsner. table is a TableView
        table.setOnKeyPressed(keyEvent -> this.handleKeyPressed(keyEvent));
    }

    public void handleKeyPressed(KeyEvent key)
    {
        // Keyboard events
        if (key.getCode().isLetterKey())
        {
            if (!this.isEditing())
            {

                this.edit = true;

                // focus index
                int focusIndex = this.table.getSelectionModel().getFocusedIndex();

                this.changeTableCellFocus(this.table, focusIndex);

                this.startEdit();
            }
        }
    }


    // startEdit() function
    @Override
    public void startEdit()
    {
        if (this.edit)
        {
            LOGGER.info("Start editing on cell index: " + this.getIndex());
            super.startEdit();
            this.createTextField();
            this.setText(null);
            this.setGraphic(this.textField);
            this.textField.selectAll();
            this.textField.requestFocus();

            this.textField.setOnKeyPressed(keyEvent -> this.handleKeyPressed(keyEvent));

            this.textField.focusedProperty()
                    .addListener((observable, oldValue, newValue) -> this.onTextFieldFocusChange(observable,
                            oldValue,
                            newValue));
        }
    }

    // Change focus
    public void changeTableCellFocus(final TableView<?> table, final int focusIndex)
    {
        table.requestFocus();
        table.getSelectionModel().clearAndSelect(focusIndex);
        table.getFocusModel().focus(focusIndex);
    }
}

在进入编辑模式之前,我将焦点更改为单击的单元格,然后调用startEdit()方法。 我试图调试问题,但是没有运气。 我注意到,focusIndex与当前的单元格索引不同。 我不确定为什么索引不同。

您的代码的问题在于,每个单元在创建时都在调用table.setOnKeyPressed(...) 这与任何其他set方法一样工作,因此表上的keyPressed处理程序仅设置为上一次创建的EditCell那个。 您无法控制单元的实际创建,并且不一定(也不太可能)是碰巧要聚焦的单元。

TableView具有足够的API,使您能够直接从表中进行管理。 尤其是

table.getFocusModel().getFocusedCell()

将为您提供一个TablePosition表示当前关注的单元格。 从中可以检索相应的行索引和TableColumn 然后,您只需要调用table.edit(int row, TableColumn<...> column); 指示相应的单元格进入编辑模式。

这是一个完整的例子。 在选择文本字段中的文本等方面,我并没有付出太多的努力来使编辑“漂亮”,并且您可能希望以某种方式实现编辑取消,但这应该可以帮助您开始。

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableViewEditOnType extends Application {


    @Override
    public void start(Stage primaryStage) {
        TableView<List<StringProperty>> table = new TableView<>();
        table.getSelectionModel().setCellSelectionEnabled(true);
        table.setEditable(true);

        for (int i = 0; i < 10; i++) {
            table.getColumns().add(createColumn(i));

            List<StringProperty> rowData = new ArrayList<>();
            table.getItems().add(rowData);
            for (int j = 0; j < 10 ; j++) {
                rowData.add(new SimpleStringProperty(String.format("Cell [%d, %d]", i, j)));
            }
        }

        table.setOnKeyTyped(event -> {
            TablePosition<List<StringProperty>, String> focusedCell = table.getFocusModel().getFocusedCell();
            if (focusedCell != null) {
                table.getItems().get(focusedCell.getRow()).get(focusedCell.getColumn()).set(event.getCharacter());
                table.edit(focusedCell.getRow(), focusedCell.getTableColumn());
            }
        });

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

    private TableColumn<List<StringProperty>, String> createColumn(int colIndex) {
        TableColumn<List<StringProperty>, String> col = new TableColumn<>("Column "+colIndex);
        col.setCellValueFactory(cellData -> cellData.getValue().get(colIndex));
        col.setCellFactory(column -> new EditCell());
        return col ;
    }

    private static class EditCell extends TableCell<List<StringProperty>, String> {

        private final TextField textField = new TextField();

        EditCell() {   
            textProperty().bind(itemProperty());
            setGraphic(textField);
            setContentDisplay(ContentDisplay.TEXT_ONLY);

            textField.setOnAction(evt -> commitEdit(textField.getText()));
            textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
                if (! isNowFocused) {
                    commitEdit(textField.getText());
                }
            });
        }

        @Override
        public void startEdit() {
            super.startEdit();
            textField.setText(getItem());
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            textField.requestFocus();          
        }

        @Override
        public void cancelEdit() {
            super.cancelEdit();
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

        @Override
        public void commitEdit(String text) {
            super.commitEdit(text);
            setContentDisplay(ContentDisplay.TEXT_ONLY);
        }

    }

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM