Могут ли TableColumns содержать разные классы в TableView?

Я пытаюсь найти способ заполнить свой столбец tablePrice ценами на определенные пункты меню. Код, показанный ниже, работает нормально, но мне пришлось создать ценовую переменную в классе MenuItem, которой раньше не было. MenuItem и PricedMenuItem, а также другие классы генерируются из модели предметной области UML для системы управления рестораном. Этот текущий метод не рекомендуется, поскольку я модифицирую модель предметной области.

Прокомментированный раздел показывает, как далеко я продвинулся с ошибкой на setCellValueFactory(). Есть ли способ, чтобы TableView содержал столбцы разных классов? Если да, может ли кто-нибудь помочь мне заполнить столбец непосредственно из класса PricedMenuItem?

MenuItem имеет частное перечисление name и itemCategory, а также метод getCurrentPricedMenuItem().

PricedMenuItem имеет как частный price, так и getPrice() метод.

@FXML private TableView<MenuItem> tableView;
@FXML private TableColumn<MenuItem, String> tableName;
@FXML private TableColumn<MenuItem, Double> tablePrice;
@FXML private TableColumn<MenuItem, ItemCategory> tableCategory;

@Override
public void initialize(URL location, ResourceBundle resources) {
    tableName.setCellValueFactory(new PropertyValueFactory<MenuItem, String>("Name"));
    tableCategory.setCellValueFactory(new PropertyValueFactory<MenuItem, ItemCategory>("itemCategory"));
    tablePrice.setCellValueFactory(new PropertyValueFactory<MenuItem, Double>("price"));

    /*way to retrieve price directly from PMI
    tablePrice.setCellValueFactory(new Callback<CellDataFeatures<MenuItem, String>, ObservableValue<String>>() {
        @Override
        public ObservableValue<String> call( CellDataFeatures<MenuItem, String> c) {
          return new SimpleStringProperty(c.getValue().getValue().getCurrentPricedMenuItem().getPrice()+"");
         }
        }); 
    */

    categoryDropDown1.getItems().setAll(ItemCategory.values());
    categoryDropDown2.getItems().setAll(ItemCategory.values());

    tableView.setItems(loadCurrentMenuItems());
    updateBox("Select a menu item to edit.", Color.BLACK);
}

person Michael    schedule 03.04.2018    source источник
comment
Разве не единственная проблема закомментированного кода - неправильные типы? Вы объявили tablePrice как TableColumn<MenuItem, Double>, но возвращаете StringProperty.   -  person James_D    schedule 04.04.2018
comment
@James_D нет, Джеймс, я изменил эту часть, чтобы закомментированный код работал   -  person Michael    schedule 04.04.2018
comment
Кажется, у вас также есть getValue() дважды в цепочке вызовов методов, что не соответствует тому, как вы описываете свои классы модели, которые необходимо настроить. Что именно вы получаете, если раскомментируете закомментированный код?   -  person James_D    schedule 04.04.2018


Ответы (1)


Объявить tablePrice как

@FXML private TableColumn<MenuItem, Number> tablePrice;

(почему см. Свойства JavaFX в TableView).

Затем фабрика значений ячейки должна вернуть Property<Number> (ваша возвращает Property<String>), поэтому вам нужно

tablePrice.setCellValueFactory(new Callback<CellDataFeatures<MenuItem, Number>, ObservableValue<Number>>() {
    @Override
    public ObservableValue<Number> call( CellDataFeatures<MenuItem, Number> c) {
      return new SimpleDoubleProperty(c.getValue().getCurrentPricedMenuItem().getPrice());
    }
}); 

или, используя лямбда-выражения, чтобы избавиться от большей части шаблонного кода

tablePrice.setCellValueFactory(cellData -> 
    new SimpleDoubleProperty(cellData.getValue().getCurrentPricedMenuItem().getPrice()));

(Я почти уверен, что у вас не должно быть двух вызовов getValue() ... но вы не разместили свои классы моделей.)

person James_D    schedule 03.04.2018