Как сделать TableCell редактируемым, чтобы он автоматически обновлял класс данных?

Я создаю систему для школьного проекта, и одна ее часть — это TableView, который заполняется строками с использованием моего собственного класса данных InventoryData со свойствами, соответствующими столбцам таблицы. Я хотел бы сделать ячейки в некоторых столбцах редактируемыми с помощью TextField, чтобы при совершении редактирования оно обновляло соответствующее свойство объекта InventoryData.

Я попытался установить TextFieldTableCell.forTableColumn() в качестве фабрики ячеек столбцов. Хотя теперь, после фиксации редактирования, текст в ячейке изменится, я не думаю, что это меняет свойство в объекте InventoryData. Причина, по которой я так думаю, заключается в том, что когда я пытаюсь снова отредактировать эту ячейку (после того, как она уже была отредактирована один раз), TextField показывает прежнее значение (до первого редактирования).

Я сделал что-то не так, или это нормальное поведение, и я должен сам выполнять коммиты?

Вот код для InventoryData :

package UILayer.TableData;

import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import ModelLayer.Product;

public class InventoryData {


    // From Product
    private Product productObj;
    private SimpleIntegerProperty id;
    private SimpleStringProperty name;

    // Constructor - converts Product obj into InventoryData
    public InventoryData(Product product) 
    {
        this.productObj = product;

        this.id = new SimpleIntegerProperty(product.getId());
        this.name = new SimpleStringProperty(product.getName())

    }


    // GET & SET
    public Product getProduct() 
    {
        return productObj;
    }

    public int getId() {
        return id.get();
    }
    public void setId(int id) {
        this.id.set(id);
    }

    public String getName() {
        return name.get();
    }
    public void setName(String name) {
        this.name.set(name);
        productObj.setName(name);
        System.out.println(productObj.getName());
    }

}

person Near    schedule 16.05.2015    source источник


Ответы (1)


Вам нужен класс InventoryData для использования шаблона свойств JavaFX. В частности, для извлечения свойства в ячейках таблицы требуются методы доступа типа свойства. Без этого фабрика значений ячеек просто вызывает стандартный метод getName() или getId() и оборачивает результат в ReadOnlyStringWrapper (или ReadOnlyIntegerWrapper): ячейка таблицы не может изменить значения этих оболочек (поскольку они доступны только для чтения).

public class InventoryData {


    // From Product
    private Product productObj;
    private IntegerProperty id;
    private StringProperty name;

    // Constructor - converts Product obj into InventoryData
    public InventoryData(Product product) 
    {
        this.productObj = product;

        this.id = new SimpleIntegerProperty(product.getId());
        this.name = new SimpleStringProperty(product.getName())

        this.name.addListener((obs, oldName, newName) -> 
            productObj.setName(newName));

    }


    // GET & SET
    public Product getProduct() 
    {
        return productObj;
    }

    public IntegerProperty idProperty() {
        return id ;
    }
    public final int getId() {
        return idProperty().get();
    }
    public final void setId(int id) {
        idProperty().set(id);
    }

    public StringProperty nameProperty() {
        return name ;
    }
    public final String getName() {
        return nameProperty().get();
    }
    public final void setName(String name) {
        this.nameProperty().set(name);
        // productObj.setName(name);
        // System.out.println(productObj.getName());
    }

}
person James_D    schedule 16.05.2015
comment
Я об этом не подумал, спасибо, вроде работает. Не могли бы вы указать, что затем вызывается, когда ячейка таблицы фиксируется? Потому что было бы неплохо, если бы он также мог выполнить productObj.setName(name) в процессе, если это возможно. EDIT: я вообще не заметил слушателя в конструкторе -.- - person Near; 16.05.2015
comment
Он вызывает nameProperty().set(...), поэтому слушатель должен синхронизировать product.name... - person James_D; 16.05.2015
comment
Да, как я уже сказал, мои глаза как бы пропустили линии слушателя :) Спасибо за вашу помощь! Хорошего дня - person Near; 16.05.2015