java基础:14.1 Java FX与属性绑定

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/L20902/article/details/86509716

图形用户界面(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 用于产生这些属性的实例

猜你喜欢

转载自blog.csdn.net/L20902/article/details/86509716