gpt4 book ai didi

java - 实现可编辑 TableView 时出现问题

转载 作者:行者123 更新时间:2023-12-01 11:00:45 25 4
gpt4 key购买 nike

所以我一直在尝试实现一个 TableView,您只需单击列即可编辑列,然后按 Enter 键保存编辑。我从this中的答案中获取了很多代码。线。这是结果:

import com.sun.javafx.collections.ObservableListWrapper;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.stage.Stage;

public class TestEditableTable extends Application {

public void start(Stage stage) {

TableView<ObservableList<String>> tableView = new TableView<ObservableList<String>>();
tableView.setEditable(true);

// Some dummy data.
ObservableList<ObservableList<String>> dummyData = FXCollections.observableArrayList();
ObservableList<String> firstRow = FXCollections.observableArrayList("Jack", "Smith");
dummyData.add(firstRow);
ObservableList<String> secondRow = FXCollections.observableArrayList("Peter", "Smith");
dummyData.add(secondRow);

TableColumn<ObservableList<String>, String> firstCol = new TableColumn<ObservableList<String>, String>(
"First name");
firstCol.setCellValueFactory(
(TableColumn.CellDataFeatures<ObservableList<String>, String> param) -> new SimpleStringProperty(
param.getValue().get(0)));

TableColumn<ObservableList<String>, String> secondCol = new TableColumn<ObservableList<String>, String>(
"Last name");
secondCol.setCellValueFactory(
(TableColumn.CellDataFeatures<ObservableList<String>, String> param) -> new SimpleStringProperty(
param.getValue().get(1)));

secondCol.setCellFactory(cell -> new EditableCell());

tableView.getColumns().addAll(firstCol, secondCol);

tableView.getItems().addAll(dummyData);

Scene scene = new Scene(tableView);
stage.setScene(scene);
stage.show();
}

public static void main(String[] args) {
launch();
}

class EditableCell extends TableCell<ObservableList<String>, String> {

private TextField textfield = new TextField();

// When the user presses the enter button the edit is saved.
public EditableCell() {
setOnKeyPressed(e -> {
if (e.getCode().equals(KeyCode.ENTER)) {
commitEdit(textfield.getText());
}
});
}

@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (isEmpty()) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
textfield.setText(item);
setGraphic(textfield);
setText(null);
} else {
setText(item);
setGraphic(null);
}
}
}

@Override
public void startEdit() {
super.startEdit();
textfield.setText(getItem());
setGraphic(textfield);
setText(null);
}

@Override
public void cancelEdit() {
super.cancelEdit();
setGraphic(null);
setText(getItem());
}

@Override
public void commitEdit(String value) {
super.commitEdit(value);

// This works. But gives me a "Discouraged access: The type 'ObservableListWrapper<String>' is not API (restriction on required library 'C:\Program Files\Java\jre1.8.0_60\lib\ext\jfxrt.jar')".
ObservableListWrapper<String> ob = ((ObservableListWrapper<String>) this.getTableRow().getItem());
ob.set(1, value);

// I had to put this in a Platform.runLater(), otherwise the textfield remained open.
Platform.runLater(() -> {
setText(value);
setGraphic(null);
});
}
}
}

这个程序运行正常。当您按下 Enter 按钮时,单元格将被编辑。但这有两个主要问题:

  1. 按下 Enter 键后,单元格已被编辑。我无法通过点击再次编辑它。我需要按另一行才能再次编辑它。设置为聚焦于行的父级并没有达到目的。

  2. commitEdit() 中的代码有效。但它很丑陋,并且使用 ObservableListWrapper 给我警告“不鼓励访问:类型'ObservableListWrapper'不是API(对所需库'C:\Program Files\Java\jre1.8.0_60\的限制” lib\ext\jfxrt.jar')"。此外,单元格索引是硬编码的,如果我在许多不同的列中使用它,它将无法工作。

上述问题均 Not Acceptable 。

最终的实现必须支持文本字段中输入的限制。据我了解,这意味着我需要访问单元格中显示的 TextField 对象,就像我当前的实现一样。

最佳答案

您正在将事件处理程序注册为单元格上的关键事件处理程序。在文本字段上注册处理程序更有意义,因为这是实际发生感兴趣事件的控件。另请注意 TextField s 按 Enter 时触发 Action 事件。

所以替换

    public EditableCell() {
setOnKeyPressed(e -> {
if (e.getCode().equals(KeyCode.ENTER)) {
commitEdit(textfield.getText());
}
});
}

    public EditableCell() {
textfield.setOnAction(e -> commitEdit(textfield.getText()));
}

这将确保编辑状态得到正确维护(这不会发生在您的事件处理程序中,原因我不太清楚),因此它解决了“重新编辑”的问题。这也意味着您不必手动重置 commitEdit 中的文本和图形。 .

对于第二期,您可以直接向下转换为 ObservableList<String>而不是ObservableListWrapper<String> 。但请注意,您也可以这样做

    @Override
public void commitEdit(String value) {
super.commitEdit(value);
ObservableList<String> row = getTableView().getItems().get(getIndex());
row.set(1, value);
}

这不仅避免了私有(private) API,还完全避免了向下转型。

关于java - 实现可编辑 TableView<ObservableList<String> 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33349822/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com