快速创建基于JavaFX的桌面App
快速创建一个基于JavaFX的桌面APP,用于模拟一个简单的客户端POST请求;
项目基于Maven创建,使用的IDE是Intellij IDEA,项目编码全部为UTF-8;
JDK版本为1.8。
制作目标
简单说明一下想制作的APP的样子:
实现一个APP,存在两个视图:首页和编辑页。首页简单的展示一些欢迎话语,编辑页负责填写POST请求的数据,并且有一个按钮提交请求。
顶部有菜单,部分菜单只在编辑视图中有效,两个视图间的切换带有动画效果。
下面,开始实现这个简单的APP。
一、创建项目
- 创建新目录,选择Maven项目,原型选择maven-archetype-quickstart;
- 添加项目依赖,说明如下:
1. 由于个人偏好使用RxJava,而且JavaFx的设计也包含对RxJava的使用,javafx有一个配套的框架,所以会引用rxjavafx框架;
2. 要实现的顶部菜单不在视图范围内,需要实现一个类似EventBus的功能,由顶部菜单向下传播点击操作的事件,因此会引入rxjava2中的部分功能;
3. controlsfx中提供了很多使用的自定义控件;
4. 控件样式直接使用基于Material Design的jfoenix;
5. datafx可以帮助我快速的管理各个视图和菜单的切换关系;
6. json解析库使用fasterxml.jackson,http请求使用apache的httpcomponents,也会使用到其他的commons库;
7. zenjava可以帮助快速打包项目为执行的APP;
8. 使用log4j记录执行日志。
项目依赖添加后部分内容如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<fasterxml.jackson.version>2.8.8</fasterxml.jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>8.40.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${fasterxml.jackson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjavafx</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.jfoenix</groupId>
<artifactId>jfoenix</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>io.datafx</groupId>
<artifactId>flow</artifactId>
<version>8.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.5.0</version>
<configuration>
<vendor>snart</vendor>
<mainClass>demo.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
maven直接创建的项目没有resources目录,因此需要在project setting中添加resources目录。
二、创建视图
javafx项目的入口只需要实现javafx.application.Application类即可
public class App extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// TODO
}
}
使用datafx管理视图的切换(datafx说明见: https://github.com/guigarage/DataFX ),首先需要在start方法中初始化一个ViewFlowContext来管理视图以及视图间共享的数据模型
ViewFlowContext flowContext = new ViewFlowContext();
Javafx用Stage(舞台)来做根基,用Scene(场景)来控制每个场景,每个场景可以定义要展示的内容,这里需要先将primaryStage注入到ViewFlowContext中,初始化一个视图流Flow,然后初始化一个Scene,每个Scene的初始化都需要一个root控件,这里我们使用jfoenix中的JFXDecorator(jfoenix说明见: https://github.com/jfoenixadmin/JFoenix )
flowContext.register("Stage", primaryStage);
// create flow and flow container, flow container controls view decoration and view exchange
Flow flow = new Flow(MainController.class);
DefaultFlowContainer container = new DefaultFlowContainer();
flow.createHandler(flowContext).start(container);
// JFXDecorator will be applied to primaryStage, and decorated on view which is created by flow container
JFXDecorator decorator = new JFXDecorator(primaryStage, container.getView(),
false, true, true);
// init scene with a decorator
Scene scene = new Scene(decorator, 750, 500);
primaryStage.setMinWidth(500);
primaryStage.setMinHeight(400);
primaryStage.setTitle("Demo");
primaryStage.setScene(scene);
primaryStage.show();
Flow的初始化需要一个默认的视图以及视图控制器:
import io.datafx.controller.ViewController;
@ViewController(value = "/views/main.fxml")
public class MainController {
}
注解@ViewController用于定义此控制器指定的视图位置,main.fxml定义在resource/views下:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx/8.0.112"
xmlns:fx="http://javafx.com/fxml/1">
<top>
<HBox prefHeight="10.0" BorderPane.alignment=