更新 TableColumn 单元格中的值时出现问题

Problem with updating value in TableColumn Cell

我的问题有点模棱两可(不知道是不是bug),我想让用户输入他想要的任何值,只要它不为空,所以我创建了一个方法来检查输入 which returns 前一个值 如果输入字符串为空,这就是问题发生的地方,如果用户清除单元格并按下回车键,单元格什么都不显示,直到我点击它,这里是我的项目的功能示例:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Launcher extends Application
{

    @Override
    public void start(Stage stage) throws Exception
    {
        AnchorPane root = new AnchorPane();

        TableView<Apprenant> table = new TableView<>();
        table.setPrefWidth(800);
        table.setEditable(true);
        
        TableColumn<Apprenant, String> nom = new TableColumn<>("Noms");
        nom.setPrefWidth(100);
        
        TableColumn<Apprenant, String> prenom = new TableColumn<>("Prenoms");
        prenom.setPrefWidth(100);

        nom.setCellValueFactory(var -> var.getValue().nomProperty());
        prenom.setCellValueFactory(var -> var.getValue().prenomProperty());
        
        nom.setCellFactory(TextFieldTableCell.forTableColumn());
        nom.setOnEditCommit((CellEditEvent<Apprenant, String> evt)->{
            
            Apprenant app = table.getSelectionModel().getSelectedItem();
            app.setNom(check(evt.getNewValue(),app.nomProperty().get()));
    
            /*THE ONLY WAY TO DISPLAY THE UPDATED VALUE*/
            //nom.setVisible(false); 
            //nom.setVisible(true);
        });

        table.getColumns().add(nom);
        table.getColumns().add(prenom);
        table.getItems().add(new Apprenant("monNom","monPrenom"));

        root.getChildren().add(table);
        
        Scene scene = new Scene(root,1200,800);
        stage.setScene(scene);
        stage.show();
    }
    
    private static String check(String valeur,String prev)
    {
        if(valeur.isEmpty())
        {   
            return prev;
        }
        else
        {
            return valeur;
        }
    }
    
    public static void main(String[] args)
    {
        launch(args);
    }
}

模特:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Apprenant
{
    private StringProperty nom = new SimpleStringProperty();
    private StringProperty prenom = new SimpleStringProperty();
    
    public Apprenant(String nom, String prenom)
    {
        this.nom.set(nom);
        this.prenom.set(prenom);
    }
    
    public StringProperty nomProperty()
    {
        return nom;
    }
    
    public StringProperty prenomProperty()
    {
        return prenom;
    }

    public void setNom(String nom)
    {
        this.nom.set(nom);
    }
    
    public void setPrenom(String prenom)
    {
        this.prenom.set(prenom);
    }

}

所以我的问题很简单,如何更新单元格而不必使用上述 setVisible 方法或 updateItem 函数?我发现 this 主题与我的有些相似,但没有提及我的问题。

JavaFX 中虚拟化控件的编辑机制有些不透明...

不捕获提交编辑后发生的 editCommit 事件,而是覆盖单元格的 commitEdit() 方法:

        nom.setCellFactory(tc -> new TextFieldTableCell<>(TextFormatter.IDENTITY_STRING_CONVERTER) {
            @Override
            public void commitEdit(String newValue) {
                if (newValue.isEmpty()) {
                    cancelEdit();
                } else {
                    super.commitEdit(newValue);
                }
            }
        });
//        nom.setCellFactory(TextFieldTableCell.forTableColumn());
//        nom.setOnEditCommit((CellEditEvent<Apprenant, String> evt)->{
//            
//            Apprenant app = table.getSelectionModel().getSelectedItem();
//            app.setNom(check(evt.getNewValue(),app.getNom().get()));
//    
//            /*THE ONLY WAY TO DISPLAY THE UPDATED VALUE*/
//            //nom.setVisible(false); 
//            //nom.setVisible(true);
//        });

这可能被认为是一种 hack,因为验证数据并不是单元的真正工作,但考虑到 API,这可能是阻力最小的路径。执行此操作的“正确”方法可能是在模型中执行验证,这(据我所知)将涉及子类化 StringPropertyBase 以支持验证。