从本章节开始我们会陆续实现各个框体的 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 | 展示名称,例如;憨憨·语约 |
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
在 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.com/javafx/8.0.121"
xmlns:fx="http://javafx.com/fxml/1">
<children>
</children>
</Pane>
操作栏;最小化、关闭(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>
<children>
,来装载元素头像(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>
promptText="账号"
密码输入框(PasswordField)
<PasswordField id="userPassword" layoutX="200" layoutY="255" prefWidth="250" prefHeight="45" promptText="密码">
<padding>
<Insets left="10"/>
</padding>
</PasswordField>
登陆按钮(Button)
<Button id="login_button" styleClass="login_button" layoutX="200" layoutY="345" prefWidth="250" prefHeight="45" text="登 陆"/>
text="登 陆"
版本(Label)
<Label id="slogan" layoutX="5" layoutY="398" prefWidth="400" prefHeight="15"
text="v1.0 小傅哥 | https://bugstack.cn">
<font>
<Font size="12"/>
</font>
</Label>
#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;
}
...
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
,右键运行
不出意外效果如下;
联系客服