一、前言
从本章节开始我们会陆续实现各个框体的 UI 开发,内容会包括;框体拆解、工程结构、代码开发,以及最后编写事件和接口。
在 JavaFx 中,一个框体包含;窗口 (Stage)、场景(Scene)、布局(Pane)、控件(Button 等) 这四方面内容。而开发过程中可以使用 xml 和编码两种方式进行处理,一般一些预定好的会使用 xml 结构,如果是随着我们业务行为触达而产生的会开发到代码中来生成。
那么接下来我们的目标是开发一个登陆框体,样式如下;

二、登陆窗体分析
按照我们的 UI 开发诉求,将整个页面进行拆解,以方便清楚知道我们的各种类型元素放置位置;

序号 | 模块 | 宽 * 高 | 描述 |
---|
1 | 整体框体 | 540 * 415 | 一个整体的 4px 的圆角面板, 去掉默认的标题和工具栏 |
2 | 背景图片 | 540 * 158 | 设置的一个背景图 |
3 | 最小化、退出 | 43 * 32 | 两个同样大小的 Button |
4 | 用户 ID 输入框 | 250 * 45 | 明文输入框 |
5 | 用户密码输入框 | 250 * 45 | 密文输入框 |
6 | 登录按钮 | 250 * 45 | 登陆按钮 Button,鼠标进入时变换背景色,点击触发登陆 |
7 | 版本展示 | 400 * 25 | 透明的无背景可以调整,一般展示版本编号如;v1.0 |
8 | 头像 | 100 * 100 | 圆角头像图片,整个可以使用 Image 等元素开发 |
9 | 标头 | 200 * 15 | 展示名称,例如;憨憨·语约 |
- 以上就是我们整体窗体的一个拆解后的示意图,接下来开始按照整个示意图进行开发。
- 如果是个人开发的新项目,一般 UI 的设计可以先在草稿设计,最后在使用工具进行具体设计。如果是公司级别会有专门的设计来出所有的图稿。
- 关于设计中使用的元素可以从工程源码中获取,可以自己从矢量图仓库中寻找自己喜欢的;https://www.
三、工程结构
itstack-naive-chat-ui-02
└── src
├── main
│ ├── java
│ │ └── org.itstack.navice.chat.ui
│ │ ├── view
│ │ │ └── Login.java
│ │ └── Application.java
│ └── resources
│ └── fxml.login
│ ├── css
│ │ └── login.css
│ ├── img
│ │ ├── close_0.png
│ │ ├── close_1.png
│ │ ├── head_default_100.png
│ │ ├── logo.png
│ │ ├── min_0.png
│ │ ├── min_1.png
│ │ └── show.png
│ └── login.fxml
└── test
└── java
└── org.itstack.test
└── ApiTest.java
- 工程结构上我们先从简单规划;启动层、展示层、资源配置层,三方面。后面在随着开发内容的增多会不断的优化结构
- fxml 是 JavaFx 开发的资源文件,可以设置界面展示,同时 xml 配置里可以引入 css 文件、设置元素大小等
四、代码讲解
1. login.fxml 配置
在 maven 管理下我们将配置文件放到资源文件夹下;fxml/login/login.fxml
整体外框 xml
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.text.Font?>
<Pane id="login" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
prefWidth="540" prefHeight="415" stylesheets="@css/login.css" xmlns="http:///javafx/8.0.121"
xmlns:fx="http:///fxml/1">
<children>
</children>
</Pane>
- 这是一个整体的面板,初步设定了面板的宽高、引入的 css 样式等
- 接下来在 children 孩子元素集合里添加各种窗体元素
操作栏;最小化、关闭(Pane)
<Pane id="operation" prefWidth="540" prefHeight="158">
<children>
<Label id="login_logo" styleClass="logo" layoutX="10" layoutY="5" prefWidth="200" prefHeight="15" text="憨憨 · 语约" style="-fx-text-fill:#666666;"/>
<Button id="login_min" styleClass="min" layoutX="454" prefWidth="43" prefHeight="32"/>
<Button id="login_close" styleClass="close" layoutX="497" prefWidth="43" prefHeight="32"/>
</children>
</Pane>
- 定义一个 Pane,并设置宽高,之后在整个面板里中添加 logo、最小化、关闭操作
- 后面你会看到更多的
<children>
,来装载元素 - 在孩子元素中有三个元素;
- login_logo 定义 logo 和文案,这里默认显示文字“憨憨 · 语约”
- login_min 最小化按钮处理
- login_close 关闭操作处理
头像(Pane)
<Pane id="headImg" layoutX="80" layoutY="200" prefWidth="100" prefHeight="100"/>
- 这个是定义一个头像区域,也可以使用其他元素进行定义
用户 ID 输入框(TextField)
<TextField id="userId" layoutX="200" layoutY="200" prefWidth="250" prefHeight="45" promptText="账号">
<padding>
<Insets left="10"/>
</padding>
</TextField>
- TextField 是一个单行明文内容输入区域,在这里不仅设置了宽高,还设置了相对位置;layoutX、layoutY
- padding.Insets,如果你写过 CSS,可能会知道。这是一个设置输入框内,文字输入区域距离左面的空出位置。一般空出的位置可以设置一个背景图片
- 同时我们设置了提示文字,这个在这里比较简单直接使用;promptText 即可。例如:
promptText="账号"
密码输入框(PasswordField)
<PasswordField id="userPassword" layoutX="200" layoutY="255" prefWidth="250" prefHeight="45" promptText="密码">
<padding>
<Insets left="10"/>
</padding>
</PasswordField>
- PasswordField 是一个单行密码内容输入区域,同样设置了宽高,以及提示文字
- 基本的使用方式与 TextField 一致,当然在你后面后去他里面内容的时候,是明文的
登陆按钮(Button)
<Button id="login_button" styleClass="login_button" layoutX="200" layoutY="345" prefWidth="250" prefHeight="45" text="登 陆"/>
- Button 按钮类的操作都可以使用,在这里设置好宽高,以及文字内容
text="登 陆"
- 同样在这里我们也设置了相对的展示位置,这个位置是相对的,相遇对当前父元素
版本(Label)
<Label id="slogan" layoutX="5" layoutY="398" prefWidth="400" prefHeight="15"
text="v1.0 小傅哥 | https://">
<font>
<Font size="12"/>
</font>
</Label>
- Label 一般可以设置文字、图片等展示内容。是一个轻量级元素
- 在这里我们设置了版本编号,和自己一些内容信息
- 同时我们还设置了字体的大小,关于字体后面我们还会使用到 css(这里的 css 是 javafx 的 css,除名称不同外基本一致)
2. login.css 设计
#login{
-fx-background-radius: 4px;
-fx-border-width: 1px;
-fx-border-radius: 4px;
-fx-border-color: rgb(180,180,180);
-fx-background-color: white;
}
#operation{-fx-border-color: rgb(180,180,180);
-fx-border-width: 1px 1px 0 1px;
-fx-border-radius: 4px 4px 0 0;
-fx-background-image: url("/fxml/login/img/system/show.png");
}
.close,.close:pressed{
-fx-background-radius: 2px;
-fx-background-position: center center;
-fx-background-repeat: no-repeat;
-fx-background-size: 43px 34px;
-fx-background-color: transparent;
-fx-background-image: url("/fxml/login/img/system/close_0.png");
-fx-cursor: hand;
-fx-border-width: 0;
}
.close:hover{
-fx-background-color: #f45454;
-fx-background-image: url("/fxml/login/img/system/close_1.png");
-fx-border-width: 1px 1px 0 0;
-fx-border-color: rgb(180,180,180);
-fx-border-radius: 2px;
}
...
- 从上面可以看到基本和我们认识的 css 代码一致,在这里我们就不全部展示这部分内容了
- 一些基本的 javafx 中的 css 常用语法我们在第一篇中已经介绍,可以参考。很常用的包括;背景色、线条色、宽高、图片、圆角、悬停手势等。
3. 代码模块
Login.java & 登陆页面初始化
public class Login extends Stage {
private static final String RESOURCE_NAME = "/fxml/login/login.fxml";
private Parent root;
public Login() {
try {root = FXMLLoader.load(getClass().getResource(RESOURCE_NAME));
} catch (IOException e) {e.printStackTrace();
}
Scene scene = new Scene(root);
scene.setFill(Color.TRANSPARENT);
setScene(scene);
initStyle(StageStyle.TRANSPARENT);
setResizable(false);
this.getIcons().add(new Image("/fxml/login/img/system/logo.png"));
}
}
单个窗体的需要继承 Stage,也就是继承了窗口类,并需要在里面创建场景,才可以运行展示
在这里我们加载配置元素 login.fxml
,初始化窗体的基本信息
在布局中我们设置了填充为透明色,以及初始化样式 StageStyle.TRANSPARENT
最后我们设置了状态栏的图标样式,这里我们设置了模仿微信的样式,颜色略有差异
this.getIcons().add(new Image("/fxml/login/img/system/logo.png"));
Application.java & 启动类
public class Application extends javafx.application.Application{
@Override
public void start(Stage primaryStage) throws Exception {Login login = new Login();
login.show();}
public static void main(String[] args) {launch(args);
}
}
这里的 Application 继承了 JavaFx 的 Application,并实现 start 启动
在这里我们初始化登陆窗体,并通过 login.show()
调用窗体的展现
上面这个结构是一个固定的模板代码,也是配置到 maven 中的启动类路径;
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
<mainClass>org.itstack.navice.chat.ui.Application</mainClass>
</configuration>
</plugin>
五、效果演示
在类org.itstack.navice.chat.ui.Application
,右键运行
不出意外效果如下;

六、总结
- 在这一篇中我们显示拆解分析了整个窗体需要实现的功能,之后逐步使用 JavaFx 去把 UI 搭建处理。在这里使用到了代码、XML、CSS,三个技术的配合工作。
- 通过上面的工程和代码可以初步的了解到一个简单的窗体的搭建和使用,并且设计了我们的工程结构,一个好的开始就从现在开始了
- 同时如果你细心可能会发现我们的工程其实是在打一个 jar 包,将来共客户端使用,最后也就达到了 UI 与业务分离,这部分会随着后续章节逐步展现