第十四章 JavaFX基础
14.1 引言
14.2 JavaFX 与 Swing 以及 AWT 的比较
Java的图形用户界面(GUI)的演变过程从AWT(Abstract Windows Toolkit),到Swing,再到JavaFX
14.3 JavaFX 程序的基本结构
// 书中的例子分析
package com.example.demo;
// 抽象类Application是JavaFX程序的基类,用于创建和管理JavaFX应用程序的整体结构和生命周期
import javafx.application.Application;
// Stage类是JavaFX中表示应用程序窗口的顶级容器。每个JavaFX应用程序都需要至少一个Stage对象来作为应用程序的主窗口
import javafx.stage.Stage;
// Scene类是JavaFX中用于表示应用程序窗口或场景的类。它是JavaFX场景图的容器,包含了应用程序中所有可见的UI元素
import javafx.scene.Scene;
// Button类是JavaFX中用于创建按钮的类
import javafx.scene.control.Button;
// 要创建一个JavaFX应用程序,首先需要定义一个继承自抽象类Application的子类
public class Test extends Application {
@Override
// start()方法是抽象类Application中的抽象方法,必须覆写,它是JavaFX应用程序的主要入口点,会在应用程序启动后立即被调用,一般用于将UI组件放人一个场景Scene,并且在舞台Stage中显示该场景
public void start(Stage primaryStage) {
// 创建按钮Button实例
Button btOK = new Button("OK");
// 创建场景Scene实例,第一个参数是Node节点,默认居中
// 可以将Control.Button直接放在Scene中,因为他们都是Parent的父类,详情看下一节
Scene scene = new Scene(btOK, 200, 250);
// 定义标题
primaryStage.setTitle("MyJavaFX");
// 把Scene实例放入舞台Stage
primaryStage.setScene(scene);
// 显示舞台
primaryStage.show();
}
// main方法可有可无,JVM会自动调用
public static void main(String[] args) {
launch(args);
}
}
14.4 面板、Ul组件以及形状
节点Node是一个可视化组件,包括形状Shape,图像视图ImageView,UI组件Control(Button就是Control的子类),面板Pane。
上一节我们直接将想要的节点Button添加到Scene中
这一节我们将节点Button添加到面板Pane,再把Pane添加到Scene中
类型是Shape和ImageView的节点,不可以直接放到Scene中,看图,Shape类型的Node,需要先进去Pane,然后到Parent,最后Scene
类型是Control和Pane的节点,可以直接放到Scene中,看图,Control先放到Parent,然后直接Scene
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
// 面板Pane是一个基本的布局容器,它允许你自由地放置子节点,并且不对子节点的位置和大小进行任何限制
import javafx.scene.layout.Pane;
// Color类是JavaFX中用于表示颜色的类。它提供了各种静态方法和属性,用于创建和操作颜色对象
import javafx.scene.paint.Color;
// Circle类是JavaFX中用于绘制圆形的类。它是Shape类的子类
import javafx.scene.shape.Circle;
public class ShowCircle extends Application {
@Override
public void start(Stage primaryStage) {
// 创建一个圆的实例
Circle circle = new Circle();
// 设置圆心
circle.setCenterX(100);
circle.setCenterY(100);
// 设置半径
circle.setRadius(50);
// 设置笔画颜色
circle.setStroke(Color.BLACK);
// 设置填充颜色
circle.setFill(Color.WHITE);
// 创建一个面板Pane的实例,默认左上角对齐,也就是说,如果不设置圆心,圆会以(0,0)为圆心创建,不会居中
Pane pane = new Pane();
// 在面板中添加节点。getChildren()返回一个类似于ArrayList的ObservableList列表,add方法把Circle节点加入该列表
// 不可以把Shape.Circle直接放在Scene场景中,需要先放到面板中,详情看上图
pane.getChildren().add(circle);
Scene scene = new Scene(pane, 200, 200);
primaryStage.setTitle("ShowCircle");
primaryStage.setScene(scene);
primaryStage.show();
}
}
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
// 面板StackPane是特殊的Pane,它按照层叠的方式排列子节点。StackPane将子节点堆叠在一起,使得后添加的节点显示在前面的节点上方。它提供了默认的布局行为,可以自动调整子节点的位置和大小,以实现层叠效果
import javafx.scene.layout.StackPane;
import javafx.scene.control.Button;
public class ButtonInPane extends Application {
@Override
public void start(Stage primaryStage) {
// 创建一个面板实例,默认节点居中对齐,如果把上一个代码中的圆用StackPane面板创建,就会自动居中对齐
StackPane pane = new StackPane();
pane.getChildren().add(new Button("OK"));
Scene scene = new Scene(pane, 200, 50);
primaryStage.setTitle("Button in a pane");
primaryStage.setScene(scene);
// 一个按钮置于面板的中央
primaryStage.show();
}
}
14.5 属性绑定
// 上一节中讲到,如果更改Scene的大小,Circle的圆心是不会居中的,下面的这行代码,讲述了属性绑定:无论场景Scene大小如何改变,圆始终居中
package com.example.demo;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class ShowCircleCentered extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane();
Circle circle = new Circle();
// 这里使用了target.bind(source)方法进行了绑定,如果pane的大小发生了变化,circle的圆心也会发生变化
// 需要注意的是,bind方法是Property接口的默认方法,代码没有实现Property接口,是因为,circle.centerXProperty()返回了一个DoubleProperty类的对象,这个类实现了Property接口,因此,我们的类就不需要实现该接口
circle.centerXProperty().bind(pane.widthProperty().divide(2));
circle.centerYProperty().bind(pane.heightProperty().divide(2));
circle.setRadius(50);
circle.setStroke(Color.BLACK);
circle.setFill(Color.WHITE);
pane.getChildren().add(circle);
Scene scene = new Scene(pane, 200, 200);
primaryStage.setTitle("ShowCircleCentered");
primaryStage.setScene(scene);
primaryStage.show();
}
}
// 下面的代码示范了单向绑定,当源对象发生改变,目标对象会随之变化,但是目标对象改变,源对象不会变化
DoubleProperty source = new SimpleDoubleProperty(5);
DoubleProperty bound = new SimpleDoubleProperty();
bound.bind(source);
System.out.println("source: " + source.get()); // 输出: source: 5.0
System.out.println("bound: " + bound.get()); // 输出: bound: 5.0
source.set(10);
System.out.println("source: " + source.get()); // 输出: source: 10.0
System.out.println("bound: " + bound.get()); // 输出: bound: 10.0
// 在单向绑定中,尝试直接修改绑定对象(目标对象)的值会导致异常抛出
bound.set(20);
System.out.println("source: " + source.get());
System.out.println("bound: " + bound.get());
// // 下面的代码示范了双向绑定,当源对象发生改变,目标对象会随之变化,目标对象改变,源对象也会变化
DoubleProperty prop1 = new SimpleDoubleProperty(5);
DoubleProperty prop2 = new SimpleDoubleProperty(10);
prop1.bindBidirectional(prop2);
System.out.println("prop1: " + prop1.get()); // 输出: prop1: 10.0
System.out.println("prop2: " + prop2.get()); // 输出: prop2: 10.0
prop1.set(20);
System.out.println("prop1: " + prop1.get()); // 输出: prop1: 20.0
System.out.println("prop2: " + prop2.get()); // 输出: prop2: 20.0
prop2.set(30);
System.out.println("prop1: " + prop1.get()); // 输出: prop1: 30.0
System.out.println("prop2: " + prop2.get()); // 输出: prop2: 30.0
14.6 节点的通用属性和方法
节点可以设置颜色等属性,应用旋转等方法
14.7 Color 类
JavaFX定义了抽象类Paint用于绘制节点。Javafx.scene.paint.Color是Paint的具体子类,Color类是不可修改的
有3种办法构造颜色
- 调用构造方法
Color color = new Color(0.25, 0.14, 0.333, 0.51);
- 调用静态方法
color(r, g, b);
- 调用标准颜色
circle.setFill(Color.RED);
14.8 Font类
javafx.scene.text.Font类描述字体名、粗细和大小,Font 对象是不可改变的
14.9 Image和ImageView类
Image 类创建一个图像实例,参数可以是文件路径或完整的URL(带http://)
ImageView 类可以用于显示一个图像,参数可以是Image对象或文件路径或完整的URL
Image 对象可以被多个节点共享,也就是1张图片可以被多次使用
但是ImageView 对象是不可以共享的,不能将一个ImageView 多次放入一个面板或者场景中
14.10 布局面板
JavaFX提供了多种类型的面板,用于自动地将节点布局在希望的位置和大小。
14.11 形状
Shape类是一个抽象基类,定义了所有形状的共同属性。这些属性有fill、stroke、strokeWidth。
fill属性指定一个填充形状内部区域的颜色、Stroke属性指定用于绘制形状边缘的颜色、strokeWidth属性指定形状边缘的宽度。
14.12 示例学习
使用JavaFX制作了时钟
14.13 总结javafx包结构
javafx
└─ application
└─ Application.java
└─ beans
└─ property
└─ DoubleProperty.java
└─ SimpleDoubleProperty.java
└─ collections
└─ ObservableList.java
└─ geometry
└─ HPos.java
└─ Insets.java
└─ Pos.java
└─ scene
└─ chart
└─ BarChart
└─ CategoryAxis.java
└─ PieChart.java
└─ NumberAxis.java
└─ XYChart.java
└─ control
└─ Button.java
└─ Label.java
└─ TextField.java
└─ Group.java
└─ image
└─ Image.java
└─ ImageView.java
└─ layout
└─ BorderPane.java
└─ ColumnConstraints.java
└─ FlowPane.java
└─ GridPane.java
└─ HBox.java
└─ Pane.java
└─ RowConstraints.java
└─ StackPane.java
└─ VBox.java
└─ paint
└─ Color.java
└─ Scene.java
└─ shape
└─ Arc.java
└─ ArcType.java
└─ Circle.java
└─ Ellipse.java
└─ Line.java
└─ Polygon.java
└─ Polyline.java
└─ Rectangle.java
└─ text
└─ Text.java
└─ Font.java
└─ FontWeight.java
└─ FontPosture.java
└─ stage
└─ Stage.java