JavaFx:ObjectProperty <integer>与ObjectProperty <unit> </unit> </integer>的绑定

时间:2014-06-24 10:35:22

标签: binding combobox javafx-8

我有一个带有NumberSpinner元素和ComboBox元素的场景,我希望将minValue元素的NumberSpinner属性与{{的valueProperty绑定1}}元素。一些代码:

ComboBox

其中@FXML private NumberSpinner aNumberSpinner; @FXML private ComboBox<Unit> aComboBox; Unit

enum

我想要的是,当我在public enum Unit { mm, degree } 中选择degree Unit aComboBox minValueProperty()成为aNumberSpinner时。我怎样才能实现它?

1 个答案:

答案 0 :(得分:5)

正如Kleopatra在评论中所建议的那样,最好是该单位知道自己的最低要求。

首选解决方案 - 无约束

我首选的解决方案根本不会使用绑定。

组合框值上的侦听器可以通过查询组合框中新选择的单位的最小值,轻松地将微调器对象的最小值直接设置为适当的值。

有时绑定可能有点太棘手......

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class UnitMinimums extends Application {
    private enum Unit {
        mm(0), degree(10);

        private final int minValue;

        private Unit(int minValue) {
            this.minValue = minValue;
        }

        public int getMinValue() {
            return minValue;
        }
    }

    private Slider slider = new Slider(0, 20, 0);

    private ComboBox<Unit> combo = new ComboBox<>(
            FXCollections.observableArrayList(
                    Unit.values()
            )
    );

    @Override
    public void start(Stage stage) throws Exception {
        combo.valueProperty().addListener((observable, oldValue, newValue) ->
                slider.setMin(newValue.getMinValue())
        );
        slider.setShowTickMarks(true);
        slider.setShowTickLabels(true);

        VBox layout = new VBox(5, slider, combo);
        layout.setPadding(new Insets(10));
        VBox.setVgrow(combo, Priority.ALWAYS);
        combo.setMaxWidth(Double.MAX_VALUE);
        combo.getSelectionModel().select(0);

        stage.setScene(new Scene(layout));
        stage.show();
    }

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

Pure Binding Solution

如果您确实需要一个纯粹的绑定解决方案,您可以执行类似下面的操作,但它的缺点是如果您在代码周围散布特定于单元最小值的信息(这是枚举所固有的)开始编写这样的代码很多。

使用Bindings.when

Bindings.when(
        combo.valueProperty().isEqualTo(Unit.degree)
    ).then(10)
     .otherwise(0)

可执行样本

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class BoundMinimums extends Application {
    private enum Unit { mm, degree }

    private Slider slider = new Slider(0, 20, 0);

    private ComboBox<Unit> combo = new ComboBox<>(
            FXCollections.observableArrayList(
                    Unit.values()
            )
    );

    @Override
    public void start(Stage stage) throws Exception {
        slider.minProperty().bind(
                Bindings.when(
                        combo.valueProperty().isEqualTo(Unit.degree)
                ).then(10)
                 .otherwise(0)
        );
        slider.setShowTickMarks(true);
        slider.setShowTickLabels(true);

        VBox layout = new VBox(5, slider, combo);
        layout.setPadding(new Insets(10));
        VBox.setVgrow(combo, Priority.ALWAYS);
        combo.setMaxWidth(Double.MAX_VALUE);

        stage.setScene(new Scene(layout));
        stage.show();
    }

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

关于数据类型转换

这对我来说有点复杂和不明显(这是有时候更喜欢听众和直接设置者而不是绑定的另一个原因),但我认为你可以做类似下面的事情,它会转换DoubleProperty {{ 1}}到slider.minProperty()

ObjectProperty<Integer>

将它与单位转换结合在一起,您可以获得以下内容,甚至可以达到您想要的效果:

ObjectProperty<Integer> op = new SimpleObjectProperty<>(5);
op.bind(
    IntegerExpression.integerExpression(
        slider.minProperty()
    ).asObject()
);