通过TAB键的JavaFX 11 TableView Cell导航无需自定义editableCell类即可 [英] JavaFX 11 TableView Cell navigation by TAB key pressed without custom editableCell class

查看:83
本文介绍了通过TAB键的JavaFX 11 TableView Cell导航无需自定义editableCell类即可的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:

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

I want to navigate through a TableView from one cell to the next right neighbor cell in JavaFX by using the TAB key.

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

Notice: The TableView is set to editable. And CellSelection is enabled too.

 tableReceipt.getSelectionModel().setCellSelectionEnabled(true);

处理KeyPressedEvent似乎不是我的问题,而是要求将单个单元格的焦点放在当前单元格的右侧.

The handling of the KeyPressedEvent seemingly is not my problem, but to request the focus of the single cell on the right of the current cell.

我可以集中一个单元格,但是当我按下TAB键时,焦点将移到表格以外的其他表单元素上.

I can focus one cell but when i press the TAB key the focus goes out of the table on other form elements.

TableView包含一些可编辑的TextFieldTableCells和一个可编辑的ComboBoxTableCell.

The TableView contains some editable TextFieldTableCells and one editable ComboBoxTableCell.

对于可编辑的单元格,我不使用自定义类,而是这样的代码:

I don't use a custom class for the editable Cells but Code like this:

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

对于具有可编辑TextField性质的TableCell.

for a TableCell with editable TextField nature.

我的问题:

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

How can I implement a solution to solve my problem? A theoretical solution would help too. I allready searched for this topic but only found an example that's using a custom EditableCell class. I think there must be a solution using the callback method like I do.

解决方法:

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".

With this code I can get focus of the right cell next to the current one. And I need the ENTER KeyPress to enable the editable mode of the Cell. But when I press TAB on keyboard the new value is not committed. For example I press '2' the default value is '0' and after pressing TAB the value is again '0'.

第2个问题:

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

How can I combine the code above with a changeListener/onEditCommitListener, that the new value is stored in the cell after pressing TAB?

谢谢.

推荐答案

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

This may be helpful. You have to manually call it after you complete a cell edit.

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 SomeClass {
  CellNav cellNav;

  public SomeClass () {
    TableView  yourTableView = new TableView();
    cellNav = new CellNav(yourTableView);

    TableColumn someCol = new TableColumn();
    someCol.setOnEditCommit(e -> {
     //commit the edit  
      if (cellNav.isNavigating()) {
        cellNav.doCellNav();
      }
    });
  }
}

这篇关于通过TAB键的JavaFX 11 TableView Cell导航无需自定义editableCell类即可的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