ATM取款机系统
本项目使用JavaSwing开发,可以实现ATM系统的基本注册登录、转账、查询、存取款业务
功能要求:
- 用户登录注册
- 用户存款
- 用户查询余额(查询账户余额和操作记录)
- 用户取款
- 用户转账功能(加分项)
- 程序
package demote2; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; public class ATMSystem extends JFrame implements ActionListener { private String loggedInUser; private Account loggedInAccount; private final JLabel welcomeLabel = new JLabel("Welcome to ATM System!"); private final JLabel userLabel = new JLabel("Username: ");//用户名标签 private final JLabel pwdLabel = new JLabel("Password: "); private final JTextField userTextField = new JTextField();//用户名输入框 private final JPasswordField pwdField = new JPasswordField(); private final JButton loginButton = new JButton("Login");//登录按钮 private final JButton registerButton = new JButton("Register");//注册按钮 private final JPanel loginPanel = new JPanel(new GridLayout(3, 2));//登录面板,使用网格布局 private final JLabel amountLabel = new JLabel("Amount: ");//金额标签 private final JTextField amountTextField = new JTextField(); //金额输入框 private final JButton depositButton = new JButton("Deposit");//存款按钮 private final JButton withdrawButton = new JButton("Withdraw"); private final JButton balanceButton = new JButton("Check Balance");//查询余额按钮 private final JButton transferButton = new JButton("Transfer");//转账按钮 private final JPanel transactionPanel = new JPanel(new GridLayout(3, 2));//交易面板,使用网格布局 private final JTextArea historyArea = new JTextArea();//交易历史文本区域 private final JScrollPane historyScroll = new JScrollPane(historyArea); //交易历史滚动面板 private final JPanel historyPanel = new JPanel(new BorderLayout());//交易历史面板,使用边界布局 private final List<Account> accountList = new ArrayList<>();//账户列表,存储所有注册的账户对象 public ATMSystem() { super("ATM System"); //调用父类构造方法,设置窗口标题 // Login Panel(向登录面板添加标签按钮) loginPanel.add(welcomeLabel); loginPanel.add(new JLabel("")); loginPanel.add(userLabel); loginPanel.add(userTextField); loginPanel.add(pwdLabel); loginPanel.add(pwdField); loginPanel.add(loginButton); loginPanel.add(registerButton); loginButton.addActionListener(this);//为登录按钮添加动作监听器,实现ActionListener接口的类为this,即本类对象 registerButton.addActionListener(this);//为注册按钮添加动作监听器,实现ActionListener接口的类为this,即本类对象 // Transaction Panel/向交易面板添加内容 transactionPanel.add(amountLabel); transactionPanel.add(amountTextField); transactionPanel.add(depositButton); transactionPanel.add(withdrawButton); transactionPanel.add(balanceButton); transactionPanel.add(transferButton); depositButton.addActionListener(this);//为存款按钮添加动作监听器,实现ActionListener接口的类为this,即本类对象 withdrawButton.addActionListener(this); balanceButton.addActionListener(this); transferButton.addActionListener(this); transactionPanel.setVisible(false);//设置交易面板不可见,只有在登录成功后才显示 // History Panel historyPanel.add(new JLabel("Transaction History:"), BorderLayout.NORTH);//向交易历史面板添加一个标签,显示在北边 historyPanel.add(historyScroll, BorderLayout.CENTER);//向交易历史面板添加一个滚动面板,显示在中间,滚动面板中包含交易历史文本区域 historyPanel.setVisible(false);//设置交易历史面板不可见,只有在登录成功后才显示 //向窗口添加登录、交易、历史面板 this.add(loginPanel, BorderLayout.CENTER); this.add(transactionPanel, BorderLayout.NORTH); this.add(historyPanel, BorderLayout.SOUTH); this.pack();//调整窗口大小以适应子组件的首选大小和布局 this.setVisible(true); // this.setVisible(true);//设置窗口可见 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗口关闭时退出程序 this.setLocationRelativeTo(null);//设置窗口居中 } @Override public void actionPerformed(ActionEvent e) { Object source = e.getSource();//获取事件源对象 if (source == loginButton) { login(); //如果事件源是登录按钮,调用登录方法 } else if (source == registerButton) { register(); } else if (source == depositButton) { deposit(); } else if (source == withdrawButton) { withdraw(); } else if (source == balanceButton) { checkBalance(); } else if (source == transferButton) { transfer(); //如果事件源是转账按钮,调用转账方法 } } private boolean checkUserExists(String username) {//检查用户名是否已存在的方法,参数为用户名字符串,返回值为布尔值 for (Account account : accountList) { if (account.getUsername().equals(username)) { return true; } }//遍历账户列表中的每个账户对象 return false; } private void register() {//注册方法,无参数无返回值 String username = userTextField.getText(); //获取用户名输入框中的文本,赋值给username变量 String password = String.valueOf(pwdField.getPassword());//获取密码输入框中的字符数组,并转换为字符串,赋值给password变量 if (username.isEmpty() || password.isEmpty()) {//如果用户名或密码为空字符串,弹出提示框,提示请输入用户名和密码 JOptionPane.showMessageDialog(this, "Please enter username and password!"); } else if (checkUserExists(username)) { //否则如果用户名已存在(调用checkUserExists方法),弹出提示框,提示用户名已存在,请选择另一个 JOptionPane.showMessageDialog(this, "Username already exists, please choose another one!"); } else { //否则(用户名不存在)则创建一个新的账户对象,传入用户名和密码作为参数 Account account = new Account(username, password); accountList.add(account); JOptionPane.showMessageDialog(this, "Register success!"); }} private void login() {//登录方法,无参数无返回值 String username = userTextField.getText();//获取用户名输入框中的文本,赋值给username变量 String password = String.valueOf(pwdField.getPassword());//获取密码输入框中的字符数组,并转换为字符串,赋值给password变量 boolean found = false;//定义一个布尔变量found,初始值为false,表示是否找到匹配的账户对象 for (Account account : accountList) {//遍历账户列表中的每个账户对象 if (account.getUsername().equals(username) && account.getPassword().equals(password)) { found = true;//如果账户对象的用户名和密码与输入的相同 found = true; 将found变量赋值为true loggedInUser = username; loggedInAccount = account; loginPanel.setVisible(false); transactionPanel.setVisible(true); historyPanel.setVisible(true); break; } } if (!found) { JOptionPane.showMessageDialog(this, "Invalid username or password!"); } } private void deposit() {//存款方法,无参数无返回值 Double amount = getAmount();//调用getAmount方法,获取输入的金额,赋值给amount变量 if (amount != null) {//如果金额不为空(即输入的金额是有效的) loggedInAccount.deposit(amount);//调用当前登录账户对象的deposit方法,传入金额作为参数,进行存款操作 updateHistory("Deposit", amount);//调用updateHistory方法,传入操作类型和金额作为参数,更新交易历史记录 } } private void withdraw() {//取款方法 Double amount = getAmount(); if (amount != null) {//如果金额不为空(即输入的金额是有效的) boolean result = loggedInAccount.withdraw(amount); //调用当前登录账户对象的withdraw方法,传入金额作为参数,进行取款操作,并将返回值赋值给result变量 if (result) {//如果返回值为真(即取款成功) updateHistory("Withdraw", amount);//调用updateHistory方法,传入操作类型和金额作为参数,更新交易历史记录 } else { //否则(即取款失败 JOptionPane.showMessageDialog(this, "Insufficient balance!");//弹出提示框,提示余额不足 } } } private void checkBalance() {//查询余额方法,无参数无返回值 String message = "Balance: " + loggedInAccount.getBalance() + "\n\nTransaction History:\n" + loggedInAccount.getHistory(); //拼接一个字符串,包含当前登录账户对象的余额和交易历史记录 historyArea.setText(message);//将交易历史文本区域中的文本设置为拼接好的字符串 } private void transfer() {//转账方法,无参数无返回值 String username = JOptionPane.showInputDialog(this, "Enter transfer destination username: "); //弹出一个输入框,提示输入转账目标用户名,并将输入的文本赋值给username变量 if (!checkUserExists(username)) {//如果用户名不存在(调用checkUserExists方法) JOptionPane.showMessageDialog(this, "Invalid destination username!"); //弹出提示框,提示目标用户名无效 return;//结束方法 } Double amount = getAmount();//调用getAmount方法,获取输入的金额,赋值给amount变量 if (amount == null) { //如果金额为空(即输入的金额是无效的 return; } for (Account account : accountList) {//遍历账户列表中的每个账户对象 if (account.getUsername().equals(username)) {//如果账户对象的用户名与目标用户名相同 boolean result = loggedInAccount.transfer(account, amount); //调用当前登录账户对象的transfer方法,传入目标账户对象和金额作为参数,进行转账操作,并将返回值赋值给result变量 if (result) { //如果返回值为真(即转账成功) updateHistory("Transfer to " + username, amount); //调用updateHistory方法,传入操作类型和金额作为参数,更新交易历史记录 JOptionPane.showMessageDialog(this, "Transfer success!"); //弹出提示框,提示转账成功 } else {//否则(即转账失败) JOptionPane.showMessageDialog(this, "Insufficient balance!"); //弹出提示框,提示余额不足 } return; } } } private Double getAmount() {//获取金额的方法,无参数返回一个Double类型的值 String amountString = amountTextField.getText();//获取金额输入框中的文本,赋值给amountString变量 Double amount = null; try { amount = Double.parseDouble(amountString);//将amountString变量转换为Double类型,并赋值给amount变量 if (amount <= 0) {//如果amount<0,则抛出一个异常 throw new Exception(); } } catch (Exception exception) {//捕获任何异常 JOptionPane.showMessageDialog(this, "Invalid amount!"); //弹出提示框,提示金额无效 } amountTextField.setText("");//将金额输入框中的文本设置为空字符串 return amount;//返回amount变量的值 } private void updateHistory(String type, double amount) {//更新交易历史的方法,参数为操作类型和金额,无返回值 String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); //获取当前时间,并按照指定的格式转换为字符串,赋值给timestamp变量 String record = timestamp + "\t" + type + "\t" + amount + "\n";//拼接一个字符串,包含时间,操作类型和金额,赋值给record变量 loggedInAccount.addHistoryRecord(record); //调用当前登录账户对象的addHistoryRecord方法,传入record变量作为参数,将交易记录添加到账户对象中 String message = "Balance: " + loggedInAccount.getBalance() + "\n\nTransaction History:\n" + loggedInAccount.getHistory(); //拼接一个字符串,包含当前登录账户对象的余额和交易历史记录 historyArea.setText(message);//将交易历史文本区域中的文本设置为拼接好的字符串 } public static void main(String[] args) { new ATMSystem();//创建一个ATMSystem类的对象,即启动程序 } }
-
account类声明
package demote2; public class Account {//定义一个账户类 private String username; private String password; private double balance;//余额 private final StringBuilder history = new StringBuilder();//定义一个私有的不可变的字符串构建器属性,表示交易历史记录 public Account(String username, String password) { //定义一个公共的构造方法,参数为用户名和密码 this.username = username;//将参数赋值给当前对象的username属性 this.password = password;//将参数赋值给当前对象的password属性 this.balance = 0.0;//将当前对象的balance属性初始化为0.0 } public String getUsername() { return username; }//定义一个公共的方法,返回用户名.返回当前对象的username属性 public String getPassword() { return password; } public void deposit(double amount) { balance += amount; } //定义一个公共的方法,进行存款操作,参数为金额 // 将当前对象的balance属性增加参数的值 public boolean withdraw(double amount) {//定义一个公共的方法,进行取款操作,参数为金额,返回值为布尔值 if (balance < amount) {//如果当前对象的balance属性小于参数的值,返回假值,表示取款失败 return false; } else { balance -= amount;; //将当前对象的balance属性减去参数的值,返回真值,表示取款成功 return true; } } public double getBalance() { return balance; } //定义一个公共的方法,返回余额 ,返回当前对象的balance属性 public boolean transfer(Account account, double amount) {//定义一个公共的方法,进行转账操作,参数为目标账户对象和金额,返回值为布尔值 boolean success = withdraw(amount);//调用当前对象的withdraw方法,传入金额作为参数,并将返回值赋值给success变量 if (success) {//如果success变量为真(即取款成功) account.deposit(amount);//调用目标账户对象的deposit方法,传入金额作为参数,进行存款操作 return true;//返回真值,表示转账成功 } else {//否则(即取款失败) return false; } } public String getHistory() { return history.toString(); } //定义一个公共的方法,返回交易历史记录 // return history.toString(); 将当前对象的history属性转换为字符串,并返回 } public void addHistoryRecord(String record) { history.append(record); }//定义一个公共的方法,添加交易记录到历史记录中,参数为交易记录字符串 // history.append(record); 将当前对象的history属性追加参数字符串 }