海创软件组-20200531-JavaFx+Spring Boot+Maven搭建与打包部署窗体程序
资料摘抄与引用来源
第一部分:基础信息概览
1. JavaFx是什么
JavaFx是一个强大的图形和多媒体处理工具集合,它允许开发者来设计,创建,调试和部署富客户端程序,并且和Java一样跨平台
2. JavaFx应用程序概览
由于JavaFX库被写成了Java API,因此JavaFX应用程序代码可以调用各种Java库中的API。例如JavaFX应用程序可以使用Java API库来访问本地系统功能并且连接到基于服务器中间件的应用程序。
JavaFX可以自定义程序外观。层级样式表(CSS)将外观和样式与业务逻辑实现进行了分离,因此开发人员可以专注于编码工作。图形设计师使用CSS来方便地定制程序的外观和样式。
如果你具有Web设计背景,或者你希望分离用户界面(UI)和后端逻辑,那么你可以通过FXML脚本语言来表述图形界面并且使用Java代码来表述业务逻辑。如果你希望通过非编码的方式来设计UI,则可以使用JavaFX Scene Builder。在你进行UI设计时,Scene Builder会创建FXML标记,它可以与一个集成开发环境(IDE)对接,这样开发人员可以向其中添加业务逻辑。
3. JavaFx8及以后版本新特性(本人使用的部分)
● Java API:
JavaFX是一个Java库,包括用Java写成的类和接口。其API对基于JVM的语言也是友好的,例如JRuby和Scala。
● FXML和Scene Builder:
FXML是一种基于XML的声明式标记语言,用于描述JavaFX应用程序的用户界面。设计师可以在FXML中编码或者使用JavaFX Scene Builder来交互式地设计图形用户接口(GUI)。Scene Builder所生成的FXML标记可以与IDE对接,这样开发者可以添加业务逻辑。
● WebView:
它是一个使用了WebKitHTML技术的Web组件,可用于在JavaFX应用程序中嵌入Web页面。在WebView中运行的JavaScript可以方便地调用JavaAPI,并且JavaAPI也可以调用WebView中的JavaScript。对附加的HTML5特性的支持,包括Web Socket、Web Worker、Web Font、打印功能等都被添加到了JavaFX8中。参考《增加HTML内容到JavaFX应用程序中(Adding HTML Content to JavaFX Applications)》章节来了解更多信息。
● 与Swing互操作:
现有的Swing程序可以通过JavaFX的新特性升级,例如多媒体播放和Web 内容嵌入。在JavaFX8中加入了SwingNode类,它可以将Swing内容嵌入到JavaFX程序中。参考SwingNode API Javadoc和《在JavaFX应用程序中嵌入Swing 内容(Embedding Swing Content in JavaFX Applications)》章节来了解更多信息。
● 内置的UI控件和CSS:
JavaFX提供了开发一个全功能应用程序所需的所有主要控件。这些组件可以使用标准的Web技术如CSS来进行装饰。在JavaFX8中,DatePicker和TreeView UI控件是可用的,并且可以使用标准的Web技术如CSS来进行美化。参考《使用JavaFX UI控件(Using JavaFX UI Controls)》章节来了解更多信息。另外CSS样式控制类都变成了公开API,它们可以使用CSS来为对象增加样式。
● 自包含的应用部署模型:
自包含应用包具有应用所需的所有资源、包括一个Java和JavaFX运行时的私有拷贝。它们可作为操作系统原生安装包发布,并提供与原生应用相同的安装和运行体验。
4. JavaFX可以构建什么
使用JavaFX你可以构建各种类型的应用程序。一般来说,它们是联网应用,可以跨平台部署,并且可以在一个具有高性能现代UI中展现信息,支持音频、视频、动画等特性。
第二部分:工具环境与打包部署配置
5. Spring Boot集成JavaFx的maven配置
Spring Boot与JavaFx8匹配使用的库:spring-boot-javafx-support
集成spring-boot-javafx-support的Maven配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>de.roskenet</groupId>
<artifactId>springboot-javafx-support</artifactId>
<version>2.1.6</version>
</dependency>
<dependency>
<groupId>de.roskenet</groupId>
<artifactId>springboot-javafx-test</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
<!-- 启动类 -->
<mainClass>cn.hctech2006.product.product.ProductApplication</mainClass>
<!-- 公司名称 -->
<vendor>海创软件组</vendor>
<!-- 应用名称 ${project.build.finalName} = ${project.artifactId}-${project.version} -->
<appName>${project.build.finalName}</appName>
<!-- 发行版本 -->
<nativeReleaseVersion>${project.version}</nativeReleaseVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
<mainclass>cn.hctech2006.product.product.ProductApplication<mainclass>
是主启动类
<vendor>海创软件组</vemdor>是所属公司名称
6. IDEA集成JavaFx Builder Scene
6.1 JavaFx Builder Scene概述
JavaFX Scene Builder 是一个可视化布局工具,可快速设计 JavaFX 应用程序用户界面,无需编写代码。用户可以拖放UI组件到工作区,修改组件的属性,应用样式表,而且在后台自动生成所创建布局的 FXML 代码。最后得到的是一个可以稍后与 Java 项目整合到一起的 FXML 文件,从而将 UI 与应用程序逻辑绑定起来。
6.2 JavaFx Builder Scene工具下载
-
下载地址:
因为我是Ubuntu系统,所以采用如下图下载
- 安装之后,打开软件界面如下:
我特别要强调的是左下角,拖动控件最好拖到左下角不要拖到中间
6.3 IDEA集成JavaFx Scene Builder
打开Intellij —>点击File—>点击settings—>Languages&Frameworks—>JavaFX, 在Path to SceneBuilder 中填入SceneBuilder的deb文件
需要说明,默认安装路径是图中的目录
7. JavaFx打包需要的Maven插件-javafx-maven-plugin
7.1项目地址
7.2javaFx Maven插件介绍
JavaFX Maven插件提供了一种从Maven内部组装JavaFX应用程序(8+和9+)的分发包的方法。
这个插件本质上是JavaFX附带的打包工具的Maven包装器,它称为javapackager
7.3 特定操作系统与环境版本的要求
(Windows)EXE安装程序:Inno安装程序
(Windows)MSI安装程序:WiX(至少3.7版)
(Linux)DEB安装程序:dpkg-deb
(Linux)RPM安装程序:rpmbuild
(Mac)DMG安装程序:hdiutil
(Mac)PKG安装程序:pkgbuild
Maven 3.5(旧版本可能也可以)
Java Developer Kit 8,至少具有Update 40
7.4 JavaFx JAR快速入门与打包可执行文件方法
- 将此添加到构建插件中的pom.xml中:
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
<mainClass>your.package.with.Launcher</mainClass>
</configuration>
</plugin>
使用JavaFX-magic创建可执行文件,请在命令行调用mvn jfx:jar.jar
文件将位于target/jfx/app,可执行文件将位于target/jfx/native
第三部分:基于Spring Boot架构的JavaFx项目开发流程
8. 使用FXML进行界面设计
8.1 创建Spring Boot工程并且集成所需的javaFx依赖和插件
8.2 创建FXML布局文件
- 代码手写
- 使用 SceneBuilder 工具创建 FXML 文件
8.3 创建*View.java处理界面逻辑
- 新建一个class,继承AbstractFxmlView,并且添加注解
@FXMLView( value = "你的fxml的地址,相对于resource,注意要以斜杠/这个开头,否则找不到", css = {"你的css文件的位置,可以用多个,相对于resource"} )
@FXMLView(value = "/CustomerDetailsView.fxml")
public class CustomerDetailsView extends AbstractFxmlView {
}
8.4 新建*ViewController.java处理数据与事件逻辑
- 需要实现Initialzable接口,加上@FXMLController注解
@FXMLController
public class CustomerDetailsViewController implements Initializable {
;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
8.5 MainStageView作为主页
这个是比较特殊的,在普通的 javafx 里面没有这个东西,但是按照 MVC 的角度来讲,业务和试图分离,还是很有必要的。
@FXMLView(value = "/MainView.fxml")
public class MainView extends AbstractFxmlView {
}
8.6 修改Application启动类
主类是需要继承AbstractJavaFxApplicationSupport这个类型,添加main方法和SpringBootApplication注解。我们使用launch方法代替SpringApplication.run,具体的可以看看AbstractJavaFxApplicationSupport的launch的实现:
/**
* Launch app.
*
* @param appClass the app class
* @param view the view
* @param args the args
*/
public static void launch(final Class<? extends Application> appClass,
final Class<? extends AbstractFxmlView> view, final String[] args);
/**
* Launch app.
*
* @param appClass the app class
* @param view the view
* @param splashScreen the splash screen
* @param args the args
*/
public static void launch(final Class<? extends Application> appClass,
final Class<? extends AbstractFxmlView> view,
final SplashScreen splashScreen, final String[] args);
/**
* Launch app.
*
* @deprecated To be more in line with javafx.application please use launch
* @param appClass the app class
* @param view the view
* @param splashScreen the splash screen
* @param args the args
*/
@Deprecated
public static void launchApp(final Class<? extends Application> appClass,
final Class<? extends AbstractFxmlView> view,
final SplashScreen splashScreen, final String[] args);
- 继承了AbstractJavaFxApplicationSupport这个类,
- 需要一个view,作为启动的界面,
- main函数的参数args,
- 如果需要,使用SplashScreen作为闪屏,应用加载界面,
- 具体代码
@SpringBootApplication
public class ProductApplication extends AbstractJavaFxApplicationSupport {
public static void main(String[] args) {
//SpringApplication.run(ProductApplication.class, args);
//多个舞台并存
launch(ProductApplication.class, LoginView.class,new SplashScreenCustom(),args);
}
@Override
public void start(Stage stage) throws Exception {
super.start(stage);
}
}
- 点击运行,可以看到一个javafx的窗口。
需要对窗口做出调整,应该使用GUIState类的静态方法获取Stage,当然,这个Stage就是主窗口的Stage了。
8.8 闪屏的实现
public class SplashScreenCustom extends SplashScreen {
@Override
public Parent getParent() { // 在这里可以设置闪屏窗口大小,默认图片大小
return super.getParent();
}
@Override
public boolean visible() { // 是否显示闪屏,默认显示
return super.visible();
}
@Override
public String getImagePath() {
return "/heikediguo2.gif";
}
}
重写getImagePath即可
9.JavaFx窗口的切换
9.1 切换窗口后,只保留一个窗口
主要用于登录跳转
ProductApplication.showView(CustomerView.class);
9.2 切换窗口后,多个窗口并存
ProductApplication.showView(CustomerView.class, Modality.NONE);
9.3 Modify概述
枚举常量和描述
- APPLICATION_MODAL 定义一个模式窗口,该窗口阻止事件传递到任何其他应用程序窗口。
- NONE 定义非模态且不阻止任何其他窗口的*窗口。
- WINDOW_MODAL 定义一个模式窗口,该窗口阻止事件传递到其整个所有者窗口层次结构。
9.4 第一种单个窗口显示的showView()源码
public static void showView(Class<? extends AbstractFxmlView> newView) {
try {
AbstractFxmlView view = (AbstractFxmlView)applicationContext.getBean(newView);
if (GUIState.getScene() == null) {
GUIState.setScene(new Scene(view.getView()));
} else {
GUIState.getScene().setRoot(view.getView());
}
GUIState.getStage().setScene(GUIState.getScene());
applyEnvPropsToView();
GUIState.getStage().getIcons().addAll(icons);
GUIState.getStage().show();
} catch (Throwable var2) {
LOGGER.error("Failed to load application: ", var2);
showErrorAlert(var2);
}
}
9.5第二种多个窗口并存的showVIew()源码以及调用的主要方法
public static void showView(Class<? extends AbstractFxmlView> window, Modality mode) {
AbstractFxmlView view = (AbstractFxmlView)applicationContext.getBean(window);
Stage newStage = new Stage();
Scene newScene;
if (view.getView().getScene() != null) {
newScene = view.getView().getScene();
} else {
newScene = new Scene(view.getView());
}
newStage.setScene(newScene);
newStage.initModality(mode);
newStage.initOwner(getStage());
newStage.setTitle(view.getDefaultTitle());
newStage.initStyle(view.getDefaultStyle());
newStage.showAndWait();
}
private void showInitialView() {
String stageStyle = applicationContext.getEnvironment().getProperty("javafx.stage.style");
if (stageStyle != null) {
GUIState.getStage().initStyle(StageStyle.valueOf(stageStyle.toUpperCase()));
} else {
GUIState.getStage().initStyle(StageStyle.DECORATED);
}
this.beforeInitialView(GUIState.getStage(), applicationContext);
showView(savedInitialView);
}
这样看就很明显了,第一种只有一个stage舞台,第二种确实可以有多个stage舞台