Coordinador Sistemas
Coordinador Sistemas

Reputation: 19

Editing Tableview Cell

Hello I Want to edit a tablecell in a Tableview, but after edit the value, this becomes 0, the new value is not saved. the value is a Integer value, From the column "Cantidad", I saved the value in the tableview , I Post some images like the example below.

this is my code:

my class item:

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

    }

}

the code to insert the data in DB

 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());
                }
            }
            );
}

what i am doing wrong?

enter image description here

enter image description here

enter image description here

Upvotes: 0

Views: 214

Answers (1)

Slaw
Slaw

Reputation: 45746

Your item class has some issues:

  1. It doesn't provide so-called "property getters" for each JavaFX property.

    • This prevents APIs such as TableView from properly observing the model item.
    • Each JavaFX property should have a getter, property getter, and—if externally writable—a setter. The getter and optional setter deal with the value of the property while the property getter returns the property object itself.
  2. The JavaFX property instance is replaced within each corresponding setter.

    • This makes observing the property useless.
  3. It doesn't follow Java naming conventions.

    • I don't believe this causes any problems in this specific case. That said, it makes it harder for other Java developers to quickly read your code. For instance, Stack Overflow doesn't apply the correct syntax highlighting. At least when posting to a public forum, please follow Java naming conventions.

Your model class should look more like:

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);
  }
}

Note: I modified the names of your class and fields to follow Java naming conventions. However, I recommend naming the item property something else to avoid having the same name as the class.

Then you'd set-up a TableView in a manner similar to the following:

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();
  }
}

Some notes:

  • Uses custom Callback implementation (via a lambda expression) for the cell value factories instead of PropertyValueFactory. This provides compile-time safety since the property has to exist and be of the correct type in order for the code to compile. On a lesser note, this also avoids reflection.

  • The column for cantidad now uses Number instead of Integer. This is a consequence of the first point since IntegerProperty is an ObservableValue<Number> and not an ObservableValue<Integer>. This also meant that IntegerStringConverter had to be replaced with NumberStringConverter.

  • The onEditCommit handlers were not set. This is because:

    By default the TableColumn edit commit handler is non-null, with a default handler that attempts to overwrite the property value for the item in the currently-being-edited row.

    Source: TableView

    This default handler can handle the simple case where the cell value factory returns an instance of WritableValue (and IntegerProperty is a WritableValue<Number>).

Upvotes: 3

Related Questions