使用JavaFX设计一个注册和登录GUI
JavaFX是一个开源的Java框架,用于创建、开发和交付可移植的硬件加速的用户界面。JavaFX为富互联网应用(RIA)创建GUI。
它适用于网络、桌面、嵌入式和移动应用。例如,它的一个用途是用于登录和注册的形式。这些都有一个独特的设计,使网站具有展示性和独特的设计。
在这篇文章中,你将学习如何构建一个JavaFX登录和注册的用户界面(UI)。
主要收获
在本文结束时,你将获得以下知识。
- 什么是JavaFX
- JavaFX库
- 建立一个JavaFX项目
- 设计登录和注册表格
- 运行应用程序
先决条件
这篇文章的基础知识包括以下内容。
- 对Java语言的了解和使用。
- 在机器中设置了一个Java IDE。我推荐最新版本的IntelliJ IDEA社区版,它是免费的,互动性很强。
- 一个稳定的网络连接。
文章中的截图图片是Intellij Ultimate
2021.2.2
版本的。
什么是JavaFX
如上所述,JavaFX是一个创建用户界面的框架,用于基于WIMP(Windows、图标、菜单和指针)的系统。
它适用于带有用户界面的Java应用程序。它很容易使用,在设计过程和测试过程中,它有几个工具和辅助工具。
UI是用Java或XML设计的。
FXML文件是用于设计和建立与主要应用逻辑分离的用户界面的XML文件。这种分离使人们能够区分用户界面文件和主应用程序的文件。
在本教程中,你将与它互动,为你的应用程序开发一个可视化界面。
JavaFX库
JavaFX中的库为人们提供了所需的控件、菜单、容器和其他元素。
这种提供是不包含不必要的额外元素和属性的。
应用程序的存储空间很小,因为它只拥有需要的东西。
这些库中的一些及其功能包括。
- ControlsFX:为开发者提供控件,如按钮、复选框、单选按钮、标签、文本、密码栏等。
- BootstrapFX:为程序提供CSS样式,为JavaFX应用程序设计。它对应用程序中的控件和其他元素进行格式化。
- FormFX:它有助于快速创建和设计表单。它包含验证、预定义控件和本地化工具等功能。这些都是为了减少创建方法来验证表单中的参数所需的时间。
- Ikonli: 有一个图标包的列表,便于在应用程序中使用。
- TilesFX:它使设计者能够使用瓷砖来增强应用程序的外观,例如在仪表盘上。
- ValidatorFX:这使得应用程序中的表格变得非常容易。
- FXGL:这是为游戏开发者准备的。它有用于开发游戏的工具。
- 图表:当人们想创建科学图表时,建议使用这个工具。它有令人惊叹的图表模板,供人们通过快速操作使用。
设置一个JavaFX项目
简单的JavaFX Hello应用程序
打开IDE,点击创建一个新项目。接下来,在打开的窗口的左侧选择JavaFX。
在文本字段中,按如下方式填写。
Name
: loginformGroup
: 登录Artifact
:loginform
这一步显示在下面的图片中。
点击 "下一步",进入下一个窗口。在依赖性窗口中,选择BootstrapFX、ControlsFx和FormsFX。
这一步如下图所示。
完成后创建一个新的项目。
文件夹结构
项目的文件夹将如下图所示。
.
├── src
│ └── main
│ ├── java
│ └── com.login.loginform
│ ├── HelloApplication.java
│ └── HelloController.java
│ └── resources
│ └── com.login.loginform
│ └── hello-view.fxml
├── loginform.iml
└── pom.xml
打开在src/main/java/com/login/loginform/ 里面找到的HelloApplication.java
文件。使用Shift + F10
运行它。
这个组合打开了一个新的*Hello!*窗口,点击按钮可以显示文本。
它看起来如下。
修改它以适应所选择的应用程序。
设置一个JavaFX场景构建器
关闭打开的窗口,到资源文件夹中去。
在随后的子文件夹中,打开hello-view.fxml
。
在窗口的底部,选择Scene Builder,使用JavaFX ScreenBuilder查看文件。
如果由于缺少Scene Builder而出现错误,请点击下载Scene Builder,如下图所示。等待它完成这一过程。
几分钟后,它将打开场景生成器,并查看应用程序运行时的样子。
它看起来如下图所示。
注意:Scene Builder也可以从IntelliJ IDEA环境中单独安装。
建立登录和注册表格
改变舞台的外观
首先,改变窗口的标题,然后增加其大小。
在HelloApplication.java
文件中,将其标题从Hello!改为Login or Sign-Up Form!。
将尺寸改为1000乘700,即宽度和高度。
它看起来会如下图所示。
package com.login.loginform;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 1000, 700);
stage.setTitle("Login or Sign-Up Form!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
定制用户界面
在hello-view.fxml
文件中,使用场景构建器查看。在左侧,删除包含标签和按钮的VBox,正如在应用程序中看到的那样。
通过从容器部分拖拽到VBX所在的窗口,添加一个边框窗格。边框窗格允许人们很容易地将控件放在窗口的顶部、左侧、右侧、中央和底部。这一步将有助于划分窗口。
现在从容器部分拖放一个AnchorPane到边界窗格的左边。
在右侧的属性窗口中,在样式中,输入CSS样式属性。它将是-fx-background-color
,并把数值放在它旁边,成为#A9A9A9
。
在布局选项卡中,将Pref Width
和Pref Height
分别设置为400和700。
旁白
前往左侧的控件标签。
将一个ImageView控件拖到AnchorPane中。
在属性标签下的布局标签,将其Fit Width
和Fit Height
设置为400。
为了使它几乎处于AnchorPane的中心位置,将Layout X
和Layout Y
的值分别设置为0和180。
将图像复制到资源文件夹中,到hello-view.fxml
文件的位置。在属性标签中,将图像名称设为logo.png。
现在前往BorderPane的右侧,拖放另一个AnchorPane。将其Pref Width
和Pref Height
分别设置为600和700。这一步使左右BorderPane部分符合初始高度。
代码在查看时应如图所示。
<?xml version="1.0" encoding="UTF-8"?>
<!-- Main Borderpane start -->
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="700.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.login.login.HelloController">
<!-- Beginning of the left part of the Borderpane -->
<left>
<!-- An AnchorPane in the Left BorderPane -->
<AnchorPane prefHeight="700.0" prefWidth="400.0" style="-fx-background-color: #A9A9A9;" BorderPane.alignment="CENTER">
<children>
<!-- Logo -->
<ImageView fitHeight="400.0" fitWidth="400.0" layoutY="180.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@logo.png" />
</image>
</ImageView>
</children>
</AnchorPane>
</left>
<!-- Ending of the left part of the Borderpane -->
<!-- Beginning of the right part of the Borderpane -->
<right>
<AnchorPane prefHeight="700.0" prefWidth="600.0" BorderPane.alignment="CENTER">
</AnchorPane>
</right>
<!-- Ending of the right part of the Borderpane -->
<!-- Beginning of the bottom part of the Borderpane -->
<bottom>
</bottom>
<!-- Ending of the bottom part of the Borderpane -->
</BorderPane>
在AnchorPane内,添加以下内容。
一个标题
ImageView
这个控件中会有一个小的购物车标志。
- 属性。
Image
: cart.png
- 布局。
Fit Width
:100Fit Height
:55Layout X
:120Layout Y
:5
标签
- 属性。
Text
:现在购买Font
:SanSerif 25px
- 风格。
-fx-background-color
: 透明-fx-text-fill
:#24a0ed
要添加更多的样式,请点击样式部分的添加按钮。
- 布局。
Pref Width
: 263Pref Height
:57Layout X
: 203Layout Y
:1
钮扣
- 属性。
Text
:取消Font
:SanSerif 15px
- 风格。
-fx-background-color
: 透明-fx-text-fill
:#A9A9A9-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Layout X
:502Layout Y
:13
它的结果是下面的代码。
<right>
<AnchorPane prefHeight="700.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<children>
<!-- The Beginning of Logo -->
<ImageView fitHeight="55.0" fitWidth="100.0" layoutX="120.0" layoutY="5.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@cart.png" />
</image>
</ImageView>
<Label layoutX="203.0" layoutY="1.0" prefHeight="57.0" prefWidth="263.0" style="-fx-background-color: transparent; -fx-text-fill: #24a0ed;" text="SHOP TODAY">
<font>
<Font name="SansSerif Regular" size="25.0" />
</font>
</Label>
<!-- The End of Logo -->
</children>
</AnchorPane>
</right>
登录部分
标签
- 属性。
Text
:登录Font
:SanSerif 30px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Pref Width
: 90Pref Height
:30Layout X
: 244Layout Y
: 60
图像视图
- 属性。
Image
: users.png
- 布局。
Fit Width
:35Fit Height
:40Layout X
:110Layout Y
:100
文本字段
- 属性。
Prompt Text
:用户名/电子邮件Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:150Layout Y
:100
密码字段
- 属性。
Prompt Text
:密码Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:150Layout Y
:140
图像视图
- 属性。
Image
: lock.png
- 布局。
Fit Width
:35Fit Height
:40Layout X
:110Layout Y
:140
复选框
- 属性。
Text
:记住我Font
:SanSerif 15px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:150Layout Y
:195
按钮
- 属性。
Text
:登录Font
:SanSerif 15px
- 风格。
-fx-background-color
: 24a0ed-fx-text-fill
:白字-fx-border-radius
:5-fx-border-width
: 2-fx-border-radius
:5-fx-border-color
:#24a0ed
- 布置。
Layout X
:335Layout Y
:195
按钮
- 属性。
Text
:忘记密码?Font
:SanSerif 15px
- 风格。
-fx-background-color
: 透明-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:190Layout Y
: 235
场景构建器产生以下代码。
<!-- The Beginning of Login form -->
<Label layoutX="244.0" layoutY="60.0" prefHeight="30.0" prefWidth="90.0" style="-fx-text-fill: #A9A9A9;" text="Login">
<font>
<Font name="SansSerif Regular" size="30.0" />
</font>
</Label>
<!-- Cancel Button -->
<Button fx:id="cancelButton" layoutX="502.0" layoutY="13.0" mnemonicParsing="false" style="-fx-background-color: transparent; -fx-text-fill: #A9A9A9; -fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;" text="Cancel">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</Button>
<!-- Inputs -->
<TextField fx:id="loginUsernameTextField" layoutX="150.0" layoutY="100.0" prefHeight="30.0" prefWidth="300.0" promptText="Username / Email" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</TextField>
<ImageView fitHeight="40.0" fitWidth="35.0" layoutX="110.0" layoutY="100.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@users.png" />
</image>
</ImageView>
<PasswordField fx:id="loginPasswordPasswordField" layoutX="150.0" layoutY="140.0" prefHeight="30.0" prefWidth="300.0" promptText="Password" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</PasswordField>
<ImageView fitHeight="40.0" fitWidth="35.0" layoutX="110.0" layoutY="140.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@lock.png" />
</image>
</ImageView>
<CheckBox layoutX="150.0" layoutY="195.0" mnemonicParsing="false" style="-fx-text-fill: #A9A9A9;" text="Remember Me">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</CheckBox>
<!-- Forgot your password button -->
<Button layoutX="190.0" layoutY="235.0" mnemonicParsing="false" style="-fx-background-color: transparent; -fx-text-fill: #Aac9A9A9;" text="Forgot your Password?" underline="true">
<font>
<Font size="15.0" />
</font>
</Button>
<!-- Login Button -->
<Button fx:id="LoginButton" layoutX="335.0" layoutY="195.0" mnemonicParsing="false" style="-fx-background-color: #24a0ed; -fx-text-fill: white; -fx-border-radius: 5; -fx-border-width: 2; -fx-border-color: #24a0ed;" text="Login">
<font>
<Font size="15.0" />
</font>
</Button>
<!-- End of Login Form -->
换行
线条
这个元素是来自形状部分
- 属性。
Fill
:深灰色Stroke
:#a8a8a8Smooth
选项。检查
这个属性是用于淡化效果。
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:0Layout Y
: -110Start X
:100Start Y
:380End X
:500End Y
:380
其产生的代码如图所示。
<!-- A simple line Separator -->
<Line endX="500.0" endY="380.0" fill="DARKGRAY" layoutY="-110.0" startX="100.0" startY="380.0" style="-fx-text-fill: #A9A9A9;" strokeWidth="3.0" />
注册部分
标签
- 属性。
Text
:注册Font
:SanSerif 30px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Pref Width
:130Pref Height
:36Layout X
: 230Layout Y
: 275
图像视图
- 属性。
Image
: users.png
- 布局。
Fit Width
:35Fit Height
:40Layout X
:110Layout Y
:320
文本字段
- 属性。
Prompt Text
:用户名Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:155Layout Y
:320
图像视图
- 属性。
Image
: email.png
- 布局。
Fit Width
:35Fit Height
:40Layout X
:110Layout Y
:360
文本字段
- 属性。
Prompt Text
:电子邮件Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:155Layout Y
:360
密码字段
- 属性。
Prompt Text
:密码Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:155Layout Y
:400
图像视图
- 属性。
Image
: lock.png
- 布局。
Fit Width
:35Fit Height
:40Layout X
:110Layout Y
:400
密码字段
- 属性。
Prompt Text
:重复密码Font
:SanSerif 14px
- 风格。
-fx-border-width
: 2-fx-border-color
:#A9A9A9-fx-border-radius
:5
- 布置。
Pref Width
:300Pref Height
:30Layout X
:150Layout Y
:440
标签
- 属性。
Text
:出生日期Font
:SanSerif 15px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Pref Width
:105Pref Height
: 20Layout X
:130Layout Y
:480
日期选择器(DatePicker
- 属性。
Prompt Text
: mm/dd/yyyyEditable
复选框。勾选Show Week number
复选框。勾选
启用它们可以让人在不使用日期选择器的情况下向该领域输入数据。它还能显示周数。
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
: 250Layout Y
:480
标签
- 属性。
Text
:性别Font
:SanSerif 15px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Pref Width
: 90Pref Height
: 20Layout X
:130Layout Y
:515
单选按钮
- 属性。
Text
:男Font
:SanSerif 14pxSelected
复选框。检查Toggle Group
:性别
这一步将对同一组的单选按钮进行分组,因此每个实例只选择一个。
- 样式。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:300Layout Y
:515
单选按钮
- 属性。
Text
:女Font
:SanSerif 14pxToggle Group
:性别
这一步将同一组的单选按钮分组,因此每个实例只能选择一个。
- 样式。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:390Layout Y
:515
复选框
- 属性。
Text
:我已经阅读了条款和条件Font
:SanSerif 15px
- 风格。
-fx-text-fill
:#A9A9A9
- 布局。
Layout X
:160Layout Y
:545
按钮
- 属性。
Text
:注册Font
:SanSerif 15px
- 风格。
-fx-background-color
:#24a0ed-fx-text-fill
:白-fx-border-radius
:5-fx-border-width
: 2-fx-border-color
:#24a0ed
- 布置。
Pref Width
:130Pref Height
:33Layout X
: 230Layout Y
: 615
按钮
- 属性。
Text
:条款和条件Font
:SanSerif 15px
- 风格。
-fx-background-color
: 透明-fx-text-fill
:#A9A9A9
- 布局。
Layout X
: 230Layout Y
: 660
其代码显示如下。
<!-- The Beginning of Signup form -->
<Label layoutX="230.0" layoutY="275.0" prefHeight="36.0" prefWidth="130.0" style="-fx-text-fill: #A9A9A9;" text="Sign-Up">
<font>
<Font name="SansSerif Regular" size="30.0" />
</font>
</Label>
<!-- User Inputs -->
<TextField fx:id="signUpUsernameTextField" layoutX="155.0" layoutY="320.0" prefHeight="30.0" prefWidth="300.0" promptText="Username" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</TextField>
<ImageView fitHeight="40.0" fitWidth="35.0" layoutX="110.0" layoutY="320.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@users.png" />
</image>
</ImageView>
<TextField fx:id="signUpEmailTextField" layoutX="155.0" layoutY="360.0" prefHeight="30.0" prefWidth="300.0" promptText="Email" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
<cursor>
<Cursor fx:constant="TEXT" />
</cursor>
</TextField>
<ImageView fitHeight="40.0" fitWidth="35.0" layoutX="110.0" layoutY="360.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@email.png" />
</image>
</ImageView>
<PasswordField fx:id="signUpPasswordPasswordField" layoutX="155.0" layoutY="400.0" prefHeight="30.0" prefWidth="300.0" promptText="Password" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</PasswordField>
<ImageView fitHeight="40.0" fitWidth="35.0" layoutX="110.0" layoutY="400.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@lock.png" />
</image>
</ImageView>
<PasswordField fx:id="signUpRepeatPasswordPasswordField" layoutX="155.0" layoutY="440.0" prefHeight="30.0" prefWidth="300.0" promptText="Repeat Password" style="-fx-border-width: 2; -fx-border-color: #A9A9A9; -fx-border-radius: 5;">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</PasswordField>
<Label layoutX="130.0" layoutY="480.0" prefHeight="20.0" prefWidth="105.0" style="-fx-text-fill: #A9A9A9;" text="Date of Birth">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</Label>
<DatePicker fx:id="signUpDateDatePicker" layoutX="250.0" layoutY="480.0" promptText="mm/dd/yyyy" showWeekNumbers="true" />
<Label layoutX="130.0" layoutY="515.0" prefHeight="20.0" prefWidth="90.0" style="-fx-text-fill: #A9A9A9;" text="Gender">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</Label>
<RadioButton layoutX="300.0" layoutY="515.0" mnemonicParsing="false" selected="true" text="Male" style="-fx-text-fill: #A9A9A9;">
<toggleGroup>
<ToggleGroup fx:id="Gender" />
</toggleGroup>
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</RadioButton>
<RadioButton layoutX="390.0" layoutY="515.0" mnemonicParsing="false" text="Female" style="-fx-text-fill: #A9A9A9;" toggleGroup="$Gender">
<font>
<Font name="SansSerif Regular" size="14.0" />
</font>
</RadioButton>
<CheckBox fx:id="termsConditionsCheckbox" layoutX="160.0" layoutY="545.0" mnemonicParsing="false" selected="true" style="-fx-text-fill: #A9A9A9;" text="I have read the Terms and Conditions">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</CheckBox>
<!-- Sign up button -->
<Button fx:id="signUpButton" layoutX="230.0" layoutY="615.0" mnemonicParsing="false" prefHeight="33.0" prefWidth="130.0" style="-fx-background-color: #24a0ed; -fx-text-fill: white; -fx-border-radius: 5; -fx-border-width: 2; -fx-border-color: #24a0ed;" text="Sign-Up">
<font>
<Font name="SansSerif Regular" size="15.0" />
</font>
</Button>
<Button layoutX="230.0" layoutY="660.0" mnemonicParsing="false" style="-fx-background-color: transparent; -fx-text-fill: #A9A9A9;" text="Terms and Conditions" underline="true">
<font>
<Font size="15.0" />
</font>
</Button>
<!-- The End of Signup form -->
页脚
在页脚部分,你将添加你的版权。在主BorderPane的底部拖放一个标签控件。
这个标签将有以下属性:Text
:商店© 2021。
设置以下样式:-fx-text-fill
:#B9a9a9。
它将有以下布局:Pref Width
:107,Pref Height
: 16.
FXML代码将看起来如下所示。
<!-- Beginning of the bottom part of the Borderpane -->
<bottom>
<!-- Simple Copyright -->
<Label prefHeight="16.0" prefWidth="107.0" style="-fx-text-fill: #B9a9a9;" text="Shop © 2021" BorderPane.alignment="CENTER" />
</bottom>
<!-- Ending of the bottom part of the Borderpane -->
注意:根据你的项目名称和机器,路径可能会有所不同。如果控件和其他元素是用代码添加的,请确保将它们导入项目中。
运行应用程序
像以前一样使用Shift + F10
快捷方式运行该应用程序。结果如下图所示。
总结
在本指南中,你已经学会了。
- 什么是JavaFX
- JavaFX库
- 建立一个简单的JavaFX项目
- 设计登录和注册的表格
- 运行该应用程序