首先使用IDEA创建一个普通的JavaFX项目,并按照下图创建文件夹。

接着是引入要使用的第三方包,需要用到的包在file文件夹下的jar包中,引入即可。

在引入成功后,数据库表的创建已经在第二节文章中讲述了,并且file文件夹下的sql包中存在着可以直接执行的SQL语句,以此来创建数据库表。

第一步:根据数据库表结构创建实体类,如下图所示。

同时tools包下有两个在项目中要使用到的工具类DateTools.java和SimpleTools.java。

这些文件都在源码中,不在此写明。

第二步:在view包下创建一个名为logupFrame.fxml的视图文件并通过Scene Builder进行设计。

(关于fxml文件中各个控件的属性配置和事件设定都可以使用Scene Builder进行查看,不在此处一一说明)。

<?xml version="1.0" encoding="UTF-8"?>
​
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.*?>
<HBox alignment="CENTER" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8"xmlns:fx="http://javafx.com/fxml/1" fx:controller="AccountSystem.controller.LogupFrameController"><children><VBox alignment="CENTER" prefHeight="371.0" prefWidth="327.0" spacing="20.0"><children><HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0"><children><ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true"><image><Image url="@../images/welcome.png"/></image></ImageView></children></HBox><HBox alignment="CENTER" prefHeight="12.0" prefWidth="327.0" spacing="15.0"><children><Label fx:id="nameLabel" contentDisplay="CENTER" styleClass="class_label" text="昵称:"textAlignment="CENTER" textOverrun="CENTER_WORD_ELLIPSIS"/><TextField fx:id="nameTextField" promptText="请填入您的昵称:" styleClass="class_textField"/></children></HBox><HBox alignment="CENTER" prefHeight="0.0" prefWidth="327.0" spacing="15.0"><children><Label fx:id="passwordLabel" contentDisplay="CENTER" styleClass="class_label" text="密码:"textAlignment="CENTER" textOverrun="CENTER_WORD_ELLIPSIS"/><PasswordField fx:id="passwordTextField" promptText="请填入您的密码:" styleClass="class_textField"/></children></HBox><HBox alignment="CENTER" prefHeight="21.0" prefWidth="327.0" spacing="25.0"><children><Button fx:id="loginButton" mnemonicParsing="false" onAction="#loginButtonEvent"styleClass="class_button" text="注册"/><Button fx:id="logupButton" mnemonicParsing="false" onAction="#logupButtonEvent"styleClass="class_button" text="登录"/></children></HBox></children><opaqueInsets><Insets/></opaqueInsets><HBox.margin><Insets/></HBox.margin></VBox></children>
</HBox>

接着是在controller包创建LogupFrameController.java即是登录界面fxml文件对应的控制器类,并且从Scene Builder中将对应界面的控件属性复制到该类中。

package AccountSystem.controller;
​
import AccountSystem.bean.Session;
import AccountSystem.bean.User;
import AccountSystem.dao.UserDao;
import AccountSystem.tools.SimpleTools;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
​
/*** 登录控制器** @author lck100*/
public class LogupFrameController {
​@FXMLprivate PasswordField passwordTextField;
​@FXMLprivate TextField nameTextField;
​/*** “注册”按钮事件监听器*/@FXMLvoid loginButtonEvent() {}
​/*** “登录”按钮事件监听器*/@FXMLvoid logupButtonEvent() {}
​
}

接着是在MainApp类中将代码改为如下,即启动程序。

package AccountSystem;
​
import AccountSystem.controller.LogupFrameController;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
​
import java.io.IOException;
​
public class MainApp extends Application {
​@FXMLprivate Stage primaryStage;
​@FXMLprivate HBox rootLayout;
​@Overridepublic void start(Stage primaryStage) {this.primaryStage = primaryStage;this.primaryStage.setTitle("管家婆系统");initLogupFrame();}
​/*** 操作结果:登录界面*/private Scene initLogupFrame() {try {FXMLLoader loader = new FXMLLoader();loader.setLocation(getClass().getResource("view/logupFrame.fxml"));rootLayout = (HBox) loader.load();
​Scene scene = new Scene(rootLayout);primaryStage.setScene(scene);primaryStage.setResizable(false);
​LogupFrameController controller = loader.getController();controller.setLogupStage(primaryStage);
​primaryStage.show();return scene;} catch (IOException e) {e.printStackTrace();}return null;}
​public static void main(String[] args) {launch(args);}
​
}

