#【 Java项目开发】账单系统(面向对象+AWT)
提示:项目启动前,请建立数据库表(如果需要预先导入数据,请先导入数据),导入所需的外部包,并调整项目中部分值,项目编码改为GBK。欢迎在评论区提出错误或建议。
项目介绍
一个面向对象版的账单系统,包含用户注册、登录、记账、查看账单等功能。整个项目是在先前小小零钱卡【控制台版】的基础上进行重做,可加深对Java面向对象的理解。此项目在先前控制台版的JDBC、正则表达式、日期时间处理、邮件发送等知识点的基础上,新增面向对象、AWT、Properties配置文件类等知识点。
自我吐槽: 在完成该项目中,遇到过许多问题,比如当一个窗口关闭后怎么返回到另外一个窗口、同一窗口的不同界面如何实现等各种问题,尝试过许多方法,虽然最终完成了项目,但其中仍可能存在问题,同时还有许多低效率的下饭操作,有时候在局限的技术范围内真的想不到合适的高效解决办法,就只能使用一些低效率的解决办法实现功能。该项目界面实现使用纯AWT包下各种控件实现,未涉及Swing包下的控件。在接下来的一段时间里,我会使用Swing来实现项目界面的重做。如果喜欢作者的项目或文章的,可以点赞加关注。让我们一起在Java学习旅程中不断成长!
一、项目功能
二、项目具体实现
1.导外部包
- 邮件发送:
- javax.mail.jar
- activation.jar(全名JavaBeans Activation Framework,简称jaf)
- JDBC:
2.数据库表
- user:用户表
- unused_account:预分配账号表(需要预先导入数据)
- identifying_table:验证码记录表
user:
CREATE TABLE `user` (
`id` bigint(11) unsigned zerofill NOT NULL,
`username` varchar(60) NOT NULL,
`password` varchar(25) NOT NULL,
`createTime` datetime NOT NULL,
`deleteTime` datetime DEFAULT NULL,
`vipEnd` datetime NOT NULL,
`idcard` char(18) DEFAULT NULL,
`name` varchar(12) DEFAULT NULL,
`phone` char(11) NOT NULL,
`email` varchar(45) NOT NULL,
`balance` decimal(20,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
unused_account:
CREATE TABLE `unused_id` (
`id` bigint(11) unsigned zerofill NOT NULL,
`type` smallint(1) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
identifying_table:
CREATE TABLE `identifying_table` (
`id` char(14) NOT NULL,
`identify_code` char(6) NOT NULL,
`startTime` datetime NOT NULL,
`endTime` datetime NOT NULL,
`type` varchar(30) NOT NULL,
`user_id` bigint(11) unsigned zerofill NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
3.代码展示(部分)
登录界面:
/**
* @Author sterarpen
* @Date 2023-4-4
* @Description 登录窗口类
* @version 1.0.0
*/
public class LoginWindow extends Frame implements WindowListener {
private RegisterWindow registerWindow = null;
private Label[] labels = new Label[2];
private TextField[] textFields = new TextField[2];
private Button[] buttons = new Button[2];
private User user = null;
private MainWindow mainWindow = null;
private Pop promptBox = null;
public LoginWindow() {
try {
setIconImage(ImageIO.read(new File(System.getProperty("user.dir") + "\\resource\\picture\\icon.png")));
} catch (IOException e) {
e.printStackTrace();
}
for(int i = 0 ; i < labels.length ; i++)
labels[i] = new Label();
for(int i = 0 ; i < textFields.length ; i++)
textFields[i] = new TextField();
for(int i = 0 ; i < buttons.length ; i++)
buttons[i] = new Button();
this.init();
addWindowListener(this);
}
public void init() {
setTitle("登录");
setSize(840,600);
setResizable(false);
setLocationRelativeTo(null);
setLayout(null);
labels[0].setText("账 号: ");
labels[0].setBounds(150,213,120,40);
labels[0].setFont(new Font("仿宋", Font.PLAIN, 30));
labels[0].setAlignment(Label.LEFT);
labels[0].setBackground(new Color(135,206,250));
textFields[0].setBounds(280,213,360,40);
textFields[0].setFont(new Font("仿宋", Font.PLAIN, 30));
labels[1].setText("密 码: ");
labels[1].setFont(new Font("仿宋", Font.PLAIN, 30));
labels[1].setAlignment(Label.LEFT);
labels[1].setBounds(150,300,120,40);
labels[1].setBackground(new Color(135,206,250));
textFields[1].setBounds(280,300,360,40);
textFields[1].setEchoChar('*');
textFields[1].setFont(new Font("仿宋", Font.PLAIN, 30));
buttons[0].setLabel("登录");
buttons[0].setBounds(280,420,360,50);
buttons[0].setFont(new Font("仿宋", Font.PLAIN, 30));
buttons[0].addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
String id = getName();
String password = getPassword();
if(UserDao.LoginUser(id,password) == 1) {
user = UserDao.queryUserComplex(id);
if(mainWindow == null)
mainWindow = new MainWindow(getThis(),user);
else
mainWindow.setVisible(true);
setVisible(false);
}
else
newPromptBoxPop("账号或密码错误");
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
});
buttons[1].setLabel("注册账户");
buttons[1].setBounds(150,420,120,50);
buttons[1].setFont(new Font("仿宋", Font.PLAIN, 20));
LoginWindow lw = this;
buttons[1].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
removeAll();
setVisible(false);
if(registerWindow == null)
registerWindow = new RegisterWindow(lw);
else
registerWindow.init();
}
});
for(Label label : labels)
add(label);
for(TextField textField : textFields)
add(textField);
for(Button button : buttons) {
add(button);
}
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
BufferedImage image;
try {
image = ImageIO.read(new File(System.getProperty("user.dir") + "\\resource\\picture\\background.png"));
g.drawImage(image, 0, 30, null);
} catch (IOException e) {
e.printStackTrace();
}
}
public void newPromptBoxPop(String content) {
if(promptBox != null) {
promptBox.reloadPop(content);
}else {
promptBox = new Pop(this,content);
}
}
public String getName() {
return this.textFields[0].getText();
}
public String getPassword() {
return this.textFields[1].getText();
}
public LoginWindow getThis() {
return this;
}
@Override
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
}
@Override
public void windowOpened(WindowEvent e) {}
@Override
public void windowClosed(WindowEvent e) {}
@Override
public void windowIconified(WindowEvent e) {}
@Override
public void windowDeiconified(WindowEvent e) {}
@Override
public void windowActivated(WindowEvent e) {}
@Override
public void windowDeactivated(WindowEvent e) {}
}
更新用户VIP的数据库操作:
/**
* 用户VIP充值,数据库操作
* @param user 获取充值VIP后VIP日期和剩余余额的用户类
* @return 操作结果,是否成功,成功返回1,失败返回对应失败异常码
*/
public static int updateUserVip(User user) {
if(user == null) return ErrorNum.PARAMS_IS_NULL;
String sql = "update user set vipEnd=?,balance=? where id=?";
PreparedStatement pstat = DatabaseUtil.getPreparedStatement(sql);
if(pstat == null) return ErrorNum.STATEMENT_IS_NULL;
try {
pstat.setTimestamp(1,user.getVipEnd());
pstat.setBigDecimal(2,user.getBalance());
pstat.setString(3,user.getId());
if(pstat.executeUpdate() != 1) return ErrorNum.RESULT_IS_NULL;
return 1;
} catch (SQLException throwables) {
throwables.printStackTrace();
return ErrorNum.CATCH_EXCEPTION;
}finally {
try {
pstat.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
三、效果展示
相关
项目下载地址:百度网盘下载
项目Gitee地址:Gitee
欢迎在观看的各位留言和根据自己想法重新完成项目并进一步完善扩展!