我想切換到我的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