Editable table cells in JavaFX show old values when trying to edit them again

Viewed 46

Edit:
-----------------------------------------------------------
I added the class InterfaceEntry which wraps Entry and gives it JavaFX properties:

public class InterfaceEntry {

    private StringProperty service = new SimpleStringProperty();
    private StringProperty username = new SimpleStringProperty();

    public InterfaceEntry() {}

    public InterfaceEntry(Entry entry) {
        setService(entry.getService());
        setUsername(entry.getUsername());
    }

    public Entry toEntry() {
        Entry entry = new Entry();

        entry.setService(getService());
        entry.setUsername(getUsername());

        return entry;
    }

    public String getService() {
        return service.get();
    }

    public StringProperty serviceProperty() {
        return service;
    }

    public void setService(String service) {
        this.service.set(service);
    }

    public String getUsername() {
        return username.get();
    }

    public StringProperty usernameProperty() {
        return username;
    }

    public void setUsername(String username) {
        this.username.set(username);
    }
}

-----------------------------------------------------------



Initial Question:
-----------------------------------------------------------
I create a table like this in FXML:

<TableView fx:id="tableView" editable="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
    <columns>
        <TableColumn reorderable="false" onEditCommit="#onEditTable" text="Service">
            <cellValueFactory>
                <PropertyValueFactory property="service"/>
             </cellValueFactory>
             <cellFactory>
                 <TextFieldTableCell fx:factory="forTableColumn"/>
             </cellFactory>
         </TableColumn>
         <TableColumn reorderable="false" onEditCommit="#onEditTable" text="Username">
            <cellValueFactory>
                <PropertyValueFactory property="username"/>
             </cellValueFactory>
             <cellFactory>
                 <TextFieldTableCell fx:factory="forTableColumn"/>
             </cellFactory>
         </TableColumn>
    </columns>
<TableView>

My controller looks like this:

@FXML
private TableView<InterfaceEntry> tableView;

private InterfaceEntry interfaceEntry;

public void initialize() {
    Entry entry = new Entry();
    
    entry.setService("Service");
    entry.setUsername("Username");

    interfaceEntry = new InterfaceEntry(entry);

    tableView.getItems().add(interfaceEntry);
}

public void onEditTable() {
    System.out.println("Username: " + interfaceEntry.getUsername());
    System.out.println("Service: " + interfaceEntry.getService());
}

This is the Entry class:

public class Entry {

    private String service;
    private String username;

    public String getService() {
        return service;
    }

    public void setService(String service) {
        this.service = service;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

If I edit for example the Username cell, everything seems to be working fine. But if I try to edit it again, the old username is shown in the TextField and the username attribute of Entry is also still the old one.

So if I change the Username cell to newUsername and the Service cell to newService, this is the output:

Username: Username
Service: Service

Username: Username
Service: Service

That is the expected output:

Username: newUsername
Service: Service

Username: newUsername
Service: newService

How can this be fixed?

1 Answers

The issue was that the default event handler was getting overwritten. I fixed it by executing it before running my logic:

public void initialize {
   tableView.getColumns().forEach(column -> {
       EventHandler handler = column.getOnEditCommit();

       handler.setOnEditCommit(event -> {
           handler.handle(event);

           onEditTable();
       });
   });
}

I also had to remove #onActionEvent="onEditTable" from the TableColumn elements in the FXML document.

Related