JavaFX: заставить TableColumn наблюдать форматированный Double с функциональностью экстрактора - PullRequest
0 голосов
/ 10 мая 2018

У меня есть TableView, обработанное ObservableList пользовательского объекта FermentableInRecipe, где один из TableColumn s определен для обработки Number с и должен отображать значения в процентах.

Пользовательский объект определяется этим классом:

public class FermentableInRecipe extends Fermentable {

    private DoubleProperty percentage = new SimpleDoubleProperty();

    ...

    public Double getPercentage() {
        return this.percentage.getValue();
    }

    public void setPercentage(Double value) {
        if (value == null || value.isNaN() || value.isInfinite() || value > 1.0 || value < 0.0) {
            this.percentage.setValue(0.0);
        } else {
            this.percentage.setValue(value);
        }
    }

    public DoubleProperty percentageProperty() {
        if (percentage == null) {
            percentage = new SimpleDoubleProperty(0.0);
        }
        return percentage;
    }
}

В моем контроллере находится TableView объект с дочерним элементом TableColumn.

@FXML
private TableView<FermentableInRecipe> tableviewFermentablesInRecipe;
@FXML
private TableColumn<FermentableInRecipe, Number> columnRecipeFermentablePercentage;

TableView заполняется следующим ObservableList моего пользовательского объекта, который был создан с помощью экстрактора.

private ObservableList<FermentableInRecipe> fermentablesInRecipe 
        = FXCollections.observableArrayList(item -> new Observable[]{
            item.WeightProperty(), 
            item.isLateAdd(), 
            item.isBulkBought()
        });

tableviewFermentablesInRecipe.setItems(fermentablesInRecipe);

При следующем использовании методов setCellValueFactory() и setCellFactory() (которые я основал на одном из моих предыдущих вопросов ), я получил значения, отображаемые так, как я хочу. Однако он не обновляется всякий раз, когда элемент в ObservableList редактируется (как если бы он игнорировал мой экстрактор). Такое поведение не происходит, когда я наблюдаю SimpleDoubleProperty в моем пользовательском объекте напрямую (но это будет неформатированный Double).

    final JavaBeanDoublePropertyBuilder percentageCellBuilder
            = JavaBeanDoublePropertyBuilder
                    .create()
                    .beanClass(FermentableInRecipe.class)
                    .name("percentage");

    columnRecipeFermentablePercentage.setCellValueFactory(item -> {
        try {
            return percentageCellBuilder.bean(item.getValue()).build();
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(MasterController.class.getName())
                    .log(Level.SEVERE, null, ex);
            return null;
        }
    });

    columnRecipeFermentablePercentage.setCellFactory(item -> 
            new PercentageCell<>()
    );

Вот класс ячеек Процент:

public class PercentageCell<T> extends TableCell<T, Number> {

    NumberFormat percentageFormat = NumberFormat.getPercentInstance();

    @Override
    protected void updateItem(Number percentage, boolean empty) {
        super.updateItem(percentage, empty);

        if (percentage == null || empty) {
            setText(null);
            setStyle("");
        } else {
            setText(percentageFormat.format(percentage));
            setStyle("-fx-alignment: CENTER;");
        }
    }
}

Итак, вопрос в том ... Как я могу получить TableColumn для отображения отформатированного числа и при этом правильно использовать функцию извлечения?

Извините, если это слишком большой пост, но я не хотел ничего упускать.

1 Ответ

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

Как указывал @James_D, я бесполезно использовал JavaBeanDoubleProperty, потому что мой пользовательский объект уже имел DoubleProperty, который я мог бы использовать.

Чтобы исправить эту глупую ошибку, я изменил это ...

final JavaBeanDoublePropertyBuilder percentageCellBuilder
        = JavaBeanDoublePropertyBuilder
                .create()
                .beanClass(FermentableInRecipe.class)
                .name("percentage");

columnRecipeFermentablePercentage.setCellValueFactory(item -> {
    try {
        return percentageCellBuilder.bean(item.getValue()).build();
    } catch (NoSuchMethodException ex) {
        Logger.getLogger(MasterController.class.getName())
                .log(Level.SEVERE, null, ex);
        return null;
    }
}); 

... в это ...

columnRecipeFermentablePercentage.setCellValueFactory(item -> 
                                item.getValue().percentageProperty()
);

Автоматическое обновление содержимого TableView через мой экстрактор теперь работает точно так, как задумано. Глупый я.

...