JAVA实训(二)
弹窗帮助类
DialogUtil
package com.qf.utils;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;
import javax.swing.*;
import java.awt.*;
import java.util.Optional;
/*
* 生成弹窗的方法
* alertType 弹窗类型
* title 标题
* header对话框的头
* message 消息
*
* */
public class DialogUtil {
public static boolean Dialog(Alert.AlertType alertType, String title, String header, String message) {
Alert alert = new Alert(alertType, message,
new ButtonType("取消", ButtonBar.ButtonData.CANCEL_CLOSE),
new ButtonType("确认", ButtonBar.ButtonData.YES));
alert.setTitle(title);
alert.setHeaderText(header);
//接受对应的按了什么按钮,返回的是按钮的类型
Optional<ButtonType> buttonType = alert.showAndWait();
//获取对按钮类型对应的按钮的buttonData值
return buttonType.get().getButtonData().equals(ButtonBar.ButtonData.YES);
}
}
Md5加密工具类
Md5Util
原因:
为了防止开发者可以随意登录用户数据,必须需要对密码进行不可逆加密。
注意:
登录的时候进行对比加密后的消息;而不是对密码进行解密。
package com.qf.utils;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Md5Util {
/**
* md5加密的方法 32位字符串
* @param str
* @return
*/
public static String md5(String str){
//生成一个Md5加密摘要
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
//将string类型数据加密转为int类型 再返回成16位的字符串
String string = new BigInteger(1,
md5.digest(str.getBytes())).toString(16);
//BigInteger会省略0 补零补32位
return fillMd5(string);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
private static String fillMd5(String md5){
return md5.length()==32?md5:fillMd5("0"+md5);
}
}
登录用户信息共享空间
Session
作用:
方便用户登录后,各个功能都能方便的调用信息。
package com.qf.utils;
import com.qf.domain.User;
/*
* 建立一个共享空间存用户
* */
public class Session {
// static保证唯一性。 单例
private static User user;
public static void setUser(User user) {
Session.user = user;
}
public static User getUser() {
return user;
}
}
用户登录流程
controller层处理
LoginController
package com.qf.controller;
import com.qf.MainApplication;
import com.qf.domain.User;
import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
import com.qf.utils.DialogUtil;
import com.qf.utils.Md5Util;
import com.qf.utils.Session;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.PasswordField;
import javafx.stage.Stage;
import javafx.scene.control.TextField;
//登录控制类
public class LoginController {
//当前的窗口容器对象;
private Stage LoginStage;
public Stage getLoginStage() {
return LoginStage;
}
public void setLoginStage(Stage loginStage) {
LoginStage = loginStage;
}
@FXML
private TextField usernameInput;//接受jfx里面的组件,名字必须he对口的fxml里面的组件一样
@FXML
private PasswordField passwordInput;//接受jfx里面的组件
//登录的方法
//在对于fxml里面调用必须带#
@FXML
void login() {
//1. 获取传的数据
String username = usernameInput.getText();
String password = passwordInput.getText();
//如果数据为空值,弹窗输入不能为空
if (username.trim().equals("") || password.trim().equals("")) {//去掉空格
DialogUtil.Dialog(Alert.AlertType.WARNING, "警告", "危险动作",
"用户名及密码不能为空");
return;
}
//2. 验证数据 :去service层
UserService userService = new UserServiceImpl();
//2.1 调用service层的方法
User user = userService.findByUserName(username);
//返回验证结果:
// 如果存在数据,可以登陆,弹框可以登录(点击确定 进入主页 初始化主页)
if (user != null) {
//将用户输入密码进行加密校验
if (user.getPassword().equals(Md5Util.md5(password))){
//将当前用户存入Session中
Session.setUser(user);
//弹窗提示
boolean success = DialogUtil.Dialog(Alert.AlertType.INFORMATION, "提示", "友情提示",
"登录成功");
//打开新的页面
if (success) {
//关闭当前窗口
this.LoginStage.close();
//打开主页
new MainApplication().initHome();
}else {
}
} //如果不存在数据,弹窗不能登录
else {
DialogUtil.Dialog(Alert.AlertType.WARNING, "警告", "危险动作",
"密码错误");
}
} else { //如果不存在数据,弹窗不能登录
DialogUtil.Dialog(Alert.AlertType.WARNING, "警告", "危险动作",
"当前用户不存在");
}
}
//注册的方法
@FXML
void register() {
//跳转到注册页面.
new MainApplication().initRegister();
}
}
service层
package com.qf.service.impl;
import com.qf.dao.UserDao;
import com.qf.dao.impl.UserDaoImpl;
import com.qf.domain.User;
import com.qf.service.UserService;
public class UserServiceImpl implements UserService {
//准备dao层实例
UserDao userDao = new UserDaoImpl();
@Override
public User findByUserName(String username) {
//调用dao层方法
User user = userDao.selectByUserName(username);
return user;
}
}
dao层
package com.qf.dao.impl;
import com.qf.dao.UserDao;
import com.qf.domain.User;
import com.qf.utils.DbUtil;
import java.sql.*;
//用户dao的实现类
public class UserDaoImpl implements UserDao {//其他方法已经省略
//利用UserName查询用户是否存在
@Override
public User selectByUserName(String username) {
Connection connection = DbUtil.getConnection();
//and 俩个同时满足
//or 俩个只需要满足其中一个就好
String sql = "select * from t_user where username=?";
PreparedStatement statement = DbUtil.getStatement(sql);
try {
statement.setString(1,username);
ResultSet resultSet = statement.executeQuery();
//准备一个对象
User user = null;
//遍历结果集
while(resultSet.next()){
user = new User();
//将结果的值设置给user对象
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
user.setAvatar(resultSet.getString("avatar"));
user.setNickname(resultSet.getString("nickname"));
}
//调用关闭方法
//DbUtil.close(connection,statement,resultSet);
return user;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
MainApplication
注册功能实现
controller层
RegisterController
package com.qf.controller;
import com.qf.MainApplication;
import com.qf.domain.User;
import com.qf.service.UserService;
import com.qf.service.impl.UserServiceImpl;
import com.qf.utils.DialogUtil;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.io.IOException;
public class RegisterController {
//当前的窗口容器对象;
private Stage RegisterStage;
public Stage getRegisterStage() {
return RegisterStage;
}
public void setRegisterStage(Stage primaryStage) {
this.RegisterStage = RegisterStage;
}
@FXML
private TextField usernameInput;//接受jfx里面的组件,名字必须he对口的fxml里面的组件一样
@FXML
private PasswordField passwordInput;//接受jfx里面的组件
//登录的方法
//在对于fxml里面调用必须带#
@FXML
void login() throws IOException {
//跳转到登录页面.
new MainApplication().initLogin();
}
//注册的方法
//在对于fxml里面调用必须带#
@FXML
void register() throws IOException {
//1.获取数据
String username = usernameInput.getText();
String password = passwordInput.getText();
//2.判断是否为空
if (username.trim().equals("") || password.trim().equals("")) {//去掉空格
DialogUtil.Dialog(Alert.AlertType.WARNING, "警告", "危险动作",
"用户名及密码不能为空");
} else {
//3.1 获取当前用户名
UserService userService = new UserServiceImpl();
User user = userService.findByUserName(username);
//3.2 判断是否存在,存在就报错
if (user != null) {
DialogUtil.Dialog(Alert.AlertType.INFORMATION, "提示", "提示",
"用户名已经存在");
} else {
User insertUser = new User();
insertUser.setUsername(username);
insertUser.setPassword(password);
//4.1添加用户 访问service 层调用添加的方法
boolean result = userService.saveUser(insertUser);
//5.1 添加成功,提示添加成功, 转跳到登录
if (result) {
boolean success = DialogUtil.Dialog(Alert.AlertType.INFORMATION, "OK", "友情提示",
"用户添加成功,点击确定进入登录,点击取消继续注册其他账户");
if (success) {
// //关闭当前窗口
// this.RegisterStage.close();
//打开登录页面
new MainApplication().initLogin();
}
} else { //5.2 添加失败,提示添加失败
DialogUtil.Dialog(Alert.AlertType.ERROR, "错误", "错误信息",
"用户添加失败");
}
}
}
}
}
service层
UserServiceImpl
其他方法已经省略
@Override
public boolean saveUser(User insertUser) {
//先将用户密码加密
//加密方式 md5(已经被破解,简单)(所以需要 加盐{未实现})
String md5Pwd = Md5Util.md5(insertUser.getPassword());
insertUser.setPassword(md5Pwd);
//将加密的信息存入数据库
boolean b = userDao.addUser(insertUser);
return b;
}
dao层
MainApplication
package com.qf;
import com.qf.controller.LoginController;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;
//视图页面运行的入口
public class MainApplication extends Application {
@FXML
private Stage primaryStage;//窗口对象
@FXML
private Parent root;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws IOException {
this.primaryStage = primaryStage;
//对于窗口标题进行设置
this.primaryStage.setTitle("管家婆");
initLogin();
}
//抽取渲染loginView.fxml的方法
public Scene initLogin() throws IOException {
//加载对于的fxml成为一个节点
//Parent root =
FXMLLoader.load(getClass().getResource("views\\LoginView.fxml"));
//新建一个FXMLLoader 传递对应的fxml的url地址
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("views\\LoginView.fxml"));
//利用新建的FxmlLoad加载对应的根节点
root = fxmlLoader.load();
//将加载的节点变成根节点 设置窗口的大小
Scene scene = new Scene(root);
//设置节点
primaryStage.setScene(scene);
//获取的是fxml对应的controller类
LoginController controller = fxmlLoader.getController();
//设置对应的loginStage
controller.setLoginStage(primaryStage);
//获取对应的Stage
//设置显示
primaryStage.show();
return scene;
}
//抽取渲染Home.fxml的方法
public Scene initHome(){
try{
//1.新建fxmlLoad
FXMLLoader load = new FXMLLoader();
//2.设置fxml路径
load.setLocation(getClass().getResource("views\\HomeView.fxml"));
//3.获取对应的root
AnchorPane root = (AnchorPane)load.load();
//4.生成对应的Scene
Scene scene = new Scene(root);
//5.设置相关内容
Stage stage = new Stage();
stage.setTitle("管家婆系统");
stage.setResizable(true);
stage.setAlwaysOnTop(false);
//初始化为应用
stage.initModality(Modality.APPLICATION_MODAL);
//覆盖窗口
stage.initOwner(primaryStage);
stage.setScene(scene);
//6.显示
stage.showAndWait();
//7.返回Scene
return scene;
}catch (Exception e){
throw new RuntimeException(e);
}
}
}
主页制作及渲染
HomeView.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400.0" prefWidth="600.0"
xmlns="http://javafx.com/javafx/10.0.2-internal"
xmlns:fx="http://javafx.com/fxml/1"
fx:controller="com.qf.controller.HomeController">
<SplitPane dividerPositions="0.29797979797979796" layoutX="-5.0"
prefHeight="400.0" prefWidth="611.0">
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0"
prefWidth="100.0">
<children>
<VBox alignment="CENTER" prefHeight="400.0" prefWidth="179.0">
<children>
<HBox alignment="BOTTOM_CENTER" prefHeight="163.0"
prefWidth="179.0">
<ImageView fitHeight="70" fitWidth="70"
fx:id="imageViewPicture">
<!-- <Image url="@/com/qf/images/panda.png" />-->
</ImageView>
</HBox>
<HBox alignment="CENTER" prefHeight="60.0"
prefWidth="179.0">
<Label fx:id="usernameLabel" />
</HBox>
<HBox alignment="TOP_CENTER" prefHeight="40.0"
prefWidth="179.0">
<Label prefHeight="15.0" prefWidth="50.0" text="总支
出:" />
<TextField alignment="CENTER" prefHeight="23.0"
prefWidth="100" fx:id="totalExpenditure" disable="true" />
</HBox>
<HBox alignment="TOP_CENTER" prefHeight="40.0"
prefWidth="179.0" fx:id="">
<Label prefHeight="15.0" prefWidth="50.0" text="总收
入:" />
<TextField alignment="CENTER" prefHeight="23.0"
prefWidth="100" fx:id="totalRevenue" disable="true"/>
</HBox>
<HBox alignment="TOP_CENTER" prefHeight="108.0"
prefWidth="179.0">
<Label prefHeight="15.0" prefWidth="50.0" text="余
额:" />
<TextField prefHeight="23.0" prefWidth="100"
fx:id="balance" disable="true"/>
</HBox>
</children>
</VBox>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0"
prefWidth="100.0">
<MenuBar prefHeight="31.0" prefWidth="426.0">
<menus>
<Menu mnemonicParsing="false" text="文件">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="编辑">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="查询">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="选项">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="帮助">
<items>
<MenuItem mnemonicParsing="false" text="Action 1" />
</items>
</Menu>
</menus></MenuBar>
<TableView layoutX="-1.0" layoutY="31.0" prefHeight="368.0"
prefWidth="425.0">
<columns>
<TableColumn prefWidth="47.000001549720764" text="序号" />
<TableColumn prefWidth="57.99999237060547" text="类型" />
<TableColumn prefWidth="64.60002899169922" text="金额" />
<TableColumn prefWidth="73.0" text="分类" />
<TableColumn prefWidth="64.0" text="备注" />
<TableColumn prefWidth="108.00003051757812" text="日期" />
</columns>
</TableView>
</AnchorPane>
</SplitPane>
</AnchorPane>
Controller层
HomeController
package com.qf.controller;
import com.qf.dao.RecordDao;
import com.qf.dao.impl.RecordDaoImpl;
import com.qf.utils.Session;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
//登录控制类
public class HomeController {
@FXML
private ImageView imageViewPicture;//图片
@FXML
private Label usernameLabel;//显示的用户名
@FXML
private TextField totalExpenditure;//显示总收入的
@FXML
private TextField totalRevenue;//显示总支出的
@FXML
private TextField balance;//显示余额的
@FXML//初始化调用的方法
public void initialize(){
initUserRecode();
}
private void initUserRecode(){
//设置给对应的usernameLabel以及对应的imageViewPicture
usernameLabel.setText(Session.getUser().getNickname());
//设置图片
imageViewPicture.setImage(new
Image("file:"+Session.getUser().getAvatar()));
//设置宽高
imageViewPicture.setFitWidth(50);
imageViewPicture.setFitWidth(50);
//设置缓存
imageViewPicture.setCache(true);
imageViewPicture.setPreserveRatio(true);
imageViewPicture.setSmooth(true);
//设置相关的收入及支出余额等
RecordDao recordDao = new RecordDaoImpl();
Double Expenditure = recordDao.queryCount(Session.getUser().getId(), "支
出");
totalExpenditure.setText(Expenditure.toString());
Double Revenue = recordDao.queryCount(Session.getUser().getId(), "收入");
totalRevenue.setText(Revenue.toString());
balance.setText(new Double((Revenue-Expenditure)).toString());
}
}
dao层
RecordDaoImpl
package com.qf.dao.impl;
import com.qf.dao.RecordDao;
import com.qf.domain.Record;
import com.qf.utils.DbUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class RecordDaoImpl implements RecordDao {
@Override
public List<Record> selectRecordByUserId(int uid) {
Connection connection = DbUtil.getConnection();
String sql = "select * from t_record where uid = ?";
PreparedStatement statement = DbUtil.getStatement(sql);
ArrayList<Record> records = new ArrayList<>();
try {
statement.setInt(1,uid);
ResultSet resultSet = statement.executeQuery();
while(resultSet.next()){
Record record = new Record(
resultSet.getInt(1),
resultSet.getString(3),
resultSet.getDouble(4),
resultSet.getString(5),
resultSet.getString(6),
resultSet.getDate(7)
);
records.add(record);
}
} catch (SQLException e) {
e.printStackTrace();
}
return records;
}
@Override
public double queryCount(int uid, String type) {
Connection connection = DbUtil.getConnection();
String sql = "select SUM(rMoney) from t_record where uid=? and rType=?";
PreparedStatement statement = DbUtil.getStatement(sql);
double total = 0;
try {
statement.setInt(1,uid);
statement.setString(2,type);
ResultSet resultSet = statement.executeQuery();
while(resultSet.next()){
total = resultSet.getDouble(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return total;
}
}