首页 > 解决方案 > 编辑表格视图单元格

问题描述

你好我想在一个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());
                }
            }
            );
}

我做错了什么?

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

标签: javafx

解决方案


你的item班级有一些问题:

  1. 它没有为每个 JavaFX 属性提供所谓的“属性获取器”。

    • 这会阻止诸如 API 之类TableView的正确观察模型项。
    • 每个 JavaFX 属性都应该有一个 getter、属性 getter 和(如果外部可写的话)一个 setter。getter 和可选 setter 处理属性的,而属性 getter 返回属性对象本身。
  2. JavaFX 属性实例在每个相应的设置器中被替换。

    • 这使得观察属性毫无用处。
  3. 它不遵循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. 这是第一点的结果,因为IntegerPropertyis anObservableValue<Number>而不是ObservableValue<Integer>。这也意味着IntegerStringConverter必须将其替换为NumberStringConverter.

  • onEditCommit设置处理程序。这是因为:

    默认情况下,TableColumn编辑提交处理程序是非空的,默认处理程序会尝试覆盖当前正在编辑的行中项目的属性值。

    资源: TableView

    WritableValue此默认处理程序可以处理单元格值工厂返回(并且IntegerProperty是 a WritableValue<Number>)的实例的简单情况。


推荐阅读