javafx - 编辑表格视图单元格
问题描述
你好我想在一个Tableview中编辑一个tablecell,但是编辑值后变成0,新的值没有保存。该值是一个整数值,从“Cantidad”列中,我将值保存在 tableview 中,我发布了一些图像,如下例所示。
这是我的代码:
我的课件:
package application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class item {
private StringProperty Item;
private IntegerProperty Cantidad;
item(String Item, Integer Cantidad) {
this.Item = new SimpleStringProperty(Item);
this.Cantidad = new SimpleIntegerProperty(Cantidad);
}
public String getItem() {
return Item.get();
}
public void setItem(StringProperty Item) {
this.Item = new SimpleStringProperty();
}
public Integer getCantidad() {
return Cantidad.get();
}
public void setCantidad(Integer Cantidad) {
this.Cantidad = new SimpleIntegerProperty();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
将数据插入数据库的代码
public void insertarequisicion() {
ObservableList<item> items = titem.getItems();
if(items.isEmpty()) {
Mensaje mensajedata = new Mensaje();
mensajedata.mensajedata(titem, stpanerequi);
}
else {
String sol=solreq.getText().toString();
String area=areauser.getText().toString();
String cargo=cargouser.getText().toString();
String miceduladata=midreq.getText().toString();
String centro = centroop.getText().toString();
try {
for(item item :titem.getItems()) {
midataini=item.getCantidad();
miiteem= item.getItem();
try {
String Queryinsertitem="INSERT INTO ITEMSREQ (CANTIDAD, ITEM,CARGO, CENTRO_OPERACION, CEDULA, FECHA_SOLICITUD)VALUES( ? , ? , ? , ? , ?, GETDATE() )";
Connection ConexionData = null;
ConexionData=conectar.miconexion(ConexionData);
PreparedStatement creadatoitem = ConexionData.prepareStatement(Queryinsertitem);
creadatoitem.setInt(1, midataini);
creadatoitem.setString(2, miiteem);
creadatoitem.setString(3, cargo);
creadatoitem.setString(4, centro);
creadatoitem.setString(5, miceduladata);
creadatoitem.executeUpdate();
}catch(SQLException ex) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, ex);
}
}
String Queryreq="INSERT INTO REQUISICIONES (SOLICITANTE, CEDULA,AREA,CARGO, CENTRO_OPERACION, FECHA_SOLICITUD)VALUES('"+sol+"','"+miceduladata+"','"+area+"','"+cargo+"','"+centro+"',GETDATE())";
Connection ConexionD = null;
ConexionD=conectar.miconexion(ConexionD);
Statement creareq =ConexionD.createStatement();
creareq.executeUpdate(Queryreq);
Mensaje data = new Mensaje();
data.Reqmsj(stpanerequi);
}catch(SQLException nn) {
Logger.getLogger(Application.class.getName()).log(Level.SEVERE, null, nn);
}
}
}
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
titem.setEditable(true);
itemm.setCellValueFactory(new PropertyValueFactory <item,String>("Item"));
cantidaditemm.setCellValueFactory(new PropertyValueFactory <item,Integer>("Cantidad"));
cantidaditemm.setCellFactory(TextFieldTableCell.<item, Integer>forTableColumn(new IntegerStringConverter()));
cantidaditemm.setOnEditCommit(
new EventHandler<CellEditEvent<item, Integer>>() {
@Override
public void handle(CellEditEvent<item, Integer> t) {
((item) t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setCantidad(t.getNewValue());
}
}
);
}
我做错了什么?
解决方案
你的item
班级有一些问题:
它没有为每个 JavaFX 属性提供所谓的“属性获取器”。
- 这会阻止诸如 API 之类
TableView
的正确观察模型项。 - 每个 JavaFX 属性都应该有一个 getter、属性 getter 和(如果外部可写的话)一个 setter。getter 和可选 setter 处理属性的值,而属性 getter 返回属性对象本身。
- 这会阻止诸如 API 之类
JavaFX 属性实例在每个相应的设置器中被替换。
- 这使得观察属性毫无用处。
它不遵循Java 命名约定。
- 我认为这不会在这种特定情况下导致任何问题。也就是说,它使其他 Java 开发人员更难快速阅读您的代码。例如,Stack Overflow 没有应用正确的语法高亮。至少在发布到公共论坛时,请遵循 Java 命名约定。
您的模型类应该看起来更像:
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
public class Item {
/*
* Note: You don't have to keep the same class layout. I made all the methods
* a single line and closely grouped together in order to take up less
* space on Stack Overflow. That said, some core JavaFX classes follow
* this pattern for properties.
*/
private final StringProperty item = new SimpleStringProperty(this, "item");
public final void setItem(String item) { this.item.set(item); }
public final String getItem() { return item.get(); }
public final StringProperty itemProperty() { return item; }
private final IntegerProperty cantidad = new SimpleIntegerProperty(this, "cantidad");
public final void setCantidad(int cantidad) { this.cantidad.set(cantidad); }
public final int getCantidad() { return cantidad.get(); }
public final IntegerProperty cantidadProperty() { return cantidad; }
public Item() {}
public Item(String item, int cantidad) {
setItem(item);
setCantidad(cantidad);
}
}
注意:我修改了您的类和字段的名称以遵循Java 命名约定。但是,我建议将item
属性命名为其他名称,以避免与类具有相同的名称。
然后,您TableView
将以类似于以下方式设置 a:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Item> table = new TableView<>();
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
table.setEditable(true);
table.getItems().addAll(new Item("usb", 3), new Item("dvd", 2));
TableColumn<Item, String> itemCol = new TableColumn<>("Item");
itemCol.setCellValueFactory(data -> data.getValue().itemProperty());
table.getColumns().add(itemCol);
TableColumn<Item, Number> cantidadCol = new TableColumn<>("Cantidad");
cantidadCol.setCellValueFactory(data -> data.getValue().cantidadProperty());
cantidadCol.setCellFactory(TextFieldTableCell.forTableColumn(new NumberStringConverter()));
table.getColumns().add(cantidadCol);
primaryStage.setScene(new Scene(table, 600, 400));
primaryStage.show();
}
}
一些注意事项:
对单元格值工厂使用自定义
Callback
实现(通过 lambda 表达式)而不是PropertyValueFactory
. 这提供了编译时安全性,因为属性必须存在并且是正确的类型才能编译代码。次要注意,这也避免了反思。该列
cantidad
现在使用Number
而不是Integer
. 这是第一点的结果,因为IntegerProperty
is anObservableValue<Number>
而不是ObservableValue<Integer>
。这也意味着IntegerStringConverter
必须将其替换为NumberStringConverter
.未
onEditCommit
设置处理程序。这是因为:默认情况下,
TableColumn
编辑提交处理程序是非空的,默认处理程序会尝试覆盖当前正在编辑的行中项目的属性值。资源:
TableView
WritableValue
此默认处理程序可以处理单元格值工厂返回(并且IntegerProperty
是 aWritableValue<Number>
)的实例的简单情况。
推荐阅读
- javascript - external function call, promise, async and Mongo - confused
- perl - 今天的日期匹配不正确
- python - 函数未返回预期实例
- java - 拆分和隐蔽以使从文本文件中读取的值加倍时找不到源错误
- asynchronous - F# 在另一个线程上运行阻塞调用,在异步工作流中使用
- android - 如何使用 okio/okhttp 解码 http 请求数据包
- elasticsearch - Elasticsearch 重新索引竞争条件
- c++ - 检测两条线是否相交的算法在 SFML 中没有给出准确/想要的结果
- ios - UITableView 不检查 Swift 中的标记单元格(在 didSelect 和 didDeselect 之外)
- keycloak - 仅允许授权 IDP 帐户的 Keycloak 流程