在引入属性绑定之前,先来看个简单的例子:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.layout.Pane;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
public class ShowCircle extends Application{
@Override
public void start(Stage stage) {
Circle circle=new Circle(100,100,50);
Pane pane=new Pane();
pane.getChildren().add(circle);
Scene scene=new Scene(pane,200,200);
stage.setTitle("ShowCircle");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
该程序在窗口正中间显示一个圆,但是当手动拉伸窗口之后,圆的位置并没有变化。还是位于相对坐标(100,100)的位置。实际应用时,我们经常想要一个图形正好显示在窗口的正中间,不论窗口大小怎么。那么,这种功能就需要用到属性绑定。
简单讲,属性绑定就是将某个属性值(目标对象)和另一个数值(源对象)进行关联,让二者存在某关系,当观察源发生改变时,为保证二者关系不变,目标对象也相应改变。例如,上例中,可令圆心横纵坐标分别绑定为窗体宽和高的1/2,实现圆一直在窗体正中间。如下:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.layout.Pane;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
public class ShowCircle extends Application{
@Override
public void start(Stage stage) {
Circle circle=new Circle(50);
Pane pane=new Pane();
pane.getChildren().add(circle);
Scene scene=new Scene(pane,200,200);
//以下两行实现了属性绑定
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
stage.setTitle("ShowCircle");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
现在对这两行进行深入的分析:
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
1.绑定属性和绑定源都是对象,属于javafx.beans.property.Property类,而且绑定源必须实现javafx.beans.value.ObervableValue接口。
2.javaFX为基本数据类型和字符串类型创建了相应的绑定属性。分别为:DoubleProperty, FloatProperty, LongProperty, IntegerProperty,BooleanProperty,StringProperty,即为各种类型包装类名后加Property。同时它们都实现了ObervableValue接口,也可以作为绑定源。
3.Property对象的add, subtract, multiply, divide方法对对象包装的值进行运算,返回与之同类的包装了运算结果的Property对象。
将上面的第一行拆分可得到:
DoubleProperty centerX=circle.centerXProperty();
DoubleProperty width=pane.widthProperty();
DoubleProperty halfOfWidth=width.divide(2);
centerX.bind(halfOfWidth);
另外,可以使用bindBidirectional方法使两个实现了ObervableValue接口的属性对象双向绑定,改变任何一个值都会引起另一个的相应变化。