随笔 - 59,  文章 - 1,  评论 - 0,  阅读 - 24152

本文是仿微信聊天程序专栏的第二篇文章,主要记录了【注册界面】的实现。

界面设计

仿微信聊天程序的注册界面,是一个表单,由三个输入框和一个按钮组成,具体UI展示如下图所示:

界面布局

页面布局使用fxml,采用VBox从上到下布局,中间的表单使用formsfx,所以只需要预留一个StackPane给表单即可。

<VBox alignment="CENTER" prefHeight="350.0" prefWidth="480.0" spacing="10.0"
stylesheets="@/css/bootstrapfx.css"
xmlns:fx="http://javafx.com/fxml" fx:controller="michong.javafx.wx.view.register.RegisterController">
<children>
<HBox alignment="CENTER_LEFT">
<children>
<Label text="注册" styleClass="h3,b"/>
<Pane HBox.hgrow="ALWAYS"/>
<Label text="使用账号"/>
<Hyperlink text="登录" onAction="#onLoginClick"/>
</children>
<padding>
<Insets left="20.0" right="20.0"/>
</padding>
</HBox>
<StackPane fx:id="formStackPane"/>
<Button minWidth="120" text="注册" styleClass="btn-primary" onAction="#onRegisterClick"/>
</children>
<padding>
<Insets bottom="30.0" left="30.0" right="30.0" top="5.0"/>
</padding>
</VBox>

表单构建

表单使用的是开源库formfx,其maven坐标如下:

<dependency>
<groupId>com.dlsc.formsfx</groupId>
<artifactId>formsfx-core</artifactId>
<version>1.3.1</version>
</dependency>

表单构建实现如下:

/**
* @author michong
*/
public class RegisterForm {
private final RegisterVO vo = new RegisterVO();
private Form form;
private FormRenderer renderer;
private RegisterForm() {
}
public static RegisterForm getInstance() {
RegisterForm rf = new RegisterForm();
rf.build();
return rf;
}
private void build() {
// @formatter:off
String nickname = "昵称";
String username = "账号";
String password = "密码";
String placeholderTextFmt = "请输入%s";
String requiredTextFmt = "%s必填";
form = Form.of(
Group.of(
Field.ofStringType(vo.nicknameProperty())
.label(nickname)
.placeholder(String.format(placeholderTextFmt, nickname))
.required(String.format(requiredTextFmt, nickname)),
Field.ofStringType(vo.usernameProperty())
.label(username)
.placeholder(String.format(placeholderTextFmt, username))
.required(String.format(requiredTextFmt, username)),
PasswordField.ofPasswordType(vo.passwordProperty())
.label(password)
.placeholder(String.format(placeholderTextFmt, password))
.required(String.format(requiredTextFmt, password))
)
);}
// @formatter:on
renderer = new FormRenderer(form);
}
}

这里的RegisterVO是一个普通的JavaBean,用于双向绑定表单数据:

public class RegisterVO {
private final StringProperty nickname = new SimpleStringProperty("");
private final StringProperty username = new SimpleStringProperty("");
private final StringProperty password = new SimpleStringProperty("");
public String getNickname() {
return nickname.get();
}
public StringProperty nicknameProperty() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname.set(nickname);
}
// 省略其他GETTER和SETTER
}

事件处理

在界面布局中,fxml绑定的controller为RegisterController,RegisterController主要负责UI的初始化和事件处理,其中:

  • initializeUI():实现UI的初始化(其中部分UI直接使用变量绑定fxml的UI,如:formStackPane)
  • initializeEvent():实现事件的初始化(其中部分事件使用方法绑定fxml的action,如onLoginClick和onRegisterClick)
public class RegisterController implements Initializable {
public StackPane formStackPane;
private RegisterForm form;
@Override
public void initialize(URL location, ResourceBundle resources) {
initializeUI();
initializeEvent();
}
void initializeUI() {
form = RegisterForm.getInstance();
formStackPane.getChildren().add(form.getRenderer());
}
void initializeEvent() {
}
public void onLoginClick(ActionEvent actionEvent) {
FX.error("功能开发中...");
}
public void onRegisterClick(ActionEvent actionEvent) {
form.getForm().persist();
if (form.getForm().isValid()) {
FX.info(form.getVO().getUsername() + "注册成功");
}
}
}

这里事件处理没有实现具体的业务,只是做一个提示,后续业务功能完善后,会继续改造这部分的功能。

启动流程

主程序实现:

public class App extends Application {
@Override
public void start(Stage primaryStage) {
AppStarter.start(primaryStage);
}
public static void main(String[] args) {
launch(args);
}
}

启动类实现:

/**
* @author michong
*/
public class AppStarter {
public static void start(Stage primaryStage) {
FXContext.setPrimaryStage(primaryStage);
Parent root = FX.fxml(RegisterController.class);
primaryStage.setScene(new Scene(root));
primaryStage.getIcons().clear();
primaryStage.getIcons().add(FXIcon.logo());
primaryStage.setResizable(false);
primaryStage.show();
}
}
posted on   $$X$$  阅读(64)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)

点击右上角即可分享
微信分享提示