enter image description here

If you multiply 5 * 5 comes out 25, when editing 6 * 5 it still goes 25.

Here are similar questions.

https://stackoverflow.com/questions/7868188/javafx-2-save-edit-in-tablecell

View

public class Earnings implements List3{ private ObservableList<Person> personList = FXCollections.observableArrayList(); private float a = 5; private float b = 5; private float c = a * b; @Override public void add(Person person) { personList.add( person ); } public ObservableList<Person> getPersonList(){ return personList; } public void print (){ int number = 0; System.out.println(); for (Person person:personList){ number++; System.out.println(number+")id ="+ person.getId()+"; position = "+person.getPosition()+"; salary = "+person.getSalary()+" prize = "+person.getPrize()+"; earnings =" + person.getEarnings()); } } public void fillEarningsData (){ personList.add( new Person( 1,"accountant",a,b,c ) ); } } 

Personcontroller

 public class PersonController { private Earnings personImpl = new Earnings(); //data bundle @FXML private TableView tablePerson; @FXML private TableColumn<Person, Integer> columnId; @FXML private TableColumn<Person, Integer> columnPosition; @FXML private TableColumn<Person, Float> columnSalary; @FXML private TableColumn<Person, Float> columnPrize; @FXML private TableColumn<Person, Float> columnEarnings; @FXML private void initialize (){ columnId.setCellValueFactory(new PropertyValueFactory<Person, Integer>("id")); columnPosition.setCellValueFactory(new PropertyValueFactory<Person, Integer>("position")); columnSalary.setCellValueFactory(new PropertyValueFactory<Person, Float>("salary")); columnPrize.setCellValueFactory(new PropertyValueFactory<Person, Float>("prize")); columnEarnings.setCellValueFactory(new PropertyValueFactory<Person, Float>("earnings")); personImpl.fillEarningsData(); tablePerson.setItems(personImpl.getPersonList()); // the mistake can here columnSalary.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter())); columnSalary.setOnEditCommit( new EventHandler<TableColumn.CellEditEvent<Person, Float>>() { @Override public void handle(TableColumn.CellEditEvent<Person, Float> t) { t.getTablePosition().getRow().setSalary( t.getNewValue() ); } } ); columnPrize.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter())); columnPrize.setOnEditCommit( new EventHandler<TableColumn.CellEditEvent<Person, Float>>() { @Override public void handle(TableColumn.CellEditEvent<Person, Float> t) { t.getTablePosition().getRow().setPrize( t.getNewValue() ); } } ); columnEarnings.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter())); columnEarnings.setOnEditCommit( new EventHandler<TableColumn.CellEditEvent<Person, Float>>() { @Override public void handle(TableColumn.CellEditEvent<Person, Float> t) { t.getTablePosition().getRow().setEarnings( t.getNewValue() ); } } ); } } 

Person

 public class Person { private int id; private String position; private float salary; private float prize; private float earnings; // Person public Person() { } public Person(int id, String position, float salary, float prize, float earnings) { this.id = id; this.position = position; this.salary = salary; this.prize = prize; this.earnings = earnings; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } public float getPrize() { return prize; } public void setPrize(float prize) { this.prize = prize; } public float getEarnings() { return earnings; } public void setEarnings(float earnings) { this.earnings = earnings; } } 

    1 answer 1

    I hope correctly understood the question ...

    As a rule, such dynamically changeable tables are simpler and more accurate to build, based on the associated .bind() objects, a vast field of various Property classes simplify working with the observed data and eliminate a lot of errors.

    Regarding the problem itself, by changing the value of one cell, you do not notify about the need to change another cell. All data in the table is stored as ObservableValue instances that the factory itself is responsible for if you have to change the cell value, then there are several ways or manually to get the object of the observed list and working with it, or it is easier to store data in the model instance as an element of Property and place (for example) the logic in the instance. Next is an example of code that I hope will clarify this me:

    PS It was not entirely clear why the position field in the Person class is an instance of String and already exists in the table as an Integer ...

     public class ForTest extends Application { private TableView<Model> tView = new TableView<>(); public static void main(String[] args) { launch(args); } @Override public void init() throws Exception { tView.setEditable(true); tView.getColumns().add(column("First", Model::firstProperty, new NumberStringConverter())); tView.getColumns().add(column("Second", Model::secondProperty, new NumberStringConverter())); tView.getColumns().add(column("Result", Model::resultProperty, new NumberStringConverter())); IntStream.rangeClosed(1, 20).mapToObj(i -> new Model(i * 2, i * 4 + 1)).forEach(tView.getItems()::add); } @Override public void start(Stage primaryStage) { Scene s = new Scene(tView, 500, 500); primaryStage.setScene(s); primaryStage.show(); } private <S, T> TableColumn<S, T> column(String title, Function<S, ObservableValue<T>> property, StringConverter<T> converter) { TableColumn<S, T> col = new TableColumn<>(title); col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); col.setCellFactory(TextFieldTableCell.forTableColumn(converter)); return col; } public static class Model { private final IntegerProperty f = new SimpleIntegerProperty(); private final IntegerProperty s = new SimpleIntegerProperty(); private final IntegerProperty result = new SimpleIntegerProperty(); public Model(int first, int second) { setFirst(first); setSecond(second); result.bind(Bindings.add(f, s)); } public final int getFirst() { return firstProperty().get(); } public final IntegerProperty firstProperty() { return f; } public void setFirst(int first) { firstProperty().set(first); } public final int getSecond() { return secondProperty().get(); } public final IntegerProperty secondProperty() { return s; } public void setSecond(int second) { secondProperty().set(second); } public final int getResult() { return resultProperty().get(); } public final IntegerProperty resultProperty() { return result; } } }