更新 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
以支持验证。
我的问题有点模棱两可(不知道是不是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
以支持验证。