同时在LogupFrameController中添加如下代码,创建Stage属性,来传递stage以便用来在登录成功后关闭登录stage。

    private Stage logupStage;
​public Stage getLogupStage() {return logupStage;}
​public void setLogupStage(Stage logupStage) {this.logupStage = logupStage;}

运行程序,出现如下界面,但是如果点击“注册”和“登录”按钮没有任何事件处理。

所以要为注册和登录按钮添加事件处理,由于需要使用数据库,所以在dao包下创建JDBCUtils.java和UserDao.java类。其中JDBCUtils.java类是数据库链接和释放资源公共方法类,而UserDao.java类是处理用户的注册、登录及增删改查和数据库备份恢复的操作类。

JDBCUtils.java

package AccountSystem.dao;
​
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
​
/*** 连接JDBC类*/
public class JDBCUtils {/*** 加载驱动,并建立数据库连接** @return 返回数据库链接对象* @throws SQLException           抛出SQLException* @throws ClassNotFoundException 抛出ClassNotFoundException* @throws IOException            抛出IOException*/static Connection getConnection() throws SQLException, ClassNotFoundException, IOException {// 实例化Properties对象Properties properties = new Properties();// 加载properties配置文件properties.load(new FileInputStream(new File("src\\AccountSystem\\properties\\db.properties")));// 通过键名获取对应的值String driverName = properties.get("driverName").toString();String url = properties.get("url").toString();String user = properties.get("user").toString();String password = properties.get("password").toString();// 数据库驱动Class.forName(driverName);// 获取数据库链接对象Connection connection = DriverManager.getConnection(url, user, password);return connection;}
​/*** 关闭数据库连接,释放资源** @param stmt Statement对象* @param conn Connection对象*/static void release(Statement stmt, Connection conn) {if (stmt != null) {try {stmt.close();} catch (SQLException e) {e.printStackTrace();}stmt = null;}if (conn != null) {try {conn.close();} catch (SQLException e) {e.printStackTrace();}conn = null;}}
​/*** 关闭数据库连接,释放资源** @param rs   ResultSet对象* @param stmt Statement对象* @param conn Connection对象*/static void release(ResultSet rs, Statement stmt, Connection conn) {if (rs != null) {try {rs.close();} catch (SQLException e) {e.printStackTrace();}rs = null;}release(stmt, conn);}
​/*** Java代码实现MySQL数据库导出** @param userName     进入数据库所需要的用户名* @param password     进入数据库所需要的密码* @param savePathName 数据库导出文件保存路径加名字* @param databaseName 要导出的数据库名* @return 返回true表示导出成功,否则返回false。*/public static boolean backup(String userName, String password, String savePathName, String databaseName) {try {
//            String stmt = "mysql -uroot -padmin myDB < " + "c:/sql.sql";String stmt = "mysqldump -u" + userName + " -p" + password + " " + databaseName + " > " + savePathName;String[] cmd = {"cmd", "/c", stmt};Process process = Runtime.getRuntime().exec(cmd);if (process.waitFor() == 0) {return true;}} catch (Exception e) {e.printStackTrace();return false;}return false;}
​/*** 操作结果:恢复数据库,前提是数据库里有该数据库名字,否则无法恢复(所以应该先创建一个数据库)** @param username     用户名* @param password     用户数据库密码* @param databasename 数据库名字* @param filePathName 数据库文件路径及名字加后缀* @return boolean 如果恢复成功则返回true,否则返回false*/public static boolean recover(String username, String password, String databasename, String filePathName) {try {
//            String stmt = "mysql -uroot -padmin myDB < " + "c:/sql.sql";String stmt = "mysql -u" + username + " -p" + password + " " + databasename + " < " + filePathName;String[] cmd = {"cmd", "/c", stmt};Process process = Runtime.getRuntime().exec(cmd);if (process.waitFor() == 0) {return true;}} catch (Exception e) {e.printStackTrace();return false;}return false;}
​
}

UserDao.java

package AccountSystem.dao;
​
import AccountSystem.bean.User;
​
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
​
public class UserDao {private Connection connection = null;
​/*** 操作结果:实现按用户名与密码查询用户的方法** @param userName 用户名* @param password 用户密码* @return Users Users对象*/public User login(String userName, String password) {User user = new User();PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {connection = JDBCUtils.getConnection();String sql = "select * from tb_users where uName=? and uPassword=?";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, userName);preparedStatement.setString(2, password);// 执行查询resultSet = preparedStatement.executeQuery();while (resultSet.next()) {user.setUserId(resultSet.getInt(1));user.setUserName(resultSet.getString(2));user.setUserPassword(resultSet.getString(3));user.setUserImagePath(resultSet.getString(4));}} catch (Exception e) {e.printStackTrace();} finally {JDBCUtils.release(resultSet, preparedStatement, connection);}return user;}
​/*** 实现用户注册** @param user 用户* @return 用户注册成功返回true,否则返回false*/public boolean register(User user) {PreparedStatement preparedStatement = null;int num = 0;try {connection = JDBCUtils.getConnection();String sql = "insert into tb_users(uName,uPassword,uImagePath) values(?,?,?)";preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1, user.getUserName());preparedStatement.setString(2, user.getUserPassword());preparedStatement.setString(3, user.getUserImagePath());// 执行插入,返回受影响行数num = preparedStatement.executeUpdate();// 判断是否注册成功return num > 0;} catch (Exception e) {e.printStackTrace();} finally {JDBCUtils.release(preparedStatement, connection);}return false;}
​/*** 根据用户ID查询用户信息** @param userId 用户id* @return 返回查询到的用户信息*/public User selectUserById(int userId) {Connection conn = null;Statement stmt = null;ResultSet rs = null;User user = new User();try {//获得数据的连接conn = JDBCUtils.getConnection();//获得Statement对象stmt = conn.createStatement();// 拼装SQL语句String sql = "select * from tb_users where uId=" + userId;//发送SQL语句rs = stmt.executeQuery(sql);// 循环添加数据while (rs.next()) {user.setUserId(rs.getInt(1));user.setUserName(rs.getString(2));user.setUserPassword(rs.getString(3));user.setUserImagePath(rs.getString(4));}} catch (Exception e) {e.printStackTrace();} finally {JDBCUtils.release(rs, stmt, conn);}return user;}
​/*** 更新用户数据** @param user 要更新的用户数据* @return 如果更新成功则返回true,否则返回false*/public boolean updateUser(User user) {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {//获得数据的连接conn = JDBCUtils.getConnection();//获得Statement对象stmt = conn.createStatement();// 拼接SQL语句String sql = "update tb_users set uName='" + user.getUserName() + "',uPassword='" + user.getUserPassword() + "',uImagePath='" + user.getUserImagePath() + "' where uId=" + user.getUserId() + ";";//发送SQL语句,获取受影响行数int num = stmt.executeUpdate(sql);//判断是否更改成功return num > 0;} catch (Exception e) {e.printStackTrace();} finally {JDBCUtils.release(rs, stmt, conn);}return false;}
}

注意:由于一次性将dao类中的所有方法都给了出来,后续将不再说明调用的方法。

即使上面写了方法也不能使用因为还没有配置数据库的基本信息,所以在properties文件夹下创建一个名为db.properties的文件。

driverName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_bookkeepingSystem
user=root
password=admin

其中driverName是驱动名称,连接的是MySQL数据库,而url指的是连接URL其中db_bookkeepingSystem是你要连接的数据库名称,而user和password分别是MySQL数据库登录的用户和密码。

所有的准备工作完成后就算写注册事件和登录事件。‘

将loginButtonEvent()方法的代码写为如下即处理注册:

    /*** “注册”按钮事件监听器*/@FXMLvoid loginButtonEvent() {// 判断用户是否输入用户名和密码if (nameTextField.getText().equals("") || passwordTextField.getText().equals("")) {SimpleTools.informationDialog(Alert.AlertType.WARNING, "提示", "警告", "请按照文本框内容提示正确填写内容!");} else {// 实例化UserDao对象UserDao userDao = new UserDao();// 封装用户输入的数据到User实体类User user = new User(nameTextField.getText(), SimpleTools.MD5(passwordTextField.getText()), "src\\AccountSystem\\images\\panda.png");// 注册用户,并返回注册结果boolean isLoginSuccess = userDao.register(user);// 对注册结果进行反馈if (isLoginSuccess) {SimpleTools.informationDialog(Alert.AlertType.INFORMATION, "提示", "信息", "恭喜您,注册成功,欢迎使用本系统!");} else {SimpleTools.informationDialog(Alert.AlertType.ERROR, "错误", "错误", "抱歉,您注册失败了,请重新尝试!");}}}

获取用户在界面输入框输入的用户名和密码,然后封装到实体类User中并调用dao包下UserDao.java中的register()方法进行注册,register()方法的实现即是将传过来的数据插入到数据表中。

无论注册成功还是注册失败都进行提示反馈。

运行项目,填入信息进行注册,界面如下:

接着是登录事件,处理代码如下:

    /*** “登录”按钮事件监听器*/@FXMLvoid logupButtonEvent() {// 判断用户是否输入用户名和密码if (nameTextField.getText().equals("") || passwordTextField.getText().equals("")) {SimpleTools.informationDialog(Alert.AlertType.WARNING, "提示", "警告", "请按照文本框内容提示正确填写内容!");} else {// 实例化UserDao对象UserDao userDao = new UserDao();// 登录用户User loginUser = userDao.login(nameTextField.getText(), SimpleTools.MD5(passwordTextField.getText()));// 对是否登录成功进行判断if (loginUser.getUserName() != null && loginUser.getUserPassword() != null) {// 设置通信对象,建立登录成功通信Session.setUser(loginUser);// 在弹出的提示框种获取用户反馈boolean b = SimpleTools.informationDialog(Alert.AlertType.INFORMATION, "提示", "信息", "恭喜" + Session.getUser().getUserName() + ",登录成功,欢迎使用本系统!");// 如果用户确定登录,则跳转到主界面if (b) {// 打开主窗口// new MainApp().initMainFrame();// 跳转到主界面后,关闭登录界面logupStage.close();}} else {SimpleTools.informationDialog(Alert.AlertType.ERROR, "错误", "错误", "用户名或密码错误!");}}}

首先是验证用户输入,验证成功后将获取的用户信息封装到实体类User中,调用UserDao.java中的login()方法进行验证登录,传入的是一个User实体类参数,即从数据库中查询记录,如果查询成功则返回User并给出一个登录成功的确认框,用户点击了“确定”即跳转到主界面并关闭登录界面。同时要注意的是,由于在后面的界面中也会用到登录成功的用户信息,所以要将登录成功的用户信息保存起来,即 Session.setUser(loginUser);。

运行程序,输入刚才注册的信息,点击“登录”,出现如下界面:

但是点击“确定”后,程序将结束,因为登录界面关闭了,并且还没有创建主界面,所以无法打开。即被注释的代码“// new MainApp().initMainFrame();”。

可搜索微信公众号【Java实例程序】或者扫描下方二维码关注公众号获取更多。

注意:在公众号后台回复【20200314】可获取本章的源码 。

Java实战之管家婆记账系统(4)——用户注册及登录功能实现相关推荐

  1. Java实战之管家婆记账系统(6)——导入和导出功能实现

    本节概要 本节将实现将用户的收入和支出记录导出到excel表中,也可以从excel中导入到管家婆记账系统中. 导出 将用户的记录导出到excel表中,导出功能的实现不需要界面,是通过菜单项进行触发的事 ...

  2. Java实战之管家婆记账系统(5)——主界面及功能实现

    本节概要 本节将实现主界面,即在登录成功后显示的主界面,将显示用户的收入支出余额信息及在右边的面板中以表格的形式显示所有的收入支出记录. 前期准备 由于需要使用表格显示记录数据,所以需要使用到实体类来 ...

  3. Java实战之管家婆记账系统(22)——实现修改软件主题皮肤功能

    本节概要 本节实现修改界面皮肤的功能,即使整个程序应用不同的CSS样式. 实现功能 关于软件不同的皮肤要能保存起来,即在软件关闭后再次重启也能显示改变的皮肤,因此需要将其保存在电脑本地,所以在prop ...

  4. Java实战之管家婆记账系统(8)——添加账目界面及功能实现

    本节概要 本节将实现账目记录的添加. 前期准备 在本节中实现记录的添加将用到分类信息的查询,所以在dao包下创建ClassificationDao.java类,代码如下: package Accoun ...

  5. Java实战之管家婆记账系统(7)——备份、恢复和退出功能实现

    本节概要 本节将实现数据库记录的备份.恢复功能和软件的退出. 备份功能 备份功能同样是在MainPageController.java中的backupMenuItemEvent()方法所触发的,即事件 ...

  6. java连接mongodb的jar包_Java实战之管家婆记账系统(1)——项目简述

    项目简述: 该项目是一个通过JavaFX实现的管家婆记账系统,具有记账的功能. 使用软件: IntelliJ IDEA 2018.3.5(Ultim ate Edition):编写Java项目代码. ...

  7. java计算机毕业设计家庭记账系统源程序+mysql+系统+lw文档+远程调试

    java计算机毕业设计家庭记账系统源程序+mysql+系统+lw文档+远程调试 java计算机毕业设计家庭记账系统源程序+mysql+系统+lw文档+远程调试 本源码技术栈: 项目架构:B/S架构 开 ...

  8. java毕业设计家庭理财记账系统mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计家庭理财记账系统mybatis+源码+调试部署+系统+数据库+lw java毕业设计家庭理财记账系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B/S ...

  9. Python+django网页设计入门(5):自定义用户注册与登录功能

    今天恰逢1024,是我们码农自己的节日,祝"Python小屋"所有朋友节日快乐!发几个去年整理的段子开心一下: 祝所有程序员1024节日快乐 =================== ...

最新文章

  1. 笔记本电脑按开机键没反应怎么办?(先记得长按开机键,大约10秒钟看看可以吗)
  2. Linux/unix不同shell环境下数值运算的处理
  3. 前端:JS/16/JavaScript简介,lt;script标记,常用的两个客户端输出方法,JS注释,JS变量(声明,命名规则,赋值),变量的数据类型(数值型,字符型)
  4. html5 canvas图表,Chart.js基于Canvas画布的HTML5统计图表库 - 资源分享
  5. 虚拟机Class文件结构笔记
  6. 6位大师浅谈未来三年大数据的发展
  7. ZOJ 3988 2017CCPC秦皇岛 H:Prime Set(二分匹配)
  8. SVM多分类问题例子+matlab代码
  9. 51单片机入门教程(2)——流水灯的实现
  10. 人民币大写转换 java_java人民币转大写中文
  11. ecshop其他页面判断是智能手机访问也跳转到ECTouch对应手机版页面[有修正]
  12. 关于python使用pandas导入dat数据文件的方法(可导入任意dat数据文件和csv数据文件)
  13. ios是什么?ios有什么特点?
  14. CSMA/CD协议分析
  15. dubbo2.7.x
  16. 晨曦记账本,记账一目了然
  17. vue3.2之 Tailwind CSS
  18. dsp控制buck电路电流环推倒与pi调节器设计
  19. listview条目有下划线
  20. 广州大学计算机考研资料汇总

热门文章

  1. 直接引用vue.js,也可以出效果。但是这样的利弊在哪?搭建脚手架的利弊又是什么呢?
  2. java实现棋盘上的麦子
  3. Spring构造器注入循环依赖的解决方案及原理探索
  4. 2020中考可不可以用计算机,2020中考必读 | 中考电脑阅卷流程“潜规则”!读完孩子少丢20分!(转给中考生)...
  5. ( C# + vs2017 )串口助手 零基础详细教程(二)
  6. 敏捷软件开发模型--SCRUM
  7. 遭遇软件兼容问题——风云防火墙+江民杀毒软件+NetLimiter
  8. CSS3动画之二:Animations功能
  9. 服务器硬件的基础知识,服务器硬件基础知识
  10. 联想硬盘保护安装linux,Ubuntu 下安装Thinkpad T400硬盘保护APS