Привязать существование значения в ObservableSet к свойству

#java #javafx #properties #javafx-8

#java #javafx #свойства #javafx-8

Вопрос:

Допустим, у меня есть ObservableSet<Integer> целых чисел. Я хочу нарисовать фигуру или, точнее, круг.

 Circle circle = new Circle(5);
circle.setFill(Color.RED);
  

Возможно ли привязать visibleProperty() этой формы к существованию значения внутри набора для JavaFX и JDK8?

Например, если набор содержит, 5 установите видимость фигуры на true , в противном случае false . Существуют ли какие-либо подходы для привязки к существованию элементов внутри коллекций в целом?

Комментарии:

1. хм.. интересно: ничего не удалось найти (что не означает, что его нет 🙂 Похоже, вам нужно сделать это вручную: зарегистрировать SetChangeListener в ObservableSet и позволить ему обновить логическое свойство при добавлении / удалении, затем привязать видимость к этому логическому

Ответ №1:

Похоже, что нет ничего готового (по крайней мере, я ничего не смог найти), поэтому мы должны сделать это сами. В основном два варианта:

  • зарегистрируйте SetChangeListener в ObservableSet, при уведомлении обновите BooleanProperty вручную
  • оберните ObservableSet в setProperty и создайте BooleanBinding, который запрашивает вызываемый объект при получении любого изменения

Оба кажутся немного неуклюжими, могут быть лучшие подходы. Пример для обоих:

 public class SetContainsBinding extends Application {
    private Parent createContent() {
        ObservableSet<Integer> numberSet = FXCollections.observableSet(1, 2, 3, 4);
        BooleanProperty contained = new SimpleBooleanProperty(this, "contained", true);
        int number = 2;
        numberSet.addListener((SetChangeListener<Integer>) c -> {
            contained.set(c.getSet().contains(number));
        });

        Circle circle = new Circle(50);
        circle.setFill(Color.RED);
        circle.visibleProperty().bind(contained);

        SetProperty<Integer> setProperty = new SimpleSetProperty<>(numberSet);
        BooleanBinding setBinding = 
                Bindings.createBooleanBinding(() -> setProperty.contains(number), setProperty);

        Circle bindingC = new Circle(50);
        bindingC.setFill(Color.BLUEVIOLET);
        bindingC.visibleProperty().bind(setBinding);

        HBox circles = new HBox(10, circle, bindingC);

        Button remove = new Button("remove");
        remove.setOnAction(e -> {
            numberSet.remove(number);
        });
        Button add = new Button("add");
        add.setOnAction(e -> {
            numberSet.add(number);
        });
        BorderPane content = new BorderPane(circles);
        content.setBottom(new HBox(10, remove, add));
        return content;
    }

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(new Scene(createContent()));
        stage.setTitle(FXUtils.version());
        stage.show();
    }

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

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger
            .getLogger(SetContainsBinding.class.getName());

}