网站seo是什么,做二维码推送网站,cms开发是什么意思,做网站要准备哪些文章目录 1 JavaFX1.1 简介1.2 环境准备1.2.1 手动管理依赖1.2.2 maven或Gradle管理 1.3 JavaFX 架构1.3.1 JavaFX 架构图1.3.2 JavaFX组件1.3.2.1 舞台1.3.2.2 场景1.3.2.3 控件1.3.2.4 布局1.3.2.5 图表1.3.2.6 2D图形1.3.2.7 3D图形1.3.2.8 声音1.3.2.9 视频 1.4 简单使用1.… 文章目录 1 JavaFX1.1 简介1.2 环境准备1.2.1 手动管理依赖1.2.2 maven或Gradle管理 1.3 JavaFX 架构1.3.1 JavaFX 架构图1.3.2 JavaFX组件1.3.2.1 舞台1.3.2.2 场景1.3.2.3 控件1.3.2.4 布局1.3.2.5 图表1.3.2.6 2D图形1.3.2.7 3D图形1.3.2.8 声音1.3.2.9 视频 1.4 简单使用1.5 FXML1.5.1 简介1.5.2 FXML布局文件使用1.5.3 Controller里的initialize方法1.5.4 在Application里操作Controller 1.6 FXML 注解讲解1.6.1 FXMLController1.6.2 FXML1.6.3 FXMLLoaderParameters1.6.4 FXMLProperty 1.7 多线程 Platform.runLater 1 JavaFX
1.1 简介
JavaFX中文官方网站 JavaFX 是一个开源的下一代客户端应用平台适用于基于Java构建的桌面、移动端和嵌入式系统。目的是为开发丰富的客户端应用提供一个现代、高效、功能齐全的工具包。 目前市面上已经使用java语言写的桌面应用项目DBeaver、finalshell、Behinder(冰蝎)、BurpSuite、Jmeter、IDEA 等等这类比较知名软件那么java是否有更好的桌面应用开发的框架呢
准备环境IDEAJDK17WindowsScene Builder
1.2 环境准备
从 JDK 11 开始JavaFX 已经从标准 JDK 中移除不再默认包含在 JDK 中。 因此使用 JDK 17 是需要额外下载 JavaFX 的 SDK 或通过依赖管理工具如 Maven 或 Gradle来引入 JavaFX 库
1.2.1 手动管理依赖
如果是手动管理依赖不使用 Maven/Gradle需要下载并配置 JavaFX SDK。 配置步骤
下载地址https://gluonhq.com/products/javafx/ 比如openjfx-23.0.1_windows-x64_bin-sdk.zip。解压到一个目录如 C:\javafx-sdk-23.0.1添加lib包 File-Project Structure [快捷键(Ctrl Alt Shift S)] -Libraries 点击旁边的 号 - 点击 Java - 找到之前安装的 JavaFX SDK 路径 - 进入该路径并添加lib包 配置项目运行时参数添加 JavaFX 模块路径。例如
--module-path C:\javafx-sdk-23.0.1\lib --add-modules javafx.controls,javafx.fxml1.2.2 maven或Gradle管理
无需手动下载 JavaFX SDK可以通过 Maven 或 Gradle 直接引入 JavaFX 的依赖 Maven 在 pom.xml 中添加以下依赖
dependenciesdependencygroupIdorg.openjfx/groupIdartifactIdjavafx-controls/artifactIdversion23.0.1/version/dependencydependencygroupIdorg.openjfx/groupIdartifactIdjavafx-fxml/artifactIdversion23.0.1/version/dependency
/dependencies如果使用非 Windows 平台请添加 classifier
dependencygroupIdorg.openjfx/groupIdartifactIdjavafx-controls/artifactIdversion23.0.1/versionclassifierlinux/classifier !-- 或 mac --
/dependencyGradle 在 build.gradle 中添加
dependencies {implementation org.openjfx:javafx-controls:23.0.1implementation org.openjfx:javafx-fxml:23.0.1
}1.3 JavaFX 架构
1.3.1 JavaFX 架构图
一般来说JavaFX应用程序包含一个或多个对应于窗口的阶段。每个阶段都有一个场景。每个场景都可以有一个控件、布局等附加到它的对象图称为场景图。这些概念都将在后面更详细地解释。下面是JavaFX应用程序的般结构的图示
1.3.2 JavaFX组件
1.3.2.1 舞台
舞台是 JavaFX 应用程序的外部框架。舞台通常对应于一个窗口。在 JavaFX 可以在浏览器中运行的早期阶段舞台还可以指网页内 JavaFX 可用于绘制自身的区域。 由于 Java 浏览器插件的弃用JavaFX 主要用于桌面应用程序。在这里JavaFX 取代了 Swing 作为推荐的桌面 GUI 框架。而且 JavaFX 看起来比 Swing 更加一致且功能丰富。 在桌面环境中使用时JavaFX 应用程序可以打开多个窗口。每个窗口都有自己的舞台。 每个阶段都由StageJavaFX 应用程序中的一个对象表示。StageJavaFX 应用程序有一个由JavaFX 运行时为您创建的主对象。如果 JavaFX 应用程序Stage需要打开其他窗口它可以创建其他对象。例如对于对话框、向导等。
1.3.2.2 场景
要在 JavaFX 应用程序的舞台上显示何内容您需要一个场景。一个舞台一次只能显示一个场景但可以在运行时交换场景。就像剧院中的舞台可以重新安排以在戏剧期间显示多个场景一样JavaFX 中的舞台对象可以在 JavaFX 应用程序的生命周期内显示多个场景 (一次一个) 。 可能想知道为什么 JavaFX 应用程序的每个阶段会有多个场景。想象一个电脑游戏。一个游戏可能有多个“屏幕”向用户显示。例如初始菜单屏幕、主游戏屏幕(玩游戏的地方)、游戏结束屏幕和高分屏幕。这些屏幕中的每一个都可以由不同的场景来表示。当游戏需要从一屏切换到下一屏时它只需将相应的场景附加到 StageJavaFX 应用程序的对象上即可。 场景由SceneJavaFX 应用程序中的对象表示。JavaFX 应用程序必须创建Scene它需要的所有对象。
场景图 所有视觉组件控件、布局等都必须附加到要显示的场景并且该场景必须附加到舞台才能使整个场景可见。附加到场景的所有控件、布局等的总对象图称为场景图。节点 附加到场景图的所有组件都称为节点。所有节点都是JavaFX 类的子类称为 javafx.scene.Node。 有两种类型的节点分支节点和叶节点。分支节点是可以包合其他节点(子节点)的节点。分支节点也称为父节点因为它们可以包含子节点。叶节点是不能包含其他节点的节点。
1.3.2.3 控件
JavaFX 控件是 JavaFX 组件它们在JavaFX 应用程序中提供某种控制功能。例如按钮、单选按钮、表格、树 为了使控件可见它必须附加到某个Scene对象的场景图中。 控件通常嵌套在一些 JavaFX 布局组件中这些组件管理控件相对于彼此的布局。 JavaFX 包含控件手风琴按钮复选框选择框选色器组合框日期选择器标签列表显示菜单菜单栏密码字段进度条单选按钮滑块微调器拆分菜单按钮拆分窗格表视图选项卡窗格文本区域文本域标题窗格切换按钮工具栏树表视图树视图
1.3.2.4 布局
JavaFX 布局是其中包含其他组件的组件。布局组件管理嵌套在其中的组件的布局。JavaFX 布局组件有时也称为父组件因为它们包含子组件而且布局组件是 JavaFX 类的子类javafx.scene.Parent。 布局组件必须附加到某个Scene对象的场景图才能可见。 JavaFX 包含布局组件团体地区窗格HBox盒子流窗格边框窗格边框窗格堆栈窗格瓷砖窗格网格窗格锚点窗格文本流
1.3.2.5 图表
JavaFX 带有一组内置的即用型图表组件因此您不必每次需要基本图表时都从头开始编写图表代码。 JavaFX 包含图表组件面积图条形图气泡图折线图饼形图散点图堆积面积图堆积条形图
1.3.2.6 2D图形
JavaFX 包含可以轻松在屏幕上绘制2D 图形的功能。
1.3.2.7 3D图形
JavaFX 包含可以轻松在屏幕上绘制 3D 图形的功能。
1.3.2.8 声音
JavaFX 包含使在 JavaFX 应用程序中播放音频变得容易的功能。这通常在游戏或教育应用中很有用。
1.3.2.9 视频
JavaFX 包合使在 JavaFX 应用程序中播放视频变得容易的功能。这通常在流媒体应用程序、游戏或教育应用程序中很有用。 JavaFX 包含一个WebView能够显示网页 (HTML5、CSS 等)的组件。JavaFXWebView 组件基于 WebKit-Chrome 和 Safari 中也使用的网页染引擎。 该WebView组件使得将桌面应用程序与 Web 应用程序混合成为可能。有时这很有用。例如如果已经有一个不错的 Web 应用程序但需要一些只有桌面应用程序才能提供的功能一一例如磁盘访问、与 HTTP 以外的其他网络协议 (例如 UDP、IAP 等) 的通信。
1.4 简单使用
编写一个JavaFX基本结构代码
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;// 继承Application抽象类重新start方法
public class Main extends Application {public static void main(String[] args) {// 入口函数里调用Application的静态方法launch之后会自动调用start方法Application.launch(args);}/*** param primaryStage 主窗口*/Overridepublic void start(Stage primaryStage) throws Exception {// 设置一个场景场景里添加一个树形组件图先创建一个标签Label label new Label(Hello JavaFx!);// 创建布局将标签放入布局里BorderPane布局把场景划分为上下左右中默认加入的控件在中间位置BorderPane pane new BorderPane(label);// 创建场景将布局放入场景里设置宽度和高度Scene scene new Scene(pane, 300, 300);// 将场景设置到窗口里primaryStage.setScene(scene);// 设置标题primaryStage.setTitle(我是窗口);primaryStage.show();}
}1.5 FXML
1.5.1 简介
FXML 是一种可编写的、基于XML的用于构造JavaFX场景图的标记语言。在FXML中一个FXML标签代表以下类型之一某个类的实例某个类实例的属性某个静态属性一个定义代码块一个脚本代码块 一个FXML属性表示以下类型之一某个类实例的属性某个静态属性事件处理程序
1.5.2 FXML布局文件使用
案例演示将下面的JavaFX文件代码中的容器、组件和监听事件改写为FXML文件的格式简化和方便管理JavaFx类的编写。
public class Main extends Application {public static void main(String[] args) {Application.launch(args);}Overridepublic void start(Stage primaryStage) throws Exception {AnchorPane root new AnchorPane();Scene scene new Scene(root, 500, 500);Label label new Label(按键盘↓向下移动);label.setLayoutX(100);label.setLayoutY(150);label.setFont(new Font(30));Button button new Button(点击按钮向上移动);button.setLayoutX(350);button.setLayoutY(200);button.setOnAction(new EventHandlerActionEvent() {Overridepublic void handle(ActionEvent event) {label.setLayoutY(label.getLayoutY() - 5);}});scene.setOnKeyReleased(new EventHandlerKeyEvent() {Overridepublic void handle(KeyEvent event) {KeyCode keyCode event.getCode();if (keyCode.equals(KeyCode.DOWN)) {label.setLayoutY(label.getLayoutY() 5);}}});root.getChildren().addAll(label, button);primaryStage.setScene(scene);primaryStage.show();}
}改写为FXML
public class Demo extends Application {public static void main(String[] args) {Application.launch(args);}Overridepublic void start(Stage primaryStage) throws Exception {// 使用FXMLLoader类的load方法来加载FXML文件并将其与Controller类进行关联。//Pane root FXMLLoader.load(getClass().getClassLoader().getResource(com/aizen/javafx/fxml/demo.fxml));Pane root FXMLLoader.load(getClass().getResource(demo.fxml));Scene scene new Scene(root, 500, 500);primaryStage.setScene(scene);primaryStage.show();}
}public class DemoController {FXMLLabel la;FXMLButton bu;public void handleButtonAction() {la.setLayoutY(la.getLayoutY() - 5);}public void handleKeyReleased(KeyEvent event) {KeyCode keyCode event.getCode();if (keyCode.equals(KeyCode.DOWN)) {la.setLayoutY(la.getLayoutY() 5);}}
}?xml version1.0 encodingUTF-8??import java.lang.*?
?import java.util.*?
?import javafx.scene.*?
?import javafx.scene.control.*?
?import javafx.scene.layout.*??import javafx.scene.text.Font?
AnchorPane xmlnshttp://javafx.com/javafxxmlns:fxhttp://javafx.com/fxmlfx:controllercom.aizen.javafx.fxml.DemoControlleronKeyReleased#handleKeyReleasedprefHeight400.0 prefWidth600.0childrenLabel fx:idla text按键盘↓向下移动 layoutX100 layoutY150fontFont size30//font/LabelButton fx:idbu text点击按钮向上移动 layoutX350 layoutY200 onAction#handleButtonAction//children
/AnchorPane1.5.3 Controller里的initialize方法
有时我们是无法在fxml文件里填充数据的并且有些内容需要初始化时就填充如表格而不是触发事件后填充此时就可以使用initialize方法做一些初始化的工作。
initialize()方法需要自定义定义完之后会自动调用该方法调用的时机是加载好fxml文件并绑定好控件id之后才会自动调用一次不需要手动指定调用 initialize 方法
initialize 是 JavaFX 的生命周期方法之一当 FXML 文件被加载并与 Controller 关联后会自动调用它。initialize 方法在 FXML 元素完成注入后调用因此在此方法中可以安全地访问 FXML 标记的 UI 元素。
演示案例使用initialize()方法初始化时填充完TableView的数据。
public class Main extends Application {public static void main(String[] args) {Application.launch(args);}Overridepublic void start(Stage primaryStage) throws Exception {Pane root FXMLLoader.load(getClass().getResource(hello.fxml));primaryStage.setScene(new Scene(root));primaryStage.show();}
}Data
public class Person {private String name;private int age;public Person(String name, int age) {this.name name;this.age age;}
}public class Controller {FXMLprivate TableViewPerson tableView;FXMLprivate TableColumnPerson, String name;FXMLprivate TableColumnPerson, Integer age;public void initialize() {ObservableListPerson cellDate FXCollections.observableArrayList();name.setCellValueFactory(new PropertyValueFactoryPerson, String(name));age.setCellValueFactory(new PropertyValueFactoryPerson, Integer(age));cellDate.add(new Person(张三, 18));cellDate.add(new Person(李四, 19));cellDate.add(new Person(王五, 23));cellDate.add(new Person(赵六, 15));tableView.setItems(cellDate);}
}?xml version1.0 encodingUTF-8??import javafx.scene.control.TableColumn?
?import javafx.scene.control.TableView?
?import javafx.scene.layout.AnchorPane?AnchorPane fx:controllercom.aizen.javafx.fxml_02.Controller maxHeight-Infinity maxWidth-Infinity minHeight-Infinity minWidth-Infinity prefHeight400.0 prefWidth600.0 xmlnshttp://javafx.com/javafx/8.0.171 xmlns:fxhttp://javafx.com/fxml/1childrenTableView fx:idtableView prefHeight400.0 prefWidth600.0columnsTableColumn fx:idname prefWidth75.0 textname /TableColumn fx:idage prefWidth75.0 textage //columns/TableView/children
/AnchorPane1.5.4 在Application里操作Controller
案例演示要求圆的中心点自适应边框大小使用fxml实现。
public class JavaFxApplication extends Application {public static void main(String[] args) {launch(args);}Overridepublic void start(Stage primaryStage) throws IOException {FXMLLoader fxmlLoader new FXMLLoader(); // 使用FXMLLoader获取布局里面的Controller的引用fxmlLoader.setLocation(getClass().getResource(hello.fxml));Parent root fxmlLoader.load();Scene scene new Scene(root);// 在Application中操作Controller进行属性绑定Controller controller fxmlLoader.getController();controller.circleLocationBind(scene);primaryStage.setScene(scene);primaryStage.show();}
}public class Controller {FXMLprivate Circle ci;public void circleLocationBind(Scene scene) {// 获得X和Y中心点的可绑定对象设置中心点自适应边框大小ci.centerXProperty().bind(scene.widthProperty().divide(2));ci.centerYProperty().bind(scene.heightProperty().divide(2));}
}?xml version1.0 encodingUTF-8??import javafx.scene.layout.AnchorPane?
?import javafx.scene.shape.Circle?AnchorPane fx:controllercom.aizen.javafx.fxml_03.Controller maxHeight-Infinity maxWidth-Infinity minHeight-Infinity minWidth-Infinity prefHeight488.0 prefWidth496.0 xmlnshttp://javafx.com/javafx/8.0.171 xmlns:fxhttp://javafx.com/fxml/1childrenCircle fx:idci centerX250.0 centerY250.0 fillDODGERBLUE radius100.0 strokeBLACK strokeTypeINSIDE //children
/AnchorPane1.6 FXML 注解讲解
1.6.1 FXMLController
这个注解用于标记一个类作为FXML的Controller类。当FXML文件加载时FXMLLoader会尝试通过这个注解来确定哪个类是它的Controller。它的作用类似于fx:controller属性。
FXMLController
public class MyController {// Controller logic
}1.6.2 FXML
这个注解用于注入FXML文件中定义的控件。通过在控件字段上加上FXML注解FXMLLoader会在加载FXML文件时将对应的FXML节点与控件字段进行关联。
public class MyController {FXMLprivate Button myButton;
}1.6.3 FXMLLoaderParameters
这个注解用于指定加载 FXML 文件时的参数。可以用它来指定控制器工厂、资源加载器等。
FXMLLoaderParameters(location MyView.fxml, controller MyController.class)
public class MyApplication extends Application {// Application logic
}标记构造函数参数指示在加载时由 FXMLLoader 提供的值。
public class Controller {FXMLLoaderParameterspublic Controller(String param) {System.out.println(Parameter: param);}
}1.6.4 FXMLProperty
这个注解用于将一个方法标记为用于处理FXML文件中的属性绑定。 用于绑定属性特别是当 FXML 文件中需要与 JavaFX 属性Property绑定时。 标记字段或方法使其与 FXML 文件中的对应属性绑定。
public class MyController {private StringProperty name new SimpleStringProperty();FXMLPropertypublic void setName(String name) {this.name.set(name);}
}1.7 多线程 Platform.runLater
当我们执行一些耗时操作时如加载资源。我们为了防止这些耗时操作占用JavaFX的主线程资源下面的代码无法执行造成软件界面加载卡顿我们通常使用JavaFX支持的多线程操作来解决这个问题。
案例演示1使用多线程技术实现点击Button按钮获取姓名数据模拟数据库获取数据显示在Label文字布局上。
public class Main extends Application {public static void main(String[] args) {launch(args);}Overridepublic void start(Stage primaryStage) throws Exception {Label label new Label(姓名是);label.setLayoutX(200);label.setLayoutY(350);Button button new Button(点击获取姓名);button.setLayoutX(200);button.setLayoutY(400);button.setOnAction(event - {new Thread(() - {String name Aizen; // 模拟数据库获取值的操作这里直接定义label.setText(name); // 更新UI控件的操作}).start();});AnchorPane pane new AnchorPane();pane.getChildren().addAll(label, button);Scene scene new Scene(pane, 500, 500);primaryStage.setScene(scene);primaryStage.show();}
}如果直接这样运行点击后会报出非法状态异常不在JavaFX的Application线程中更新UI控件必须在FX Application主线程中。
想要避免这个问题需要使用到JavaFX提供的静态方法Platform.runLater(Runnable runnable)其中参数需要一个Runnber对象runLater方法将Runnable放在任务队列里面在Application线程空闲的时候会执行队列里的任务。
public class Main0 extends Application {public static void main(String[] args) {launch(args);}Overridepublic void start(Stage primaryStage) throws Exception {Label label new Label(姓名是);label.setLayoutX(200);label.setLayoutY(350);Button button new Button(点击获取姓名);button.setLayoutX(200);button.setLayoutY(400);button.setOnAction(event - {// 报错案例/*new Thread(() - {String name Aizen; // 模拟数据库获取值的操作这里直接定义label.setText(name); // 更新UI控件的操作}).start();*/// 正确案例// runLater方法将Runnable放在任务队列里面在Application线程空闲的时候会执行队列里的任务new Thread(() - {String name Aizen; // 模拟数据库获取值的操作这里直接定义Platform.runLater(() - {label.setText(name); // 更新UI控件的操作});}).start();});AnchorPane pane new AnchorPane();pane.getChildren().addAll(label, button);Scene scene new Scene(pane, 500, 500);primaryStage.setScene(scene);primaryStage.show();}
}