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

界面设计

仿微信聊天程序的注册界面,是一个表单,由三个输入框和一个按钮组成,具体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 2023-07-16 13:32  ql1710  阅读(43)  评论(0编辑  收藏  举报