通过TAB键的JavaFX 11 TableView Cell导航无需自定义editableCell类即可 [英] JavaFX 11 TableView Cell navigation by TAB key pressed without custom editableCell class
问题描述
问题:
我想使用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屋!