我想切换到我的TableView只要我输入编辑模式。我不想双击或按第一个单元格输入,这很烦人。
我想出了下面这段代码。问题在于它是或多或少的副作用编程,我怀疑是麻烦。当您使用KEY_RELEASED将表切换到编辑模式时,第一次按键会丢失。
所以你必须使用KEY_PRESSED。这一切现在似乎都运行良好,但偶尔会遇到竞争条件,并且TextField单元格编辑器中的插入符号位于输入文本之前而不是之后。但是当你继续打字时,文字会在现有文字后正确地追加。
看起来没问题,但从发展的角度来看,它似乎像一个混乱的竞争条件。
问题
没有人有做一个“类型,以编辑”功能的有道?
代码
这里是到目前为止,我已经得到了代码:
public class InlineEditingTableView extends Application {
private final ObservableList<Data> data =
FXCollections.observableArrayList(
new Data(1.,5.),
new Data(2.,6.),
new Data(3.,7.),
new Data(4.,8.)
);
private TableView<Data> table;
@Override
public void start(Stage stage) {
// create edtiable table
table = new TableView<Data>();
table.setEditable(true);
// column 1 contains numbers
TableColumn<Data, Number> number1Col = new TableColumn<>("Number 1");
number1Col.setMinWidth(100);
number1Col.setCellValueFactory(cellData -> cellData.getValue().number1Property());
number1Col.setCellFactory(createNumberCellFactory());
number1Col.setOnEditCommit(new EventHandler<CellEditEvent<Data, Number>>() {
@Override
public void handle(CellEditEvent<Data, Number> t) {
System.out.println(t);
// ((Person) t.getTableView().getItems().get(t.getTablePosition().getRow())).setFirstName(t.getNewValue());
}
});
// column 2 contains numbers
TableColumn<Data, Number> number2Col = new TableColumn<>("Number 2");
number2Col.setMinWidth(100);
number2Col.setCellValueFactory(cellData -> cellData.getValue().number2Property());
number2Col.setCellFactory(createNumberCellFactory());
// add columns & data to table
table.setItems(data);
table.getColumns().addAll(number1Col, number2Col);
// switch to edit mode on keypress
// this must be KeyEvent.KEY_PRESSED so that the key gets forwarded to the editing cell; it wouldn't be forwarded on KEY_RELEASED
table.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER) {
// event.consume(); // don't consume the event or else the values won't be updated;
return;
}
// switch to edit mode on keypress, but only if we aren't already in edit mode
if(table.getEditingCell() == null) {
if(event.getCode().isLetterKey() || event.getCode().isDigitKey()) {
TablePosition focusedCellPosition = table.getFocusModel().getFocusedCell();
table.edit(focusedCellPosition.getRow(), focusedCellPosition.getTableColumn());
}
}
}
});
table.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.ENTER) {
table.getSelectionModel().selectBelowCell();
}
}
});
// single cell selection mode
table.getSelectionModel().setCellSelectionEnabled(true);
table.getSelectionModel().selectFirst();
// add nodes to stage
BorderPane root = new BorderPane();
root.setCenter(table);
Scene scene = new Scene(root, 800,600);
stage.setScene(scene);
stage.show();
}
/**
* Number cell factory which converts strings to numbers and vice versa.
* @return
*/
private Callback<TableColumn<Data, Number>, TableCell<Data, Number>> createNumberCellFactory() {
Callback<TableColumn<Data, Number>, TableCell<Data, Number>> factory = TextFieldTableCell.forTableColumn(new StringConverter<Number>() {
@Override
public Number fromString(String string) {
return Double.parseDouble(string);
}
@Override
public String toString(Number object) {
return object.toString();
}
});
return factory;
}
/**
* Table data container
*/
public static class Data {
private final SimpleDoubleProperty number1;
private final SimpleDoubleProperty number2;
private Data(Double number1, Double number2) {
this.number1 = new SimpleDoubleProperty(number1);
this.number2 = new SimpleDoubleProperty(number2);
}
public final DoubleProperty number1Property() {
return this.number1;
}
public final double getNumber1() {
return this.number1Property().get();
}
public final void setNumber1(final double number1) {
this.number1Property().set(number1);
}
public final DoubleProperty number2Property() {
return this.number2;
}
public final double getNumber2() {
return this.number2Property().get();
}
public final void setNumber2(final double number2) {
this.number2Property().set(number2);
}
}
public static void main(String[] args) {
launch(args);
}
}
非常感谢你,我非常感谢你的努力。但是如果我选择你的解决方案,那么我会失去选择和e的选项。 G。复制/粘贴表格单元格。 – Roland
其实,你仍然可以选择单元格,虽然它确实很难:你需要单击单元格但在文本字段外(默认情况下,有少量空间)。但是,您也可以将焦点侦听器添加到文本字段,并在获得焦点时将单元格设置为选中状态。请参阅完整示例中的更新。 –
谢谢,但它不直观。我们正试图用JavaFX替换Swing。我们有沉重的桌子使用。到目前为止,我所看到的JavaFX缺乏人们对桌面的期望。我想这就是为什么它调用tableVIEW而不是TableEditor。基本上我们的用户需要他们与Excel一起使用的东西。我仍然想知道为什么Oracle不以这种方式实施这个表。我确实尝试了SpreadsheetView。但是,当我甚至无法在ControlsFX采样器jar中显示该示例时,这已经失败。必须是一些Java版本的东西,因为它在几个月前运行。您的意见始终很感谢,谢谢! – Roland