【问题标题】:JavaFX 11 TableView Cell navigation by TAB key pressed without custom editableCell class按下 TAB 键的 JavaFX 11 TableView 单元格导航没有自定义 editableCell 类
【发布时间】:2019-08-12 11:45:09
【问题描述】:

问题:

我想使用 TAB 键在 JavaFX 中从一个单元格导航到下一个右侧相邻单元格的 TableView。

注意:TableView 设置为可编辑。并且 CellSelection 也已启用。

 tableReceipt.getSelectionModel().setCellSelectionEnabled(true);

KeyPressedEvent的处理貌似不是我的问题,而是请求当前单元格右侧的单个单元格的焦点。

我可以聚焦一个单元格,但是当我按下 TAB 键时,焦点会从表格中移到其他表单元素上。

TableView 包含一些可编辑的 TextFieldTableCell 和一个可编辑的 ComboBoxTableCell。

我没有为可编辑单元格使用自定义类,而是这样的代码:

Callback<TableColumn<Receipt, int>, TableCell<Receipt, int>> tfCallBack = TextFieldTableCell.forTableColumn();
columnAmount.setCellFactory(tfCallBack);

对于具有可编辑 TextField 特性的 TableCell。

我的问题:

如何实施解决方案来解决我的问题?理论上的解决方案也会有所帮助。我已经搜索过这个主题,但只找到了一个使用自定义 EditableCell 类的示例。我想一定有像我这样使用回调方法的解决方案。

解决方法:

tableReceipt.setOnKeyPressed(new EventHandler<KeyEvent>() {
    @Override
    public void handle(KeyEvent t) {
        if (t.getCode() == KeyCode.TAB) {
            tableReceipt.getFocusModel().focusRightCell();
            Robot r = new Robot();
            r.keyPress(KeyCode.ENTER);
         }
     }
});

使用此代码,我可以获得当前单元格旁边的右侧单元格的焦点。我需要 ENTER KeyPress 来启用单元格的可编辑模式。但是当我在键盘上按 TAB 时,不会提交新值。例如,我按“2”默认值为“0”,按 TAB 后该值再次为“0”。

问题 2:

如何将上面的代码与 changeListener/onEditCommitListener 结合起来,以便在按 TAB 后将新值存储在单元格中?

谢谢。

【问题讨论】:

  • 你考虑过使用SpreadsheetView吗?
  • 我会看看那个。感谢您的及时回复。
  • 仍然不完全了解您的需求...您能否提供minimal reproducible example 来证明您的要求?
  • SpreadsheetView 似乎对解决这个问题很有用,但我使用的是 Java 12,而 ControlsFX 库目前只支持 Java 直到版本 9。
  • 好的,在 ControlsFX 可用的 maven 存储库中还有一个适用于 Java 11 的 RC2,如果 Java 版本 12 和 ControlsFX 存在问题,我可能会将我的应用程序回滚到 Java 11,但我认为它也应该可以工作.我只是在尝试。

标签: javafx tabs navigation tableview focus


【解决方案1】:

这可能会有所帮助。完成单元格编辑后,您必须手动调用它。

import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

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

/**
 * Created by Brian Boutin on 5/14/2019
 */

class CellNav<T> {

    private final TableView<T> tableView;
    private KeyEvent lastKeyEvent;
    private TablePosition editingPosition;

    CellNav(TableView<T> tableView) {
        this.tableView = tableView;
        this.editingPosition = null;

        tableView.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.TAB || event.getCode() == KeyCode.ENTER) {
                editingPosition = tableView.getEditingCell();
                lastKeyEvent = event;
            }
        });

        tableView.setOnMouseReleased(e -> editingPosition = null);

        for (TableColumn col : tableView.getColumns()) {
            col.setOnEditCancel(event -> editingPosition = null);
        }
    }

    void doCellNav() {
        if (editingPosition == null) {
            return;
        }

        if (lastKeyEvent.getCode() == KeyCode.ENTER) {

            int selectIdx;
            if (lastKeyEvent.isShiftDown()) {
                selectIdx = editingPosition.getRow() - 1;
            } else {
                selectIdx = editingPosition.getRow() + 1;
            }

            if (selectIdx < 0 ) {
                selectIdx = tableView.getItems().size() - 1;

            } else if (selectIdx > tableView.getItems().size() - 1) {
                selectIdx = 0;
            }

            tableView.layout();
            tableView.scrollTo(selectIdx == 0 ? selectIdx : selectIdx - 1);
            tableView.getSelectionModel().clearAndSelect(selectIdx);
            tableView.edit(selectIdx, editingPosition.getTableColumn());

        } else if (lastKeyEvent.getCode() == KeyCode.TAB) {
            TableColumn colToEdit = getNextColumn(!lastKeyEvent.isShiftDown(), editingPosition.getTableColumn());
            if (colToEdit != null) {
                tableView.layout();
                tableView.scrollToColumn(colToEdit);
                tableView.edit(editingPosition.getRow(), colToEdit);
            }
        }

        editingPosition = null;
    }

    boolean isNavigating() {
        return editingPosition != null;
    }

    private TableColumn getNextColumn(boolean forward, TableColumn currentCol) {
        List<TableColumn> columns = new ArrayList<>();
        for (TableColumn col : tableView.getColumns()) {
            if (col.isEditable() && col.isVisible() && (col.getStyleClass().contains("editable-col") || col.getStyleClass().contains("result-col"))) {
                columns.add(col);
            }
        }

        if (columns.size() < 2) {
            return null;
        }

        int currentIndex = -1;
        for (int i = 0; i < columns.size(); i++) {
            if (columns.get(i) == currentCol) {
                currentIndex = i;
                break;
            }
        }
        int nextIndex = currentIndex;
        if (forward) {
            nextIndex++;
            if (nextIndex > columns.size() - 1) {
                nextIndex = 0;
            }
        } else {
            nextIndex--;
            if (nextIndex < 0) {
                nextIndex = columns.size() - 1;
            }
        }
        return columns.get(nextIndex);
    }
}


public class ExampleClass{
  CellNav cellNav;
  
  public ExampleClass() {
    TableView  yourTableView = new TableView();
    cellNav = new CellNav(yourTableView);

    TableColumn someCol = new TableColumn();
    someCol.setOnEditCommit(e -> {

     //perform a save of your table data here

       //pick up cell nav again
      if (cellNav.isNavigating()) {
        cellNav.doCellNav();
      }
    });
  }
}

【讨论】:

    猜你喜欢
    • 2017-11-18
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 2011-06-05
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多