java基础:10.1 Java FX与属性绑定
图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面。
JavaFX作为Java新一代的GUI编程框架,受到Java程序员的广泛欢迎。比起上一代的Swing技术,JavaFX功能更强大,编程更简单,构造界面的控件种类更丰富,并且有功能强大的界面设计工具的支持。
下面就来简单地介绍一下JavaFX程序的基本结构,并通过一个具体的例子来做说明。
首先,介绍一下JavaFX程序的基本构成。JavaFX程序作为一种特殊类型的应用程序,它的构成也是特殊的。JavaFX为了方便程序员编写JavaFX程序,特别定义好了一个特殊的类Application,即javafx.application.Application,JavaFX程序中的主类必须从这个类派生出来,并且必须覆盖start方法,这个方法是JavaFX程序的启动方法,由Java虚拟机自动调用。代码如下:
public class MyJavaFX extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// code here
}
}
start方法的主要作用就是完成程序界面的具体构造,它接受的参数primaryStage是由Java虚拟机自动创建的一个特殊对象,称为主舞台stage,相当于程序的主窗口。我们需要在这个主舞台上完成界面的构造。
首先需要创建一个场景(Scene)对象,然后将场景对象添加到主舞台上,然后再在场景上摆放各种节点Node来构造界面。它们的关系如下图所示:
图中的按钮Button就是控件,控件也是节点的一种,具体的界面主要就是由各种控件来构成,不同的控件有着不同的外观和功能。
Stage(舞台) > Scene(场景) > Pane(面板) > node(节点)
面板的作用:为了更好地构造不同的界面,可以借助各种面板来进行布局。容器类。自动地将节点布局在一个希望的位置和大小。将节点置于一个面板中,然后将面板再置于一个场景中。将节点置于一个面板中,然后将面板再置于一个场景中JavaFX提供了多种面板供我们使用,方便我们进行不同风格的布局。
节点是可视化组件,比如一个形状、一个图像视图、一个UI 组件或者一个面板。
形状是指文字、直线、圆、椭圆、矩形、弧、多边形、折线等。
UI 组件是指标签、按钮、复选框、单选按钮、文本域、文本输入区域等。
Scene 可以包含Control 或者Pane, 但是不能包含Shape 和ImageView。
Pane可以包含Node 的任何子类型。
可以使用构造方法Scene(Parent, width, height)或者SCene(Parent)创建 Scene。后一个构造方法中场景的尺寸将自动确定。
Node的每个子类都有一个无参的构造方法,用于创建一个默认的节点。
下面的例子中使用了HBox 面板,HBox的布局策略是将所有节点摆放在同一排。首先创建了两个Button,代码如下:
Button btOK = new Button("OK");
btOK.setPrefSize(100, 20);//将Button的宽度和高度设置为100和20
Button btCancel = new Button("Cancel");
btCancel.setPrefSize(100, 20); //将Button的宽度和高度设置为100和20
然后创建HBox对象,代码如下:
HBox hbox = new HBox(); //设置控件与 HBox 边缘之间的距离
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10); // 设置节点之间的间隔距离
hbox.setStyle("-fx-background-color: #336699;");//设置背景色
然后将两个Button添加到HBox中,代码如下:
hbox.getChildren().addAll(btOK, btCancel);
然后创建场景Scene对象,将场景对象添加到主舞台上,代码如下:
Scene scene = new Scene(hbox, 200, 250);
primaryStage.setScene(scene);
最后,显示主舞台,代码如下:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.geometry.Insets;
public class MyJavaFX extends Application {
@Override // Override the start method in the Application class
public void start(Stage primaryStage) {
// the first stage
HBox hbox = new HBox();
hbox.setPadding(new Insets(15, 12, 15, 12));
hbox.setSpacing(10);
hbox.setStyle("-fx-background-color: #336699;");
Button btOK = new Button("是");
btOK.setPrefSize(100, 20);
Button btCancel = new Button("必须是");
btCancel.setPrefSize(100, 20);
hbox.getChildren().addAll(btOK, btCancel);
Scene scene = new Scene(hbox, 200, 250);
primaryStage.setTitle("yes or no");
primaryStage.setScene(scene);
primaryStage.show();
}
}
注意,如果要编译和运行JavaFX程序,必须安装JDK 8以上的版本。
在窗口内添加一个圆
我们发现,建立了一个200*200的面板,圆的中心坐标位于100*100.
但是当我们拉伸面板的大小时,圆不再居中。------> 引入 属性绑定
Circle circle = new Circle();
circle.setCenterX(100);
circle.setCenterY(100);
circle.setRadius(50);
circle.setStroke(Color.BLUEVIOLET);
circle.setFill(Color.CYAN);
Stage stage = new Stage();
Pane pane = new Pane();
pane.getChildren().add(circle);
Scene scene2 = new Scene(pane,200,200);
stage.setTitle("A circle");
stage.setScene(scene2);
stage.show();
属性绑定
target.bind(source); // bind方法在javafx.beans.property.Property 接口中定义
Pane pane = new Pane();
Circle circle = new Circle();
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
circle.setRadius(50);
circle.setStroke(Color.BLUEVIOLET);
circle.setFill(Color.CYAN);
Stage stage = new Stage();
pane.getChildren().add(circle);
Scene scene2 = new Scene(pane,200,200);
stage.setTitle("A circle");
stage.setScene(scene2);
stage.show();
另一个绑定的小程序
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
public class BindingDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
DoubleProperty d1 = new SimpleDoubleProperty(1);
DoubleProperty d2 = new SimpleDoubleProperty(2);
d1.bind(d2);
System.out.println("dl is " + d1.getValue() +" and d2 is" + d2.getValue());
d2.setValue(70.2);
System.out.println("dl is " + d1.getValue() + " and d2 is " + d2.getValue());
}
}
DoubleProperty、FloatProperty、LongProperty、IntegerProperty以及BooleanProperty都是抽象类。它们的具体子类SimpleDoubleProperty、SimpleFloatProperty、SimpleLongProperty、SimplelntegerProperty 以及SimpleBooleanProperty 用于产生这些属性的实例