我有一个带有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
时。我怎样才能实现它?
答案 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(
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()
);