[英]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.