TableView не отображает элементы правильно

Я хочу, чтобы мой TableView с моими тремя TableColumns отображал в нем некоторые продукты. При добавлении новых продуктов они сохраняются в контейнерах данных, но не отображаются в моем представлении таблицы.

import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.cell.TextFieldTableCell;
public class ViewShop extends BorderPane {

    private Button add;
    private Button remove;
    private TextField name;
    private TextField price;
    private TextField count;
    private VBox vbox;
    private HBox hbox;
    public TableView<fpt.com.Product> tv;
    private TableColumn<fpt.com.Product, Number> sprice;
    private TableColumn<fpt.com.Product, String> sname;
    private TableColumn <fpt.com.Product, Number>scount;
    private Label namelabel;
    private Label pricelabel;
    private Label countlabel;

    private ListView<fpt.com.Product> list; 

    public ViewShop()
    {

        remove=new Button("Remove");
        add=new Button("Add");
        name=new TextField();
        price=new TextField();
        count=new TextField();
        tv=new TableView<fpt.com.Product>();
        sprice=new TableColumn<fpt.com.Product, Number>("Preis");
        sname=new TableColumn<fpt.com.Product, String>("Name");
        scount=new TableColumn<fpt.com.Product, Number>("Anzahl");
        namelabel=new Label("Name");
        pricelabel=new Label("Preis");
        countlabel=new Label("Anzahl");
        list = new ListView<fpt.com.Product>();
        hbox=new HBox();
        vbox=new VBox();
        tv.getColumns().addAll(sname,sprice,scount);
        tv.setEditable(true);
        tv.getColumns().get(0).getCellData(0);
        tv.setItems(list.getItems());
        sname.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        sprice.setCellValueFactory(cellData -> cellData.getValue().priceProperty());
        scount.setCellValueFactory(cellData -> cellData.getValue().quantityProperty());
        tv.setItems(list.getItems());
        hbox.getChildren().addAll(remove, add);
        vbox.getChildren().addAll(namelabel,name,pricelabel ,price, countlabel , count, hbox);
        this.setRight(vbox);
        this.setLeft(tv);
    }
    public void addEventHandleradd(EventHandler<ActionEvent> eventHandler) {
        this.add.addEventHandler(ActionEvent.ACTION, eventHandler);
    }
    public void addEventHandlerremove(EventHandler<ActionEvent> eventHandler) {
        this.remove.addEventHandler(ActionEvent.ACTION, eventHandler);
    }
    public String giveName()
    {
        return name.getText();
    }
    public String givePrice()
    {
        return price.getText();
    }
    public String giveCount()
    {
        return count.getText();
    }
    public ListView<fpt.com.Product> getList()
    {
        return list;
    }


}

Класс ControllerShop

import javafx.event.ActionEvent;
import javafx.event.EventHandler;

public class ControllerShop {

    ModelShop model;
    ViewShop view;

    public void link(ModelShop model, ViewShop view)
    {
        this.model=model;
        this.view=view;
        model.setProductList();
        view.getList().setItems(model);
        view.addEventHandleradd(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                model.doAdd(model.size(), new Product(view.giveName(), Integer.parseInt(view.giveCount()), Double.parseDouble(view.givePrice())));
                System.out.println(view.getList().getItems().size());
                System.out.println(model.size());
            }
        });
        view.addEventHandlerremove(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                model.remove(model.findProductByName(view.giveName()));
                }
        });

    }

}

Класс Продукт

import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.InvalidationListener;
import javafx.beans.property.DoubleProperty;

public class Product implements fpt.com.Product {

    Long id;
    SimpleStringProperty name;
    SimpleIntegerProperty quantity;
    SimpleDoubleProperty price;

    public Product(String name, int quantity, double price)
    {
        this.name=new SimpleStringProperty(name);
        this.quantity=new SimpleIntegerProperty(quantity);
        this.price=new SimpleDoubleProperty(price);
    }




    @Override
    public long getId() {
        return id;
    }

    @Override
    public void setId(long id) {
        this.id=id;

    }

    @Override
    public double getPrice() {
        return this.price.get();
    }

    @Override
    public void setPrice(double price) {
        this.price.set(price);
    }

    @Override
    public int getQuantity() {
        return this.quantity.get();
    }

    @Override
    public void setQuantity(int quantity) {
        this.quantity.set(quantity);
    }

    @Override
    public String getName() {
        return this.name.get();
    }

    @Override
    public void setName(String name) {
        this.name.set(name);
    }

    @Override
    public StringProperty nameProperty() {
        return name;
    }

    @Override
    public DoubleProperty priceProperty() {
        return price;
    }

    @Override
    public IntegerProperty quantityProperty() {
        return quantity;
    }

}

Класс Main

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application{

    public static void main(String[] args) {
        Application.launch(args);

    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        ModelShop model=new ModelShop();
        ViewShop view=new ViewShop();
        ControllerShop controller=new ControllerShop();
        controller.link(model, view);
        primaryStage.setScene(new Scene(view, 400, 400));
        primaryStage.show();

    }

}

person sebastiank.    schedule 18.11.2015    source источник


Ответы (1)


В конструкторе ViewShop вы устанавливаете список элементов таблицы в список элементов ListView:

tv.setItems(list.getItems());

Затем, позже, в конструкторе вашего контроллера вы меняете список элементов ListView на список из модели:

view.getList().setItems(model);

Однако на этом этапе вы не меняете список элементов таблицы. Итак, теперь список элементов ListView является моделью, а список элементов таблицы является исходным (по умолчанию) списком элементов из ListView. Следовательно, когда вы добавляете элементы в свою модель, таблица не будет видеть эти элементы.

Вам либо нужно установить список элементов таблицы для модели в конструкторе контроллера:

view.getTable().setItems(model);

(с очевидным getTable() методом, определенным в представлении), или вы можете привязать элементы таблицы к элементам списка, заменив

tv.setItems(list.getItems());

с участием

tv.itemsProperty().bind(list.itemsProperty());

в конструкторе представления.

person James_D    schedule 18.11.2015
comment
Setitems метода (значение ObservableList ‹Product›) TableView ожидает ObservableList. Таким образом, TableView получает уведомление при изменении его элементов. Я считаю, что это причина того, что ваше предложение не работает. Я проверил это, но это не так. Но все же спасибо за ваше предложение :) Вы видите другие причины, по которым код не работает? - person sebastiank.; 18.11.2015
comment
Я предположил, что model был ObservableList<Product>, поскольку вы также передаете его методу setItems представления списка. - person James_D; 18.11.2015
comment
Кроме того, если вам нужно больше решений, чем я предоставил, я рекомендую вам создать минимально воспроизводимый пример. Мое решение отлично работает в моем тестовом примере. - person James_D; 19.11.2015
comment
Я исправил проблему очень странным решением. Я добавил эти строки в ControllerShip: - person sebastiank.; 19.11.2015
comment
int i=0; Я объявил эту новую переменную вне метода. Я добавил следующий код в дескриптор метода, я включил телевизор в общедоступную переменную в ViewShop i++; view.tv.getItems().add(new Product("a",1,1)); view.tv.getItems().remove(i); , теперь он работает. Но я действительно не знаю почему. - person sebastiank.; 19.11.2015