我有一个侦听键盘事件的事件监听器。当我尝试使用键事件进入编辑模式时,由于某些奇怪的原因,不正确的单元格进入编辑模式。
例如,我想编辑一个单元格。我使用键盘箭头转到我想要编辑的单元格,即聚焦的单元格。通过单击键盘上的字母,焦点单元格应进入编辑模式。当我尝试编辑聚焦单元格时,错误的单元格进入编辑模式。
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与当前的单元格索引不同。我不确定为什么索引不同。
答案 0 :(得分:6)
您的代码存在的问题是每个单元格在创建时都在调用table.setOnKeyPressed(...)
。这与任何其他set
方法一样,因此表上的keyPressed
处理程序只设置为创建的最后一个EditCell
。你无法控制细胞的实际创建,这不一定(并且不太可能)成为碰巧聚焦的细胞。
TableView
有足够的API供您直接从表中管理。特别是
table.getFocusModel().getFocusedCell()
将为您提供代表当前焦点单元格的TablePosition
。从那里你可以检索相应的行索引和TableColumn
。然后你只需要调用table.edit(int row, TableColumn<...> column);
来指示相应的单元格进入编辑模式。
这是一个完整的例子。我没有做太多努力来编辑&#34;漂亮&#34;在文本字段中选择文本等方面,您可能希望以某种方式实现编辑取消,但这应该让您开始。
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);
}
}