Java 更新TableColumn单元格中的值时出现问题
我的问题有点模棱两可(我不知道这是不是一个bug),我希望用户输入他想要的任何值,只要它不是空的,所以我创建了一个方法来检查输入,如果输入字符串是空的,则返回上一个值,如果用户清除单元格并按下enter键,这就是问题发生的地方,该单元格不显示任何内容,直到我单击它,以下是我的项目的功能示例:Java 更新TableColumn单元格中的值时出现问题,java,javafx,Java,Javafx,我的问题有点模棱两可(我不知道这是不是一个bug),我希望用户输入他想要的任何值,只要它不是空的,所以我创建了一个方法来检查输入,如果输入字符串是空的,则返回上一个值,如果用户清除单元格并按下enter键,这就是问题发生的地方,该单元格不显示任何内容,直到我单击它,以下是我的项目的功能示例: import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.TableColu
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);
}
}
因此,我的问题很简单,如何更新单元格而不必使用上述
setVisible
方法或updateItem
函数?我发现这个主题与我的主题有些相似,但没有提及我的问题。JavaFX中虚拟化控件的编辑机制有些不透明
与其捕获提交编辑后发生的editCommit
事件,不如覆盖单元格的committedit()
方法:
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);
// });
nom.setCellFactory(tc->new TextFieldTableCell(TextFormatter.IDENTITY\u STRING\u转换器){
@凌驾
public void committedit(字符串newValue){
if(newValue.isEmpty()){
取消编辑();
}否则{
super.committedit(newValue);
}
}
});
//nom.setCellFactory(TextFieldTableCell.forTableColumn());
//名称setOnEditCommit((CellEditEvent evt)->{
//
//Apprenant app=table.getSelectionModel().getSelectedItem();
//app.setNom(检查(evt.getNewValue(),app.getNom().get());
//
///*显示更新值的唯一方法*/
////名称setVisible(false);
////nom.setVisible(true);
// });
这可能被认为是一种黑客行为,因为验证数据实际上不是细胞的工作,但考虑到API,这可能是阻力最小的途径。“正确”的方法可能是在模型中执行验证,这(据我所知)将涉及子类化
StringPropertyBase
,以支持验证。无关:请使用属性命名模式。例如,您应该有StringProperty nomProperty()
,String getNom()
,还有void setNom(String nom)
@kleopatra,像这样吗?我不熟悉约定:)根据设计,提交处理程序是实现接受或拒绝类型的验证的方法——无可否认,这并不太灵活。不显示编辑后的值是一个错误,无论是在OPs代码中(对所选项目而不是通过事件传递的状态进行操作的奇怪实现),还是在fx中(隐约记得一些问题,现在已经太晚了,无法挖掘)
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);
// });