javafxtableviewobservablelist

How can I update my data using an observable list and an editable table view


I've been trying this for quite some time myself and did lots of research. However, I have not come up with a solution. In my table view, I have an editable column. I can change the data in that table and print it in the controller.

TableView:

    <TableColumn fx:id="colQTY" editable="true" onEditCommit="#changeQty" prefWidth="35.0" text="Ist">
        <cellValueFactory>
          <PropertyValueFactory property="sQuantity" />
        </cellValueFactory>
        <cellFactory>
        <TextFieldTableCell fx:factory="forTableColumn" />
        </cellFactory>
    </TableColumn>  

Controller:

    @FXML
    private void changeQty(CellEditEvent<?,?> event) {
        System.out.println(event.getNewValue().toString());
    }

The data is in an sqlite database, represented by an observable list

Data Class:

public class SupplyData {
    public SimpleStringProperty sPart;
    public SimpleStringProperty sLocation;
    public SimpleStringProperty sQuantity;
    
    public SupplyData(String sPart, String sLocation, String sQuantity) {
        this.sPart= new SimpleStringProperty(sPart);
        this.sLocation= new SimpleStringProperty(sLocation);
        this.sQuantity= new SimpleStringProperty(sQuantity);
    }   
    
    public void setsPart(String sPart) {
        this.sPart.set(sPart);
    }
    
    public String getsPartl() {
        return sPart.get();
    }
    
    public SimpleStringProperty sPartProperty() {
        return sPart;
    }
    
    public void setsLocation(String sLocation) {
        this.sLocation.set(sLocation);
    }
    
    public String getsLocation() {
        return sLocation.get();
    }

    public SimpleStringProperty sLocationProperty() {
        return sLocation;
    }

    public void setsQuantity(String sQuantity) {
        this.sQuantity.set(sQuantity);
    }
    
    public String getsQuantity() {
        return sQuantity.get();
    }
    
    public SimpleStringProperty sQuantityProperty() {
        return sQuantity;
    }
}

Data Access Class:

public class SupplyDataAccess {

    private ObservableList<SupplyData> supplies;

    public SupplyDataAccess() {
        supplies = FXCollections.observableArrayList();
    }

    public ObservableList<SupplyData> getSupplies() {
        return supplies;
    }

    public static Connection connectDB(String sDB) {
        Connection myDB = null;
        try {
            myDB = DriverManager.getConnection(sDB);
        }catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        
        return myDB;
    }    
    
    public void loadData(){

        SupplyData data;
        
        String sDB = "jdbc:sqlite:c:\\supplies.db";
        String sQuery = "select * from supplies;";
        Connection myDB = connectDB(sDB);
        

        try{
        
            ResultSet rs = myDB.createStatement().executeQuery(sQuery);
            while(rs.next()) {
                data = new SupplyData(  rs.getString("Part"),
                                        rs.getString("Location"),
                                        rs.getString("Quantity"));
                supplies.add(data);
            } //while
            rs.close();
            myDB.close();

        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }               
                
    }//loadData
    
} //class

The controller has this code snipplet to populate the tableview:

    public void initialize(){
        
        dataAccess = new SupplyDataAccess();
        dataAccess.loadData();
        tblSupplies.setItems(dataAccess.getSupplies());
    }

That works and I can change the quantity. It is visible in the table view. How can I write the new value back to the observable list and from there to the database?

How can I access the other fields in changeQty in the controller? Part and Location are the fields I need to identify the record in the underlying database. If I can access those values in the controller, I can pass them to the data access class and create a SQL statement. That's not a problem.

Thanks in advance,

Michael


Solution

  • I figured it out.
    The commit handler I had created (onEditCommit="#changeQty") didn't do anything but showing the new value. After I deleted the commit handler, the ObservableList was updated as it should.
    That brought me back to the problem of how to update the database to make the change persistent.
    I created the commit handler again, update the observable list, and call a method in the data access class to update the database. Like so

        @FXML
        private void updateQty(CellEditEvent<SupplyData,String> event) {
            //this defines ChangedSupply and writes the current row of the table to it
            SupplyData ChangedSupply = event.getRowValue();
            
            //this updates the observable list
            ChangedSupply.setsQuantity(event.getNewValue());
            
            //this in the end updates the database
            dataAccess.updateData(ChangedSupply);
        }
    

    Thanks to @kleopatra for pointing me in the right direction. Maybe this helps someone else in the future.