File I/O and GUI with JavaFX
文件输入/输出与JavaFX图形用户界面
一、Overview
1. File I/O
(1) learning Java File I/O mechanism
(2) writing into and reading from a file 使用文件I/O进行数据读取和写入。
2. GUI with JavaFX
(1)drawing shapes and creating graphical user interface 使用JavaFX创建图形界面,绘制形状
(2) practicing OOP with JavaFX
Learning Outcomes
• 能够开发可以通过图形表示或文本菜单与用户交互的程序。
graphical representation, or text-based menus.
• 使用Java编程表示、显示和操作数据作为对象,同时注意相关的风险/安全,确保计算和信息系统的安全操作。
being cognizant of associated risk/safety for safe operation of computing and information systems.
二、 File I/O (文件输入/输出)
1. File and File Class (文件和文件类)
(1) 程序结束时(terminates),存储在变量中的数据将丢失,因此我们需要将数据保存在文件中,并将文件存储在存储设备上(storage device)。
(2) 绝对路径(Absolute file name):操作系统(OS)相关,例如在Windows中:
C:\Users\teng.ma\Documents\NetBeansProjects\Lecture10Demo\data\text1.txt
(3) 相对路径(Relative file name): relative to the current working directory,例如:data\text1.txt
(4) 使用Java中的File对象来表示文件。
File file =new File("C:\\Users\\teng.ma\\Documents\\NetBeansProjects\\Lecture10Demo\\data\\text1.txt");
2. File Object
(1)Since OS may vary, do not use absolute file name when creating File objects
(2) Use relative file name in Java (with forward slash) :
File file = new File("data/text1.txt");
(3) creating a File object does not actually create a file on the computer!
3. File Methods (文件方法)
File类包含用于获取(obtain)文件属性的方法,以及重命名和删除文件的方法。
(1) obtain the property of a file/directory
exists(), isFile(), length(), canRead(), canWrite()
File file = new File("data/text1.txt");
file.exists();
file.isFile();
file.isDirectory();
file.isHidden();
file.length(); //in bytes
file.canRead();
file.canWrite();
file.getAbsolutePath();
(2) rename and delete a file/directory
delete(), renameTo(File), mkdir()
• exists():检查文件或目录是否存在。
• isFile():检查是否为普通文件。(不是目录)
• isDirectory():检查是否为目录。
• isHidden():检查文件或目录是否为隐藏文件。(隐藏文件用于存储系统配置或操作系统的内部文件,这些文件不应该被普通用户直接访问或修改)
• length():获取文件大小,单位为字节,如果是目录,通常返回 0 或未定义
• canRead():检查文件是否可读。
• canWrite():检查文件是否可写。
• getAbsolutePath():获取文件的绝对路径。
File file = new File("example.txt");
System.out.println("文件的绝对路径:" + file.getAbsolutePath());
• delete():删除文件或目录。(如果是目录,目录必须为空才能删除)
//如果文件或目录成功删除,返回 true;否则返回 false
file.delete()
• renameTo(File):重命名文件或移动文件。
File oldFile = new File("oldName.txt");
File newFile = new File("newName.txt");
if (oldFile.renameTo(newFile)) {
System.out.println("文件重命名成功。");
} else {
System.out.println("文件重命名失败。");
}
• mkdir():创建新目录。
File directory = new File("newDirectory");
if (directory.mkdir()) {
System.out.println("目录创建成功。");
} else {
System.out.println("目录创建失败。");
}
4. PrintWriter类用于创建文件并将数据写入文本文件(text file)
Key methods in PrintWriter
• flush() 方法的作用是强制将缓冲区中的内容立刻写入到文件。通常,PrintWriter 类会将写入的内容暂时存储在内存中的缓冲区,直到缓冲区满或者文件关闭时,才会将内容实际写入文件。
• print():写入文本,不自动换行;适用于在同一行写入多个文本内容。
• write():写入原始数据,不做格式处理;适合于写入字符、字节等低级数据。
• println(): Prints data followed by a new line.
• close(): Closes the writer and releases the associated resources.
printf(String format, Object... args):允许格式化输出。如:output.printf("Hello, %s!", "World");
PrintWriter writer = new PrintWriter("example.txt");
writer.print("Hello, ");
writer.print("world!"); //输出结果 Hello, world!
writer.flush(); // 强制将内容写入文件
writer.close(); // 关闭流
create a file
File newFile = new File("data/text2.txt");
if (newFile.exists()) {
System.out.println("File already exists!");
System.exit(0); //exit the program
}
try {
PrintWriter output = new PrintWriter(newFile);
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
write data into a text file
File file = new File("data/text1.txt");
try {
PrintWriter output = new PrintWriter(file);
output.println(“CPT111");
output.println(“is");
output.println(“so hard");
output.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
when you’re trying to create a file (e.g., text1.txt) within a folder (e.g., data), you must ensure that the folder (data) already exists.(because Java doesn’t automatically create parent directories for a file unless explicitly told to do so File folder = new File("data");)
• 在创建文件前,检查文件是否已存在,避免覆盖。(overwriting)
默认情况下,PrintWriter 在每次创建时会 覆盖 文件,这意味着 不会添加更多行,而是 替换 文件中的内容。
5. BufferedWriter to Improve Efficiency
BufferedWriter 包装 FileWriter
• BufferedWriter将字符串先缓存到内存中,再写入文件,能提高效率。
• 使用flush()方法强制将缓冲区内容(buffered content)写入文件。
在 Windows 上,\n 代表换行,但标准换行符是 \r\n,而在 Linux/macOS 上,\n 就是标准的换行符。
• buffer.newLine() 方法是为了跨平台的兼容性,它会自动根据操作系统的要求插入正确的换行符。
try {
FileWriter file = new FileWriter("data/text1.txt");
BufferedWriter buffer = new BufferedWriter(file);
buffer.write(“CPT111");
buffer.newLine();
buffer.write(“is");
buffer.newLine();
buffer.flush(); //otherwise write until buffer is full or closed
buffer.write(“so hard");
buffer.newLine();
buffer.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
• BufferedWriter 主要用于高效写入字符流,提供了一个缓冲机制,它不会自动添加换行符,除非显式调用 newLine() 方法。
• BufferedReader一次性(in one)将文件内容读取到内存中,之后可以高效地访问。
• PrintWriter 提供了更多便捷的写入方法,例如 println()、printf() 等。它不仅可以写入普通文本,还能格式化输出并自动添加换行符。
• BufferedWriter 和 PrintWriter 都需要包装一个底层 Writer(如 FileWriter)才能完成文件写入,而 FileWriter 是可以单独使用的。
PrintWriter 封装 BufferedWriter 是可以覆盖 FileWriter 的功能
6. Scanner
(1)Reading text Data Using Scanner
• 使用Scanner逐行(line by line)读取文本文件内容。
• nextLine():读取整行输入,包括空格,直到遇到换行符。
• next():读取下一个词,遇到空格或者换行符会停止。
• nextInt():读取一个整数,输入必须是合法的整数字符串。
• nextDouble():读取一个双精度浮点数。
• hasNext():检查是否有更多的输入数据(一个词)。
• hasNextInt():检查是否有下一个整数。
• hasNextDouble():检查是否有下一个双精度浮点数。
File file = new File("data/text1.txt");
try {
Scanner input = new Scanner(file);
while (input.hasNextLine()) {
String line = input.nextLine();
System.out.println(line);
}
input.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
(2)Reading csv data using Scanner
• 从CSV(comma-separated values)文件中读取数据,使用split(",")来分割(extract)每行的内容。
create a Scanner for the file, extract the values by first splitting them
File file = new File("data/cpt111.csv");
try {
Scanner input = new Scanner(file);
while (input.hasNextLine()) {
String line = input.nextLine();
String[] values = line.split(",");
String module = values[0];
int grade = Integer.parseInt(values[1]);
System.out.println(“Component: " + module + " Grade: " +
grade);
}
input.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
• split 方法: String 类中的 split 方法用于根据指定的分隔符(这里是 ",")将字符串拆分为子字符串,并返回一个字符串数组。
7. Improve efficiency using BufferedReader
File file = new File("data/text1.txt");
try {
FileReader fileReader = new FileReader(file);
BufferedReader reader = new BufferedReader(fileReader);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
• 没有修饰符的情况:在方法内部定义的局部变量(local variables)不需要修饰符。它们的生命周期仅限于方法内部。而成员变量(定义在类中的变量)通常需要修饰符来决定其访问权限。
三、GUI with JavaFX (Graphical User Interface)
1. JavaFX Basics
• JavaFX是替代Swing和AWT(Abstract Windows Toolkit)的图形用户界面框架。
JavaFX is the new GUI framework
• JavaFX的优势:支持面向对象的编程,使用Stage、Scene和Node组织图形界面。
Stage (top-level container), Scene (holds nodes), and Node (visual components:buttons, images, panes, and shapes).
Node can contain other nodes
2. JavaFX程序的基本结构
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
public class JavaFXTesting extends Application {
// 定义类 JavaFXTesting,并继承 Application 类,表明这是一个 JavaFX 应用程序。
@Override
public void start(Stage primaryStage) {
// 重写 Application 类的 start 方法。该方法是 JavaFX 应用程序的入口点,负责设置和展示 UI。
Button helloButton = new Button("Hello World!");
// 创建一个 Button 对象,并设置按钮显示的文本为 "Hello World!"。
Scene scene = new Scene(helloButton, 200, 250);
// 创建一个 Scene 对象,指定场景的根节点为按钮 helloButton,并设置场景的宽度为 200,高度为 250。
primaryStage.setTitle("My First JavaFX Program");
// 设置窗口标题为 "My First JavaFX Program"。
primaryStage.setScene(scene);
// 将场景 scene 设置为主舞台(窗口)的场景。
primaryStage.show();
// 显示主舞台,即打开窗口并展示 UI。
}
public static void main(String[] args) {
// 主方法,程序入口点。
launch(args);
// 启动 JavaFX 应用程序,会调用 start 方法。
}
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;public class JavaFXExample extends Application {
@Override
public void start(Stage primaryStage) {
// 创建按钮
Button button = new Button("Click Me");
button.setOnAction(e -> System.out.println("Button was clicked!"));// 创建场景
Scene scene = new Scene(button, 300, 200);
scene.setFill(javafx.scene.paint.Color.LIGHTBLUE);// 设置主舞台
primaryStage.setTitle("JavaFX Example");
primaryStage.setScene(scene);
primaryStage.setWidth(400);
primaryStage.setHeight(300);
primaryStage.show();
}public static void main(String[] args) {
launch(args);
}
}
当 JavaFX 应用程序调用 launch(args) 时,它会将 main 方法接收到的命令行参数传递给 launch 方法,以便 JavaFX 应用程序在初始化时使用这些参数。
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
System.out.println("Button clicked!");
}
});
e 是事件对象,类型为 ActionEvent,它表示由按钮点击产生的事件。
e -> System.out.println("Button clicked!") 是一个 Lambda 表达式,表示一个匿名函数。它是 EventHandler<ActionEvent> 接口的实现。
(1)Stage and Scene
• Stage是窗口对象,Scene包含要显示的内容。
a Stage object called primary stage is automatically created by JVM when the application is launched
• Scene通过构造函数创建,并设置宽高和节点。
Scene objects are created by Scene(node, width, height)
Panes and Group
• Pane 是一个容器,可以设置子节点的位置和大小。Place nodes inside a Pane
• Group 是一个简单的节点集合,可以将多个节点组合在一起。
Parent 提供了许多方便的方法,让管理节点变得简单:
• getChildren():获取容器内的所有子节点。
• add(Node child):向容器中添加子节点。
• remove(Node child):从容器中移除子节点。
• getBoundsInParent():获取子节点在父容器中的边界信息。
Parent 的子类(如 Pane、HBox、VBox)提供了适应不同需求的布局方式:
• VBox:让节点垂直排列。
• HBox:让节点水平排列。
• StackPane:让节点堆叠在一起。
Parent 是一种特殊的 Node,它可以包含子节点,是容器类的基类。
实心菱形:聚合关系(Composition): 表示 “整体-部分” 的强依赖关系。
• Scene 到 Parent 的实心菱形:
• Scene 是整体,而 Parent(或者具体的根节点,例如 Pane 或 Group)是它的部分。
• 这意味着一个 Scene 必须包含一个根节点(Parent 类型)。
• 如果 Scene 被销毁,它的根节点也会随之销毁。
空心菱形:关联关系(Aggregation): 表示 “整体-部分” 的弱依赖关系。
• Parent 到 Node 的空心菱形:
• Parent 是整体,Node 是它的部分。
• 一个 Parent(如 Pane 或 Group)可以包含多个 Node 子节点。
• 但是,Node 可以独立于 Parent 存在,比如创建一个 Button,不一定非要马上加入到 Parent 中。
Button in a Pane
在一个 StackPane 中放置一个按钮。
• StackPane 是一个简单的布局容器,会将子节点堆叠起来,并默认将它们放置在容器中心。
@Override
public void start(Stage primaryStage) {
// 重写 start 方法,设置 JavaFX 程序的初始内容
StackPane pane = new StackPane();
// 创建一个 StackPane 对象,用于布局子节点
pane.getChildren().add(new Button("OK"));
// 向 StackPane 中添加一个按钮,按钮的文字是 "OK"
Scene scene = new Scene(pane, 200, 50);
// 创建一个 Scene 场景对象,将 StackPane 作为根节点,设置宽度 200,高度 50
primaryStage.setTitle("Button in a Pane");
// 设置主窗口的标题为 "Button in a Pane"
primaryStage.setScene(scene);
// 将场景设置到主窗口
primaryStage.show();
// 显示主窗口
}
public static void main(String[] args) {
launch(args);
// 启动 JavaFX 应用程序,会自动调用 start 方法
}
}
Circle
在 Pane 中放置一个圆形(Circle)。
• 圆形的属性如 中心点 和 半径 可以通过方法设置。
注意:窗口大小调整后,圆形的位置不会自动调整。
public class ShowCircle extends Application {
@Override
public void start(Stage primaryStage) { // 重写 start 方法
Circle circle = new Circle(); // 创建一个 Circle 对象
circle.setCenterX(100); // 设置圆心的 X 坐标为 100
circle.setCenterY(100); // 设置圆心的 Y 坐标为 100
circle.setRadius(50); // 设置圆的半径为 50
circle.setStroke(Color.BLACK); // 设置圆的边框颜色为黑色
circle.setFill(Color.WHITE); // 设置圆的填充颜色为白色
Pane pane = new Pane(); // 创建一个 Pane 容器
pane.getChildren().add(circle); // 将圆形添加到 Pane 容器中
Scene scene = new Scene(pane, 200, 200); // 创建一个场景,将 Pane 设置为根节点,宽度和高度均为 200
primaryStage.setTitle("ShowCircle"); // 设置主窗口的标题
primaryStage.setScene(scene); // 将场景设置到主窗口
primaryStage.show(); // 显示主窗口
}
public static void main(String[] args) {
launch(args);
// 启动 JavaFX 应用程序
}
}
Java Coordinate System
Java coordinate system is measured in pixels, with (0, 0) at its upper-left corner
Property Binding to Center Circle on Resizing
• 将 Circle 的中心点(centerX 和 centerY)与容器的宽度和高度绑定。
• 当窗口大小改变时,圆形会保持居中。
public class ShowCircleCentered extends Application {
@Override
public void start(Stage primaryStage) {
Pane pane = new Pane(); // 创建一个 Pane 容器
Circle circle = new Circle(); // 创建一个 Circle 对象
circle.centerXProperty().bind(pane.widthProperty().divide(2));
// 将圆心的 X 坐标绑定到 Pane 的宽度的一半
circle.centerYProperty().bind(pane.heightProperty().divide(2));
// 将圆心的 Y 坐标绑定到 Pane 的高度的一半
circle.setRadius(50);
circle.setStroke(Color.BLACK); //设置圆的边框颜色
circle.setFill(Color.WHITE); // 设置圆的填充颜色为白色
pane.getChildren().add(circle); // 将圆形添加到 Pane 容器中
Scene scene = new Scene(pane, 200, 200); //创建一个场景,将 Pane 设置为根节点
primaryStage.setTitle("ShowCircleCentered"); // 设置主窗口的标题
primaryStage.setScene(scene); // 将场景设置到主窗口
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
// 启动 JavaFX 应用程序
}
}
Color
Color 类用于创建和管理颜色。
• 颜色可以通过 RGBA(红、绿、蓝、透明度)模型或预定义的标准颜色常量表示。
RGBA 模型:
• R(红色),G(绿色),B(蓝色):from 0.0 (darkest) to 1.0 (lightest)
• A(透明度):0.0 完全透明,1.0 完全不透明。
• 示例:Color color = new Color(0.25, 0.14, 0.333, 0.51);
标准颜色常量:
• Color 类提供了一些预定义的常量,例如 RED, GREEN, BLUE 等。
• 使用示例:circle.setFill(Color.RED);
Font, Label and StackPane
Font is defined by its name, weight, posture, and size; and is set on a Label object
A StackPane object is used to contain a circle and a label
// 创建 StackPane 容器
Pane pane = new StackPane();
// 创建圆形并设置属性
Circle circle = new Circle();
circle.setRadius(50); // 圆的半径为 50
circle.setStroke(Color.BLACK); // 边框颜色为黑色
circle.setFill(new Color(0.5, 0.5, 0.5, 0.1)); // 填充颜色为灰色(带透明度)
pane.getChildren().add(circle); // 将圆形添加到 StackPane 中
// 创建标签并设置属性
Label label = new Label("JavaFX");
label.setFont(Font.font("Times New Roman", FontWeight.BOLD, FontPosture.ITALIC, 20));
// 设置字体为 Times New Roman,粗体,斜体,大小为 20
pane.getChildren().add(label); // 将标签添加到 StackPane 中
// 创建场景并设置到舞台
Scene scene = new Scene(pane);
primaryStage.setTitle("FontDemo"); // 设置窗口标题
primaryStage.setScene(scene); // 将场景设置到舞台
primaryStage.show(); // 显示窗口
Font:
• 字体可以通过名称(如 "Times New Roman")、粗细(FontWeight)、样式(FontPosture)和大小来定义。
• 使用 Font.font() 方法设置字体。
Label:
• Label 是一种控件,用于显示文本内容。
• 可以通过 setFont() 方法设置字体样式。
Image and ImageView
Image class loads an image; ImageView is a node for displaying image
An HBox is a pane that places all nodes horizontally in one row
1. Image 类:
• 用于加载图像文件。
• 示例:Image image = new Image("path/to/image.jpg");
2. ImageView 类:
• 用于显示 Image 对象。
• 提供属性设置:
• setFitWidth() 和 setFitHeight():设置图像显示的宽度和高度。
• setRotate():设置图像的旋转角度。
3. HBox 布局:
• HBox 是一个布局容器,将所有子节点水平排列。
// 创建 HBox 容器并设置边距
Pane pane = new HBox(10); // HBox 容器,子节点间距为 10
pane.setPadding(new Insets(5, 5, 5, 5)); // 设置容器的边距
// 加载图像
Image image = new Image("image/us.gif");
// 添加原始图像
pane.getChildren().add(new ImageView(image));
// 设置大小后添加图像
ImageView imageView2 = new ImageView(image);
imageView2.setFitHeight(100); // 设置图像高度
imageView2.setFitWidth(100); // 设置图像宽度
pane.getChildren().add(imageView2);
// 设置旋转后添加图像
ImageView imageView3 = new ImageView(image);
imageView3.setRotate(90); // 设置图像旋转 90 度
pane.getChildren().add(imageView3);
// 创建场景并显示
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowImage"); // 设置窗口标题
primaryStage.setScene(scene); // 设置场景
primaryStage.show(); // 显示窗口
Layout Panes
Pane 类:提供 getChildren() 方法来管理子节点。
Shapes
Shapes 是 JavaFX 中用于绘制图形的节点:
• 包括:Text(文本)、Line(线条)、Rectangle(矩形)、Circle(圆形)、Ellipse(椭圆)、Arc(弧形)、Polygon(多边形)、Polyline(折线)
fill:
• 设置形状内部的填充颜色。interior of a shape
• 示例:circle.setFill(Color.RED);
stroke:
• 设置形状边框的颜色。outline of a shape
• 示例:rectangle.setStroke(Color.BLACK);
strokeWidth:
• 设置边框的宽度。
• 示例:line.setStrokeWidth(2);
(1) Text
Text 类用于在指定的起始位置 (x, y) 绘制字符串:
• 可以设置字体、颜色、下划线、删除线等样式。
• Text 是 Shape 的一个子类。
// 创建 Pane 容器并设置内边距
Pane pane = new Pane();
pane.setPadding(new Insets(5, 5, 5, 5));
// 添加第一个文本节点
Text text1 = new Text(20, 20, "Programming is fun"); // 起点 (20, 20)
text1.setFont(Font.font("Courier", FontWeight.BOLD, FontPosture.ITALIC, 15)); // 设置字体
pane.getChildren().add(text1);
// 添加第二个文本节点
Text text2 = new Text(60, 60, "Programming is fun\nDisplay text"); // 包含换行符
pane.getChildren().add(text2);
// 添加第三个文本节点,并设置更多样式
Text text3 = new Text(10, 100, "Programming is fun\nDisplay text");
text3.setFill(Color.RED); // 设置填充颜色
text3.setUnderline(true); // 设置下划线
text3.setStrikethrough(true); // 设置删除线
pane.getChildren().add(text3);
// 创建场景并设置到舞台
Scene scene = new Scene(pane);
primaryStage.setTitle("ShowText"); // 设置窗口标题
primaryStage.setScene(scene);
primaryStage.show(); // 显示窗口
(2) Line
Line 类用于绘制一条连接两点 (startX, startY) 和 (endX, endY) 的直线:
• 提供属性绑定功能,可根据容器的宽高动态调整。
public class ShowLine extends Application {
@Override
public void start(Stage primaryStage) {
// 创建场景并设置到舞台
Scene scene = new Scene(new LinePane(), 200, 200); // 使用自定义 Pane
primaryStage.setTitle("ShowLine");
primaryStage.setScene(scene);
primaryStage.show();
}
}
// 自定义 Pane 类,绘制两条对角线
class LinePane extends Pane {
public LinePane() {
// 第一条线
Line line1 = new Line(10, 10, 10, 10); // 起点和终点初始相同
line1.endXProperty().bind(widthProperty().subtract(10)); // 动态绑定宽度
line1.endYProperty().bind(heightProperty().subtract(10)); // 动态绑定高度
line1.setStrokeWidth(5); // 设置边框宽度
line1.setStroke(Color.GREEN); // 设置颜色
getChildren().add(line1);
// 第二条线
Line line2 = new Line(10, 10, 10, 10);
line2.startXProperty().bind(widthProperty().subtract(10)); // 动态绑定起点宽度
line2.endYProperty().bind(heightProperty().subtract(10)); // 动态绑定终点高度
line2.setStrokeWidth(5);
line2.setStroke(Color.GREEN);
getChildren().add(line2);
}
}
(3)Rectangle
Rectangle 类用于绘制矩形:
• 提供属性:x, y(左上角坐标),width(宽度),height(高度),arcWidth(圆角宽度),arcHeight(圆角高度)。
// 创建矩形并设置属性
Rectangle r1 = new Rectangle(25, 10, 60, 30); // 左上角 (25, 10),宽 60,高 30
r1.setStroke(Color.BLACK); // 设置边框颜色
r1.setFill(Color.WHITE); // 设置填充颜色
Rectangle r2 = new Rectangle(25, 50, 60, 30); // 第二个矩形
Rectangle r3 = new Rectangle(25, 90, 60, 30);
r3.setArcWidth(15); // 设置圆角宽度
r3.setArcHeight(25); // 设置圆角高度
// 创建组容器并添加节点
Group group = new Group();
group.getChildren().addAll(new Text(10, 27, "r1"), r1,
new Text(10, 67, "r2"), r2,
new Text(10, 107, "r3"), r3);
// 动态生成旋转的矩形
for (int i = 0; i < 4; i++) {
Rectangle r = new Rectangle(100, 50, 100, 30);
r.setRotate(i * 360 / 8); // 设置旋转角度
r.setStroke(Color.color(Math.random(), Math.random(), Math.random())); // 随机颜色
r.setFill(Color.WHITE); // 设置填充颜色
group.getChildren().add(r);
}
// 创建场景并设置到舞台
Scene scene = new Scene(new BorderPane(group), 250, 150);
primaryStage.setScene(scene);
primaryStage.setTitle("ShowRectangle");
primaryStage.show();
line1.endXProperty().bind(widthProperty().subtract(10));
• endXProperty() 方法:
• 是 Line 类的一个方法,用于获取该直线的终点 X 坐标属性。
• 返回值是一个 DoubleProperty,可以进行动态绑定。
• bind() 方法:
• 是 Property 接口中的方法,用于将一个属性绑定到另一个属性。
• 绑定效果:
• 如果被绑定的属性发生变化(例如容器宽度变了),当前属性会自动更新。
• widthProperty() 方法:
• 是 Pane 类的一个方法,返回容器的宽度属性。
• 通过绑定 widthProperty(),可以使线段的终点 X 坐标随容器宽度动态变化。
• subtract(10) 方法:
• 是 NumberExpression 类中的方法,用于对数值表达式进行计算。
• widthProperty().subtract(10) 表示容器宽度减去 10 像素。
Scene scene = new Scene(new BorderPane(group), 250, 150);
• new BorderPane(group):
• 创建了一个 BorderPane 对象,并将 Group 设置为其中心区域的内容
pane.setPadding(new Insets(5, 5, 5, 5));
• setPadding() 方法:
• 是 Pane 类 提供的方法,用于设置容器的内边距(Padding)。
• 内边距是指容器的边框与内部子节点之间的距离。
• Insets 类:
• Insets(double top, double right, double bottom, double left):
• 构造方法,用于分别指定容器四个方向的边距值。