Работать со значением из PropertyValueFactory в TableView - JavaFx - PullRequest
0 голосов
/ 11 мая 2018

В моем проекте JavaFx у меня есть сцена с несколькими представлениями. Для нижнего колонтитула окна у меня есть класс, выходящий из TableView:

public class FooterView extends TableView<Area> implements ViewTemplate {...}

Отображает таблицу с некоторыми данными из CSV-файла.

Когда дело доходит до назначения значения конкретного свойства presentationmodel для ячеек, я делаю это так:

TableColumn<Area,Double> powerColumn = new TableColumn<>("Power Overview");
powerColumn.setCellValueFactory(new PropertyValueFactory<>("powerPerArea"));

this.setItems(filePM.getAreas()); //filePm is my filehandler
this.getColumns().addAll(powerColumn, other_columns);

getAreas() выглядит так:

public List<Area> readCantonsFromFile() {
        try (Stream<String> stream = getStreamOfLines(AREA_FILE_NAME)) {
            return stream.skip(1)
                    .map(l -> new Area(l.split(DELIMITER, 12)))
                    .collect(Collectors.toList());
        }
}

В конструкторе Area я устанавливаю свойства. Одним из свойств является упомянутый powerPerArea

private final DoubleProperty powerPerArea = new SimpleDoubleProperty();
...
public void setPowerPerCanton(double powerPerCanton) {
    this.powerPerCanton.set(powerPerCanton);
}

Мой вопрос: Есть ли способ изменить значение в FooterView до его отображения? Я пробовал что-то вроде этого:

powerColumn.setCellValueFactory(Math.round(new PropertyValueFactory<>("powerPerArea")));

Но похоже, что я перепутал DoubleProperty, Double и ObservableDouble. Могу ли я изменить значение здесь?

Проблема: я не могу округлить значение в установщике, потому что я добавляю двойное значение в цикле через эту функцию:

public void addPowerPerArea(double power){
    double sum = getPowerPerCanton() + power;
    setPowerPerCanton(sum);
}

И округление значения здесь даст мне неверный результат. (округление недостаточно точное). Мне нужно сделать это в конце, когда все суммы добавляются

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

Вы должны использовать cellValueFactory, чтобы определить , какие данные отображаются в ячейках: в этом случае данные, возвращаемые вашим PropertyValueFactory, являются фактическим значением double, возвращаемым из powerPerAreaProperty().get(), что именно то, что вы хотите.

Если вы хотите контролировать как данные отображаются, вы должны использовать cellFactory. Таким образом, для отображения данных в определенном формате, включая ограничение количества десятичных знаков, вы можете сделать:

powerColumn.setCellFactory(tc -> new TableCell<Area, Double>() {
    @Override
    protected void updateItem(Double power, boolean empty) {
        super.updateItem(power, empty);
        if (empty) {
            setText(null);
        } else {
            setText(String.format("%.0f", power.doubleValue()));
        }
    }
});

Дело в том, что вы не должны изменять данные в зависимости от того, как вы хотите их отображать; цель наличия cellValueFactory и cellFactory состоит в том, чтобы отделить отображение данных от самих фактических данных.

0 голосов
/ 11 мая 2018

Альтернативой возвращению пользовательских ячеек из cellFactory может быть использование пользовательского cellValueFactory для возврата свойства, отформатированного как строка:

TableColumn<Area, String> powerColumn = new TableColumn<>("Power Overview");
powerColumn.setCellValueFactory(cd -> cd.getValue().powerPerAreaProperty().asString(""%.0f""));
0 голосов
/ 11 мая 2018

Я вижу два способа сделать это.Вы можете:

использовать метод setCellFactory и в методе updateItem вы форматируете его.Должно выглядеть примерно так: не тестировал

powerColumn.setCellFactory(column -> {
    return new TableCell<Area, Double>() {
        @Override
        protected void updateItem(Double item, boolean empty) {
            super.updateItem(Math.round(item), empty);
        }
    };
});

ИЛИ: Вы можете создать другое свойство вашего класса Area, которое привязано к существующему свойству powerOfArea, но возвращает округленное значение.Я уверен, что это как-то возможно, вы можете просто переопределить некоторые функции readOnlyDoubleProperty, но должен быть лучший способ.Может быть через DoubleBindings.

...