javafx
JavaFX
JavaFX简介
JavaFX是一个用于创建富客户端应用程序的图形用户界面(GUI)框架。它是Java平台的一部分,从Java 8开始成为Java的标准库。
JavaFX提供了丰富的图形和多媒体功能,使开发人员能够创建具有吸引力和交互性的应用程序。它支持各种UI控件、布局和样式,以及动画、图形渲染和多媒体处理等功能。
以下是一些JavaFX的主要特点和功能:
-
UI控件:JavaFX提供了一系列内置的UI控件,如按钮、标签、文本框、列表、表格等,以及自定义控件的能力。
-
布局:JavaFX支持多种布局管理器,如栈布局(StackPane)、流布局(FlowPane)、网格布局(GridPane)等,以便开发人员可以轻松地设计和排列应用程序的界面。
-
样式和主题:JavaFX使用CSS来定义应用程序的样式和外观。开发人员可以通过CSS样式表来自定义控件的外观,从而实现更好的界面设计。
-
动画和过渡效果:JavaFX提供了强大的动画和过渡效果支持,可以实现平滑的界面过渡、元素的渐变、旋转、缩放等效果,增强用户体验。
-
多媒体支持:JavaFX支持音频和视频播放、图像处理和渲染等多媒体功能,可以创建具有丰富多媒体内容的应用程序。
-
事件处理:JavaFX提供了事件模型和事件处理机制,开发人员可以通过监听和处理事件来实现应用程序的交互性。
-
场景图和渲染引擎:JavaFX使用场景图(scene graph)作为UI的基础结构,通过渲染引擎将场景图渲染到屏幕上。
JavaFX可以与Java语言无缝集成,可以使用Java代码或FXML(一种基于XML的语言)来创建界面。它还提供了丰富的API和工具,以支持开发人员构建跨平台的富客户端应用程序。
需要注意的是,从Java 11开始,JavaFX不再是Java标准库的一部分,而是作为一个独立的模块进行开发和发布。因此,如果您使用的是Java 11及更高版本,您需要单独下载和安装JavaFX,并将其添加到您的项目中。
Maven JavaFX 项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.lihaozhe</groupId><artifactId>demo01</artifactId><version>1.0.0</version><description>JavaFX mvn project</description><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><junit.version>5.10.0</junit.version></properties><dependencies><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>${junit.version}</version><scope>test</scope></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-engine</artifactId><version>${junit.version}</version><scope>test</scope></dependency><dependency><groupId>org.openjfx</groupId><artifactId>javafx-controls</artifactId><version>17.0.8</version></dependency><dependency><groupId>org.openjfx</groupId><artifactId>javafx-fxml</artifactId><version>17.0.8</version></dependency><dependency><groupId>org.openjfx</groupId><artifactId>javafx-graphics</artifactId><version>17.0.8</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.11.0</version><configuration><source>17</source><target>17</target></configuration></plugin><plugin><groupId>org.openjfx</groupId><artifactId>javafx-maven-plugin</artifactId><version>0.0.8</version><executions><execution><!-- Default configuration for running with: mvn clean javafx:run --><id>default-cli</id><configuration><!-- 主窗口启动类为 com.lihaozhe.App --><mainClass>com.lihaozhe.App</mainClass><launcher>app</launcher><jlinkZipName>app</jlinkZipName><jlinkImageName>app</jlinkImageName><noManPages>true</noManPages><stripDebug>true</stripDebug><noHeaderFiles>true</noHeaderFiles></configuration></execution></executions></plugin></plugins></build>
</project>
主窗口启动类
com.lihaozhe.App01
package com.lihaozhe;import javafx.application.Application;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description 主敞口启动类* @create 2023/9/3*/
public class App01 extends Application {/*** @param stage 主窗口* @throws Exception IO异常*/@Overridepublic void start(Stage stage) throws Exception {// 设置主窗口标题stage.setTitle("我爱你中国");// 显示窗口stage.show();}public static void main(String[] args) {// 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法launch(args);}
}
注意,此时直接启动会出现如下报错:
错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序
导入JavaFX模块
从Java 11开始,JavaFX不再是Java标准库的一部分,而是作为一个独立的模块进行开发和发布。
因此,如果您使用的是Java 11及更高版本,您需要单独下载和安装JavaFX,并将其添加到您的项目中
src/main/java/module-info.java
module com.lihaozhe {requires javafx.controls;requires javafx.fxml;opens com.lihaozhe to javafx.fxml;exports com.lihaozhe;
}
运行主窗口类
JavaFX基本结构
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description 主敞口启动类* @create 2023/9/3*/
public class App01 extends Application {/*** @param stage 主窗口* @throws Exception IO异常*/@Overridepublic void start(Stage stage) throws Exception {// 设置主窗口标题stage.setTitle("我爱你中国");// Label 标签Label label = new Label("我爱你中国,亲爱的母亲!");// BorderPane 边框布局 将编写好的标签 放在边框布局中 默认标签居中显示// 常见的布局如下:// BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane// BorderPane 提供了5个放置节点的区域:top, bottom, left, right, 和 center// HBox 横的一个一个摆// VBox 竖的一个一个摆// StackPane 新放的东西会覆盖原来的东西// GridPane 一格一格的放,可以设置行和列// FlowPane 会一行一行的摆,放不下就拐到下一行// SplitPane 能用鼠标拖动的面板// Accordion 可以翻的页面// TabPane 一个一个的标签// AnchorPane我们可以看到,每个页面里面都有AnchorPane,// 意思就跟随外面的移动,外面的往左,里面的就往左,外面的往右,里面的就往右BorderPane borderPane = new BorderPane(label);// Scene 场景 将编写好的布局 放在场景中Scene scene = new Scene(borderPane, 600, 600);// 将场景放在主窗口内stage.setScene(scene);// 显示窗口stage.show();}public static void main(String[] args) {// 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法launch(args);}
}
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description 主敞口启动类* @create 2023/9/3*/
public class App02 extends Application {/*** @param stage 主窗口* @throws Exception IO异常*/@Overridepublic void start(Stage stage) throws Exception {// 设置主窗口标题stage.setTitle("我爱你中国");// Button 按钮Button button = new Button("你过来呀");// 按钮点击事件button.setOnAction(event -> {// 通过系统默认浏览器打开指定的网页getHostServices().showDocument("https://blog.csdn.net/qq_24330181");getHostServices().showDocument("https://space.bilibili.com/480308139");});// BorderPane 边框布局 将编写好的标签 放在边框布局中 默认标签居中显示// 常见的布局如下:// BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane// BorderPane 提供了5个放置节点的区域:top, bottom, left, right, 和 center// HBox 横的一个一个摆// VBox 竖的一个一个摆// StackPane 新放的东西会覆盖原来的东西// GridPane 一格一格的放,可以设置行和列// FlowPane 会一行一行的摆,放不下就拐到下一行// SplitPane 能用鼠标拖动的面板// Accordion 可以翻的页面// TabPane 一个一个的标签// AnchorPane我们可以看到,每个页面里面都有AnchorPane,// 意思就跟随外面的移动,外面的往左,里面的就往左,外面的往右,里面的就往右BorderPane borderPane = new BorderPane(button);// Scene 场景 将编写好的布局 放在场景中Scene scene = new Scene(borderPane, 600, 600);// 将场景放在主窗口内stage.setScene(scene);// 显示窗口stage.show();}public static void main(String[] args) {// 父类中继承过来的静态方法启动 launch 方法会自动调用 start 方法launch(args);}
}
BorderPane、StackPane、GridPane、FlowPane、SplitPane、TabPane、AnchorPane
Application简介
要创建JavaFX应用程序,您需要遵循以下步骤:
-
设置开发环境:安装Java开发工具包(JDK)和支持JavaFX开发的集成开发环境(IDE),如Eclipse、IntelliJ IDEA或NetBeans。
-
创建一个新的JavaFX项目:打开您的IDE并创建新的JavaFXProject。这将建立必要的项目结构和依赖关系。
-
创建主应用程序类:在项目内部,创建一个扩展
javafx.application.application
类的新类。这个类将作为JavaFX应用程序的入口点。 -
重写
start
方法:在您的主应用程序类中,重写start
方法。此方法用于定义应用程序的初始UI布局和行为。 -
创建主阶段(primary stage)和场景(scene):在
start
方法中,创建一个新的javafx.stage.stage
对象,该对象表示应用程序的主窗口。然后,创建一个javafx.scene.scene
对象,并将其设置为舞台的场景。 -
设计UI:在场景内部,您可以使用JavaFX的内置UI控件或通过创建自定义控件来添加各种UI控件和元素。可以使用不同的布局管理器来排列场景中的控件。
-
添加事件处理:实现事件处理程序来处理用户与UI控件的交互。您可以使用
setOnAction
方法或其他适当的方法将事件处理程序附加到控件。 -
启动应用程序:在您的主方法或单独的启动器类中,调用
application.slaunch
方法来启动JavaFX应用程序。这将调用主应用程序类的start
方法。 -
构建并运行应用程序:构建您的项目并运行该应用程序。您应该看到JavaFX应用程序窗口,其中包含已定义的UI和行为。
以下是一个显示Hello,JavaFX!
标签的JavaFX应用程序的简单示例:
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class HelloWorldApp extends Application {@Overridepublic void start(Stage primaryStage) {Label label = new Label("Hello, JavaFX!");StackPane root = new StackPane();root.getChildren().add(label);Scene scene = new Scene(root, 300, 200);primaryStage.setTitle("Hello World");primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);}
}
这是一个基本示例,但您可以通过添加更多的UI控件、事件处理和其他功能来扩展它,以创建更复杂的JavaFX应用程序。
Stage
在JavaFX中,stage 表示JavaFX应用程序中的顶级窗口。它是javafx.stage.stage
类的一个实例,用作一个或多个场景的容器。
要在JavaFX中创建和使用阶段,请执行以下步骤:
-
创建一个stage对象:您可以使用
javafx.stage.stage
类创建一个新的stage对象。通常,您在javafx.application.application
子类的 start() 方法中创建一个stage对象。 -
设置场景:要在舞台内部显示内容,需要设置场景。场景表示将在舞台内显示的内容。使用舞台对象的
setScene()
方法设置场景。 -
.设置标题:您可以使用
setTitle()
方法为舞台设置标题。标题将显示在窗口的标题栏中。 -
设置其他属性:您可以设置后台文件的各种属性,如大小、可调整大小的行为和可见性。使用“Stage”类提供的适当方法,如
setWidth()
,setHeight()
,setResizable()
和show()
。 -
处理阶段事件:您可以注册事件处理程序来处理与阶段相关的事件,例如当它显示、隐藏或关闭时。使用
setOn...()
方法,如setOnShown()
、setOnHidden()
和setOnCloseRequest()
,将事件处理程序附加到阶段。以下是一个示例,演示如何在JavaFX中创建和使用阶段:
package com.lihaozhe;import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;import java.util.Optional;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class StageExample extends Application {@Overridepublic void start(Stage primaryStage) {// Button 按钮Button button = new Button("你过来呀");BorderPane root = new BorderPane(button);// Create a scene with the root nodeScene scene = new Scene(root, 400, 300);// Set the scene for the stageprimaryStage.setScene(scene);// Set the title of the stageprimaryStage.setTitle("JavaFX Stage Example");// width,height,用于设置窗口大小primaryStage.setWidth(800);primaryStage.setHeight(600);// resizable,是否允许改变窗口大小primaryStage.setResizable(true);// x,y,用于设置窗口在桌面上显示的位置primaryStage.setX(100);primaryStage.setY(100);// 用户设置窗口的样式// 我们可以通过枚举类选择窗口样式,默认的窗口样式为“DECORATED”// 枚举类StageStyle有以下样式:// DECORATED 用纯白背景和平台装饰定义一个普通的窗口样式// UNDECORATED 定义一个窗口样式,背景为纯白,没有任何装饰// 当我们没有为Stage设置Sence时,我们在桌面上将看不到任何东西// 当我们有为Stage设置Sence时,可以看到,该窗口样式的最大特点就是,我们看不到标题、图表、隐藏按钮,全屏按钮、关闭按钮那一栏// TRANSPARENT 定义具有透明背景且没有装饰的窗口样式// UTILITY 定义具有纯白背景和用于实用程序窗口的最小平台装饰的样式// UNIFIED 使用平台装饰定义窗口样式,并消除客户端区域和装饰之间的边界。客户区背景与装修统一primaryStage.initStyle(StageStyle.DECORATED);// primaryStage.initModality(Modality.WINDOW_MODAL);// 设置窗口的图标// primaryStage.getIcons().add(new Image("https://img1.baidu.com/it/u=2865456449,2930074044&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"));// primaryStage.getIcons().add(new Image("file:///D:\\dev\\java\\code\\javafx\\demo01\\src\\main\\resources\\icon\\java02.png"));// 获取图标文件类路径String path = this.getClass().getResource("/icon/java02.png").getPath();// 设置协议String protocol = "file://";primaryStage.getIcons().add(new Image(protocol + path));// 按钮点击事件button.setOnAction(event -> {Stage stage = new Stage();stage.setTitle("自强不息");stage.setWidth(400);stage.setHeight(300);// 将主窗口设置为父窗口stage.initOwner(primaryStage);// Modality 模态框// NONE// WINDOW_MODAL 需要父窗口 只有父窗口不可用其它窗口可用// APPLICATION_MODAL 应用模态 只有本窗口可用其它窗口不可用stage.initModality(Modality.WINDOW_MODAL);stage.show();});// Show the stageprimaryStage.show();// 取消系统默认退出Platform.setImplicitExit(false);// Register an event handler for the close request eventprimaryStage.setOnCloseRequest(event -> {System.out.println("Closing the stage...");// 取消系统默认关闭窗口event.consume();Alert alert = new Alert(Alert.AlertType.CONFIRMATION);alert.setTitle("退出程序");alert.setHeaderText(null);alert.setContentText("是否退出程序");Optional<ButtonType> result = alert.showAndWait();if (result.get() == ButtonType.OK) {// 关闭窗口primaryStage.close();// 退出程序Platform.exit();}});}public static void main(String[] args) {launch(args);}
}
在本例中,我们使用 stage 类创建一个舞台对象,并设置一个带有标签的场景作为舞台的内容。我们设置了舞台的标题、大小和可调整大小的行为。最后,我们展示阶段并为关闭请求事件注册一个事件处理程序。
您可以通过设置舞台图标、应用CSS样式或添加动画和效果来进一步自定义舞台。
Secne
在JavaFX中,Secne 表示显示在JavaFX应用程序的窗口(阶段)内的内容。它充当组成应用程序用户界面的所有视觉元素(节点)的容器。
要在JavaFX中创建场景,需要执行以下步骤:
-
创建根节点:根节点是作为场景中所有其他节点的父节点的顶级节点。它可以是
javafx.scene.Parent
类的任何子类,如javafx.secene.layout.Pane
或javafx-secene.layout.GridPane
。您可以将子节点添加到根节点以定义场景的布局和结构。 -
创建场景对象:使用
javafx.scene.scene
类创建新的场景对象。将根节点以及所需的场景宽度和高度作为参数传递给构造函数。 -
为 Stage 设置场景:要在窗口中显示场景,需要将其设置为
javafx.stage.stage
对象的场景。该阶段代表JavaFX的主窗口 -
显示stage:最后,调用stage对象上的 Show() 方法使其可见。这将在窗口内显示场景及其内容。
下面是一个示例,演示如何创建一个带有标签的简单JavaFX场景:
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class SceneExample extends Application {@Overridepublic void start(Stage primaryStage) {// 设置主窗口标题primaryStage.setTitle("我爱你中国");Button button0 = new Button("进入场景1");Button button1 = new Button("进入场景0");BorderPane borderPane0 = new BorderPane(button0);BorderPane borderPane1 = new BorderPane(button1);int width = 800;int height = 600;Scene scene0 = new Scene(borderPane0, width, height);Scene scene1 = new Scene(borderPane1, width, height);// 将场景放在主窗口内primaryStage.setScene(scene0);// 显示窗口primaryStage.show();button0.setOnAction(event -> primaryStage.setScene(scene1));button1.setOnAction(event -> primaryStage.setScene(scene0));}public static void main(String[] args) {launch(args);}
}
在本例中,我们创建一个 StackPane 作为根节点,并向其添加一个 Label 。然后,我们使用根节点创建一个场景,并将其设置为舞台的场景。最后,我们设置了舞台的标题并展示出来。
您可以通过设置场景的背景颜色、添加CSS样式或将动画和效果应用于场景中的节点来进一步自定义场景。
Node通用UI属性
package com.lihaozhe;import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class NodeExample extends Application {@Overridepublic void start(Stage primaryStage) {Label label = new Label("Hello, JavaFX!");// 样式StringBuilder style = new StringBuilder();style.append("-fx-background-color: #FF0000;");style.append("-fx-border-color: #00FF00;");style.append("-fx-border-image-width: 3px;");label.setStyle(style.toString());// 宽度label.setPrefWidth(100);// 高度label.setPrefHeight(50);// 透明度 取值范围 0 到 1label.setOpacity(0.5);// 角度label.setRotate(30);// 内容居中显示label.setAlignment(Pos.CENTER);// 平移label.setTranslateX(50);label.setTranslateY(50);// 位置label.setLayoutX(50);label.setLayoutY(50);AnchorPane root = new AnchorPane();root.getChildren().add(label);Scene scene = new Scene(root, 300, 200);primaryStage.setTitle("Hello World");primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);}
}
属性绑定与监听
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class PropertyExample extends Application {@Overridepublic void start(Stage primaryStage) {// 圆形 属性Circle circle = new Circle();circle.setCenterX(400);circle.setCenterY(300);circle.setRadius(100);circle.setStroke(Color.BLACK);circle.setFill(Color.WHITE);AnchorPane root = new AnchorPane();root.getChildren().add(circle);Scene scene = new Scene(root, 800, 600);// 圆心始终问宽度和高度一半的位置circle.centerXProperty().bind(scene.widthProperty().divide(2));circle.centerYProperty().bind(scene.heightProperty().divide(2));// 属性监听// observable 监听对象// oldValue 旧值// newValue 新值circle.centerXProperty().addListener((observable, oldValue, newValue) -> System.out.println(observable + "\t" + oldValue + "\t" + newValue));primaryStage.setTitle("Hello World");primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);}
}
图片
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class ImageExample extends Application {@Overridepublic void start(Stage primaryStage) {// 获取图片文件类路径String path = this.getClass().getResource("/icon/java02.png").getPath();// 设置协议String protocol = "file://";Image image = new Image(protocol + path);ImageView imageView = new ImageView(image);BorderPane root = new BorderPane(imageView);Scene scene = new Scene(root, 800, 600);primaryStage.setTitle("Hello World");primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);}
}
事件驱动
package com.lihaozhe;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;/*** @author 李昊哲* @version 1.0* @Description* @create 2023/9/3*/
public class EventExample extends Application {@Overridepublic void start(Stage primaryStage) {// 获取图片文件类路径String path = this.getClass().getResource("/icon/dog.png").getPath();// 设置协议String protocol = "file://";Image image = new Image(protocol + path);ImageView imageView = new ImageView(image);imageView.setFitWidth(100);imageView.setFitHeight(100);imageView.setRotate(90);AnchorPane root = new AnchorPane(imageView);Scene scene = new Scene(root, 800, 600);primaryStage.setTitle("Hello World");// 键盘抬起scene.setOnKeyReleased(event -> {// 获取键盘事件码switch (event.getCode()) {case UP -> {imageView.setRotate(0);imageView.setLayoutY(imageView.getLayoutY() - 10);}case RIGHT -> {imageView.setRotate(90);imageView.setLayoutX(imageView.getLayoutX() + 10);}case DOWN -> {imageView.setRotate(180);imageView.setLayoutY(imageView.getLayoutY() + 10);}case LEFT -> {imageView.setRotate(270);imageView.setLayoutX(imageView.getLayoutX() - 10);}}});primaryStage.setScene(scene);primaryStage.show();}public static void main(String[] args) {launch(args);}
}
FXML布局
FXML是一种以XML的格式表示JavaFX界面对象的文件,
FXML文件中的每一个元素可以映射到JavaFX中的一个类,
每个FXML元素的属性或者其子元素都可以映射为该对应JavaFXML类的属性.
package com.lihaozhe.fxml;import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;import java.io.IOException;public class FxmlApplication extends Application {@Overridepublic void start(Stage stage) throws IOException {FXMLLoader fxmlLoader = new FXMLLoader(FxmlApplication.class.getResource("fxml-view.fxml"));Scene scene = new Scene(fxmlLoader.load(), 640, 480);stage.setTitle("Hello!");stage.setScene(scene);stage.show();}public static void main(String[] args) {launch();}
}
package com.lihaozhe.fxml;import javafx.fxml.FXML;
import javafx.scene.control.Label;
/*** 用来绑定这个fxml文件用的,用于控制这个界面的一些操作,实现一些功能*/
public class FxmlController {@FXMLprivate Label welcomeText;@FXMLprotected void onHelloButtonClick() {welcomeText.setText("Welcome to JavaFX Application!");}
}
<?xml version="1.0" encoding="UTF-8"?><?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?><?import javafx.scene.control.Button?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"fx:controller="com.lihaozhe.fxml.FxmlController"><padding><Insets bottom="20.0" left="20.0" right="20.0" top="20.0"/></padding><Label fx:id="welcomeText"/><Button text="Hello!" onAction="#onHelloButtonClick"/>
</VBox>
Scene Builder
官网:https://openjfx.io/
中文官网:https://openjfx.cn/
IDEA整合Scene Builder
新建 JavaFX 项目
initialize
controller中的initialize方法
相关文章:

javafx
JavaFX JavaFX简介 JavaFX是一个用于创建富客户端应用程序的图形用户界面(GUI)框架。它是Java平台的一部分,从Java 8开始成为Java的标准库。 JavaFX提供了丰富的图形和多媒体功能,使开发人员能够创建具有吸引力和交互性的应用程…...
玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— 编译构建及此过程中的踩坑填坑(3)
接前一篇文章:玩转贝启科技BQ3588C开源鸿蒙系统开发板 —— 编译构建及此过程中的踩坑填坑(2) 上一篇文章结束时在等待提示的各依赖包下载安装后的编译结果,但是很遗憾,编译并没有最终完成,既未成功也没有失…...
SQL ORDER BY 关键字
ORDER BY 关键字用于对结果集进行排序。 SQL ORDER BY 关键字 ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。 ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序,您可以使用 DESC 关键字。 SQL ORDER BY 语法 SELECT …...

多线程-生产者消费者模型
一、基本信息 1、场景介绍:厨师和吃货的例子,吃货吃桌子上的面条,吃完让厨师做,厨师做完面条放桌子上,让吃货吃,厨师如果发现桌子上有面条,就不做,吃货发现桌子上没有面条就不吃。 …...
解压命令之一 gzip
文章目录 解压命令之一 gzip更多信息 解压命令之一 gzip gzip用于对后缀为gz文件进行解压: $ gzip -d data.gz这个命令将解压examplefile.gz,并且在当前目录下生成一个名为data的解压后的文件。 但特别需要留意的是,这个操作会删除源文件&…...

力扣:438. 找到字符串中所有字母异位词 题解
Problem: 438. 找到字符串中所有字母异位词 438. 找到字符串中所有字母异位词 预备知识解题思路复杂度Code其它细节推荐博客或题目博客题目滑动窗口哈希表 预备知识 此题用到了双指针算法中的滑动窗口思想,以及哈希表的运用。c中是unordered_map。如果对此不了解的u…...
QT 高DPI解决方案
一、根据DPI实现动态调整控件大小(三种方式) 1、QT支持高DPI(针对整个进程中所有的UI) // main函数中 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling)tips:(1)如果不想全局设置&am…...
SLB、DMZ、Nginx、Ingress、Gateway、Kibana和Grafana
SLB、DMZ、Nginx、Ingress、Gateway、Kibana和Grafana虽然有一些相似之处,但是它们的功能和适用场景还是有所不同。 SLB主要用于将大流量的请求分配到多个服务器上进行处理,从而提高系统的可伸缩性和可靠性。它适用于需要处理大流量的应用,如…...

【已解决】Invalid bound statement (not found)
报错讯息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.casey.mapper.SysRoleMapper.getUserRoleCode at org.apache.ibatis.binding.MapperMethod S q l C o m m a n d . < i n i t > ( M a p p e r M e t h o d . j a v a :…...
汽车信息安全--芯片厂、OEM安全启动汇总(1)
目录 1.芯驰E3安全启动 2.STM32 X-CUBE-SBSFU 3.小米澎湃OS安全启动 4.小结 我在前篇文章里详细记录了车规MCU信息安全设计过程关于网络安全架构的思考过程,从芯片原厂、供应商、OEM等角度思考如何建立起完备的信任链; 不过这思考过程仅仅只是一家之言,因此我又对比了国…...

气膜建筑:舒适、智能、可持续
气膜建筑之所以能够拥有广阔的发展空间,源于其融合了诸多优势特点,使其成为未来建筑领域的前沿趋势。 气膜建筑注重环境可持续性和能源效率。在材料和设计上,它采用可回收材料、提高热保温效果,并积极利用太阳能等可再生能源&…...

【C语言】一种状态超时阻塞循环查询的办法
【C语言】一种状态超时阻塞循环查询的办法 文章目录 【C语言】一种状态超时阻塞循环查询的办法1.方法12.方法21.方法1 static void wait_notify_async(notify_type_t notify_type) {static rt_tick_t exit_tick;exit_tick = rt_time_get_msec();lb_int32 notify_success = RT_F…...

【leetcode】力扣热门之回文链表【简单难度】
题目描述 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。 用例 输入:head [1,2,2,1] 输出:true 输入:head [1,2] 输出:f…...
【MySQL】ALL函数的巧用 以及 排序(order by)巧用 sum(条件表达式) 语法
力扣题 1、题目地址 578. 查询回答率最高的问题 2、模拟表 SurveyLog 表: Column NameTypeidintactionENUMquestion_idintanswer_idintq_numinttimestampint 这张表可能包含重复项。action 是一个 ENUM(category) 数据,可以是 “show”、“answer”…...

Debezium发布历史49
原文地址: https://debezium.io/blog/2019/02/19/reliable-microservices-data-exchange-with-the-outbox-pattern/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. 使用发件箱模式进行可靠的微服务数…...

数据结构——队列(Queue)
目录 1.队列的介绍 2.队列工程 2.1 队列的定义 2.1.1 数组实现队列 2.1.2 单链表实现队列 2.2 队列的函数接口 2.2.1 队列的初始化 2.2.2 队列的数据插入(入队) 2.2.3 队列的数据删除(出队) 2.2.4 取队头数据 2.2.5 取队…...

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -后端架构搭建
锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…...

两种方式实现mysql截取年月日
select date_format(now(), %Y-%m-%d) select substring(now(), 1, 10)...

WPF 使用矢量字体图标
矢量字体图标 在WPF项目中经常需要显示图标,但是项目改动后,有时候需要替换和修改图标,这样非常麻烦且消耗开发和美工的时间。为了快速开发项目,节省项目时间,使用图标矢量字体图标是一个非常不错的选择。 矢量字体图标…...

编程语言的语法糖,你了解多少?
什么是语法糖 语法糖是一种编程语言的特性,通常是一些简单的语法结构或函数调用,它可以通过隐藏底层的复杂性,并提供更高级别的抽象,从而使代码更加简洁、易读和易于理解,但它并不会改变代码的执行方式。 为什么需要语…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...