简单的java问题,急求解

img


【目的】
1、理解Java程序设计语言的特点和用法,掌握面向对象程序设计语言Java 语言的语法机制;
2、培养面向对象程序设计的思维,掌握使用主流编程语言lava 进行程序设计,解决实际问题的技能
3、通过相应的实验设计,能够将实际问题的分析转换成程序语言的能力。【题目内容】
1、ATM 柜员机模拟程序
要求:使用图形用户界面编程。当输入给定的卡号和密码(初始卡号和密码为123456)时,系统能登录 ATM 柜员机系统,用户可以按照以下规则进行1)查询余额:初始余额为 10000元。
2)ATM 取款:每次取款金额为 100 的倍数,总额不超过 5000 元,支取金额不允许透支。3)ATM 存款:不能出现负存款。
4)修改密码:新密码长度不小于6位,不允许出现6位完全相同的情况,只有旧密码正确,新密码符合要求,且两次输入相同的情况下才可以成功修改密码。
2、一个计算数学表达式的程序要求:
1)由用户输入一个简单的四则运算表达式,求出其计算结果后显示。
2)允许在表达式中出现常用的数学函数,如绝对值、取整、三角函数、倒数、平方根、平方、立方等3)尽量使用图形界面实现,要符合日常软件使用规范来设计菜单和界面。如果无法实现图形界面则在命令行方式下也需要提供菜单,方便用户操作。4)能够注意各种异常处理,注重提高程序运行效率。

第一题:

img

img

img

img

一共四个类
第一个:Account

public class Account {
    String account;//账户
    String passwd;//密码
    String name;//姓名
    double money;//余额

    //生成有参构造函数
    public Account(String account, String passwd, String name) {
        this.account = account;
        this.passwd = passwd;
        this.name = name;
    }
    /**生成set、get方法*/
    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

}

第二个:BankOperate


import java.util.Scanner;

public class BankOperate {
    //银行开户的方法
    public static void regist(String account, String passwd, String name) {
        Account account1 = new Account(account, passwd, name);
        for (int i = 0; i < BankTool.account.length; i++) {
            if (BankTool.account[i] == null) {
                BankTool.account[i] = account1;
                System.out.println("注册成功");
                break;
            }
        }
    }
    //银行账号登录的方法
    public static boolean logine(String account, String passwd) {
        //循环从账户数组里面寻找是否存在该账号
        for (int i = 0; i < BankTool.account.length; i++) {
            if (BankTool.account[i] != null) {
                //如果账号相同并且密码相同
                if (account.equals(BankTool.account[i].getAccount())
                        && passwd.equals(BankTool.account[i].getPasswd())) {
                    BankTool.index = i;
                    return true;//返回true,表示登录成功
                }
            }
        }
        return false;
    }
    /**存钱*/
    public static void save(double money) {
        BankTool.account[BankTool.index].setMoney(BankTool.account[BankTool.index].getMoney() + money);
        System.out.println("存钱成功");
    }
    /**取钱*/
    public static void take(double money) {
        if(money>5000){
            System.out.println("单笔交易额不能超过5000!");
            return ;
        }
        if(money%100!=0){
            System.out.println("取款金额必须是100的倍数!");
            return;
        }
        BankTool.account[BankTool.index].setMoney(BankTool.account[BankTool.index].getMoney() - money);
        System.out.println("取钱成功");
    }

    public static void check() {
        System.out.println("当前账户余额为:"+BankTool.account[BankTool.index].getMoney());
    }
    /**修改账户密码*/
    public static boolean change(String new_password){
        int a=111111;
        int b=Integer.parseInt(new_password);
        for(int i=1;i<10;i++) {
            a = a * i;
            if(a==b){
                System.out.println("密码6位数相同,安全性较低,请重新输入:");
                return false;
            }else{continue;}
        }
        for(;;) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入新密码再次确认:");
            String new_pass = sc.nextLine();
            if (new_pass.equals(new_password)) {
                BankTool.account[BankTool.index].setPasswd(new_password);
                System.out.println("修改成功!");
                return true;
            } else {
                continue;
            }
        }
    }
}

第三个:BankTool

//用于记录银行账号信息
public class BankTool {
    public static Account[] account=new Account[100];
    public static int index=0;
}

第四个:主函数

import java.util.Scanner;

public class dome {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("------欢迎使用自助存取款系统------");
            System.out.println("请输入账户密码(首次使用请按#注册):");
            String account = scanner.nextLine();
            if (account.equals("#")) {
                System.out.println("请输入新的账户:");
                String account1 = scanner.nextLine();
                System.out.println("请输入密码:");
                String passwd1 = scanner.nextLine();
                System.out.println("请输入用户姓名:");
                String name1 = scanner.nextLine();
                BankOperate.regist(account1, passwd1, name1);
                continue;
            }
            System.out.println("请输入密码:");
            String passwd2 = scanner.nextLine();
            // BankOperate.logine(account, passwd2);
            boolean result = BankOperate.logine(account, passwd2);
            if (result) {
                System.out.println("登录成功,欢迎" + BankTool.account[BankTool.index].getName() + "光临");
                operate();
            } else {
                System.out.println("输入错误,请重新输入。");
            }
        }
    }

    public static void operate() {
        Scanner scanner1 = new Scanner(System.in);
        while (true) {
            System.out.println("请选择服务项目:");
            System.out.println("1.存款");
            System.out.println("2.取款");
            System.out.println("3.查询");
            System.out.println("4.修改密码");
            System.out.println("5.退出");
            int n = scanner1.nextInt();
            switch (n) {

                case 1:
                    System.out.println("请输入存款金额:");
                    double money = scanner1.nextDouble();
                    BankOperate.save(money);

                    break;
                case 2:
                    System.out.println("请输入取款金额:");
                    double money1 = scanner1.nextDouble();
                    BankOperate.take(money1);
                    break;
                case 3:
                    BankOperate.check();
                    break;
                case 4:
                    Scanner sc=new Scanner(System.in);
                    System.out.println("请输入新密码:");
                    String new_password=sc.nextLine();
                    BankOperate.change(new_password);
                    break;
                case 5:

                    return;

                default:
                    System.out.println("输入错误,请重新输入。");
                    break;
            }
        }
    }
}

第二题:

img




import java.util.ArrayList;
import java.util.Scanner;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class dome {
    public static void main(String[] args) {
        System.out.println("请输入表达式:");
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        //System.out.println(s.substring(1));
        System.out.println("结果是:");
        calculate(s);
    }
    //负数的问题
    public static int calculate(String strExpression)
    {
        String s = simplify(strExpression);
        //System.out.println("s : "+s);
        String numStr = "";//记录数字
        Stack<Character> opeStack = new Stack<>();//符号站
        int l = s.length();//字符串长度 l
        List<String> list = new ArrayList<>();
        for(int i=0;i<l;i++)
        {
            char ch = s.charAt(i);
            if(isAllOpe(ch))
            {
                if(numStr!="")
                {
                    list.add(numStr);
                    numStr="";
                }

                if(ch=='(')
                {
                    opeStack.push(ch);
                }
                else if(isOpe(ch))
                {
                    char top = opeStack.peek();
                    if(isGreater(ch, top))
                    // ch优先级大于top 压栈
                    {
                        opeStack.push(ch);
                    }
                    else
                    //否则,将栈内元素出栈,直到遇见 '(' 然后将ch压栈
                    {
                        while(true)
                        //必须先判断一下 后出栈 否则会有空栈异常
                        {
                            char t=opeStack.peek();
                            if(t=='(')
                                break;
                            if(isGreater(ch, t))
                                break;
                            list.add(Character.toString(t));
                            t=opeStack.pop();
                        }
                        opeStack.push(ch);
                    }
                }
                else if(ch==')')
                {
                    char t = opeStack.pop();
                    while(t!='('&&!opeStack.isEmpty())
                    {
                        list.add(Character.toString(t));
                        t = opeStack.pop();
                    }
                }
            }
            else//处理数字
            {
                numStr+=ch;
            }
        }
        //计算后缀表达式
        //System.out.println(list.toString());
        Stack<Integer> num = new Stack<>();
        int size = list.size();
        for(int i=0;i<size;i++)
        {
            String t =list.get(i);
            if(isNumeric(t))
            {//将t转换成int 方便计算
                num.push(Integer.parseInt(t));
            }
            else
            {
                //如果t为运算符则 只有一位
                char c = t.charAt(0);
                int b = num.pop();
                //如果有 算式是类似于 -8-8 这样的需要判断一下栈是否为空
                int a = num.pop();
                switch(c)
                {
                    case '+':
                        num.push(a+b);
                        break;
                    case '-':
                        num.push(a-b);
                        break;
                    case '*':
                        num.push(a*b);
                        break;
                    case '/':
                        num.push(a/b);
                        break;
                    default:
                        break;
                }
            }
        }
        System.out.println(num.pop());
        return 0;
    }

    /**化简表达式
     * 将表达式中的 {}[]替换为()
     * 负数的处理
     * 为了方便将中缀转换为后缀在字符串前后分别加上(,) eg:"1+1" 变为"(1+1)"
     * @param str 输入的字符串
     * @return s 返回简化完的表达式
     */
    public static String simplify(String str)
    {
        //负数的处理
        // 处理负数,这里在-前面的位置加入一个0,如-4变为0-4,
        // 细节:注意-开头的地方前面一定不能是数字或者反括号,如9-0,(3-4)-5,这里地方是不能加0的
        // 它的后面可以是数字或者正括号,如-9=>0-9, -(3*3)=>0-(3*3)
        String s = str.replaceAll("(?<![0-9)}\\]])(?=-[0-9({\\[])", "0");
        //将表达式中的 {}[]替换为()
        s = s.replace('[', '(');
        s = s.replace('{', '(');
        s = s.replace(']', ')');
        s = s.replace(']', ')');
        //为了方便将中缀转换为后缀在字符串前后分别加上(,)
        s="("+s+")";
        return s ;
    }
    /**判断字符c是否为合理的运算符
     *
     * @param c
     * @return
     */
    public static boolean isOpe(char c)
    {
        if(c=='+'||c=='-'||c=='*'||c=='/')
            return true;
        else
            return false;
    }
    public static boolean isAllOpe(char c)
    {
        if(c=='+'||c=='-'||c=='*'||c=='/')
            return true;
        else if(c=='('||c==')')
            return true;
        else
            return false;
    }
    /**
     * 比较字符等级a是否大于b
     * @param a
     * @param b
     * @return 大于返回true 小于等于返回false
     */
    public static boolean isGreater(char a,char b)
    {
        int a1 = getLevel(a);
        int b1 = getLevel(b);
        if(a1>b1)
            return true;
        else
            return false;
    }
    /**
     * 得到一个字符的优先级
     * @param a
     * @return
     */
    public static int getLevel(char a)
    {
        if(a=='+')
            return 0;
        else if(a=='-')
            return 1;
        else if(a=='*')
            return 3;
        else if(a=='/')
            return 4;
        else
            return -1;
    }
    //判断是不是数字
    public static boolean isNumeric(String str){
        Pattern pattern = Pattern.compile("[0-9]*");
        Matcher isNum = pattern.matcher(str);
        if( !isNum.matches() ){
            return false;
        }
        return true;
    }
}


第二题:
带界面的

img



import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Objects;

import javax.swing.*;

//Calculator类,继承JFrame框架,实现事件监听器接口
public class Calculator extends JFrame implements ActionListener {
    private final String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt",
            "%", "x*x", "*", "(", ")", ".", "=" };
    private JButton keys[] = new JButton[KEYS.length];
    private JTextArea resultText = new JTextArea("0.0");// 文本域组件TextArea可容纳多行文本;文本框内容初始值设为0.0
    private JTextArea History = new JTextArea();// 历史记录文本框初始值设为空
    private JPanel jp2=new JPanel();
    private JScrollPane gdt1=new JScrollPane(resultText);//给输入显示屏文本域新建一个垂直滚动滑条
    private JScrollPane gdt2=new JScrollPane(History);//给历史记录文本域新建一个垂直滚动滑条
    // private JScrollPane gdt3=new JScrollPane(History);//给历史记录文本域新建一个水平滚动滑条
    private JLabel label = new JLabel("历史记录");
    private String b = "";

    // 构造方法
    public Calculator() {
        super("Caculator");//“超”关键字,表示调用父类的构造函数,
        resultText.setBounds(20, 18, 255, 115);// 设置文本框大小
        resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框内容右对齐
        resultText.setEditable(false);// 文本框不允许修改结果
        History.setBounds(290, 40, 250,370);// 设置文本框大小
        History.setAlignmentX(LEFT_ALIGNMENT);// 文本框内容右对齐
        History.setEditable(false);// 文本框不允许修改结果
        label.setBounds(300, 15, 100, 20);//设置标签位置及大小
        jp2.setBounds(290,40,250,370);//设置面板窗口位置及大小
        jp2.setLayout(new GridLayout());
        JPanel jp1 = new JPanel();
        jp1.setBounds(20,18,255,115);//设置面板窗口位置及大小
        jp1.setLayout(new GridLayout());
        resultText.setLineWrap(true);// 激活自动换行功能
        resultText.setWrapStyleWord(true);// 激活断行不断字功能
        resultText.setSelectedTextColor(Color.RED);
        History.setLineWrap(true);//自动换行
        History.setWrapStyleWord(true);
        History.setSelectedTextColor(Color.blue);
        gdt1.setViewportView(resultText);//使滚动条显示出来
        gdt2.setViewportView(History);
        gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示
        gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条一直显示
        gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//设置让水平滚动条一直显示
        jp1.add(gdt1);//将滚动条添加入面板窗口中
        jp2.add(gdt2);
        this.add(jp1);//将面板添加到总窗体中
        this.add(jp2);//将面板添加到总窗体中
        this.setLayout(null);
        this.add(label);// 新建“历史记录”标签
        //this.add(resultText);// 新建文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示或者发生覆盖
        //this.add(History);// 新建历史记录文本框,该语句会添加进去一个新的JTextArea导致带有滚动条的文本无法显示

        // 放置按钮
        int x = 20, y = 150;
        for (int i = 0; i < KEYS.length; i++)
        {
            keys[i] = new JButton();
            keys[i].setText(KEYS[i]);
            keys[i].setBounds(x, y, 60, 40);
            if (x < 215) {
                x += 65;
            } else {
                x = 20;
                y += 45;
            }
            this.add(keys[i]);
        }
        for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件监听器
        {
            keys[i].addActionListener(this);
        }
        this.setResizable(false);
        this.setBounds(500, 200, 567, 480);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    // 事件处理
    public void actionPerformed(ActionEvent e)
    {
        //History.setText(b);//使输入的表达式显示在历史记录文本框中
        String label=e.getActionCommand();//获得事件源的标签
        if(Objects.equals(label, "="))//
        {
            resultText.setText(this.b);
            History.setText(History.getText()+resultText.getText());
            if(label.equals("="))//调用计算方法,得出最终结果
            {
                String[] s =houzhui(this.b);
                String result=Result(s);
                this.b=result+"";
                //更新文本框,当前结果在字符串b中,并未删除,下一次输入接着此结果以实现连续运算
                resultText.setText(this.b);
                History.setText(History.getText()+"="+resultText.getText()+"\n");
            }
        }
        else if(Objects.equals(label, "AC"))//清空按钮,消除显示屏文本框前面所有的输入和结果
        {
            this.b="";
            resultText.setText("0");//更新文本域的显示,显示初始值;
        }
        else if(Objects.equals(label, "sqrt"))
        {
            String n=kfys(this.b);
            resultText.setText("sqrt"+"("+this.b+")"+"="+n);//使运算表达式显示在输入界面
            History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框
            this.b=n;
        }
        else if(Objects.equals(label, "x*x"))
        {
            String m=pfys(this.b);
            resultText.setText(this.b+"^2"+"="+m);//使运算表达式显示在输入界面
            History.setText(History.getText()+this.b+"^2"+"=");//获取输入界面的运算表达式并使其显示在历史记录文本框
            this.b=m;
        }
        else if(Objects.equals(label, "e") || Objects.equals(label, "pi"))
        {
            if(label.equals("e"))
            {
                String m=String.valueOf(2.71828);//将e的值以字符串的形式传给m
                this.b=this.b+m;//保留显示m之前输入的运算符或数字字符继续下一步运算
                resultText.setText(this.b);
                // History.setText(History.getText()+this.b);
            }
            if(label.equals("pi"))
            {
                String m=String.valueOf(3.14159265);
                this.b=this.b+m;
                resultText.setText(this.b);
                // History.setText(History.getText()+this.b);
            }
        }
        else
        {
            this.b=this.b+label;
            resultText.setText(this.b);
            // History.setText(History.getText()+this.b);


        }
        //History.setText(History.getText()+this.b);//使输入的表达式显示在历史记录文本框中
    }
    //将中缀表达式转换为后缀表达式
    private String[] houzhui(String str) {
        String s = "";// 用于承接多位数的字符串
        char[] opStack = new char[100];// 静态栈,对用户输入的操作符进行处理,用于存储运算符
        String[] postQueue = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独立的字符串
        int top = -1, j = 0;// 静态指针top,控制变量j
        for (int i = 0; i < str.length(); i++)// 遍历中缀表达式
        // indexof函数,返回字串首次出现的位置;charAt函数返回index位置处的字符;
        {
            if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况直接入队
            {
                s = "";// 作为承接字符,每次开始时都要清空
                for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
                    s = s + str.charAt(i);
                    //比如,中缀表达式:234+4*2,我们扫描这个字符串的时候,s的作用相当于用来存储长度为3个字符的操作数:234
                }
                i--;
                postQueue[j] = s;// 数字字符直接加入后缀表达式
                j++;
            }
            else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号
                top++;
                opStack[top] = str.charAt(i);// 左括号入栈
            }
            else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号
                for (;;)// 栈顶元素循环出栈,直到遇到左括号为止
                {
                    if (opStack[top] != '(') {// 栈顶元素不是左括号
                        postQueue[j] = opStack[top] + "";// 栈顶元素出栈
                        j++;
                        top--;
                    } else { // 找到栈顶元素是左括号
                        top--;// 删除栈顶左括号
                        break;// 循环结束
                    }
                }
            }
            else if ("*%/+-".indexOf(str.charAt(i)) >= 0)// 遇到运算符
            {
                if (top == -1)
                {// 若栈为空则直接入栈
                    top++;
                    opStack[top] = str.charAt(i);
                }
                else if ("*%/".indexOf(opStack[top]) >= 0)
                {// 当栈顶元素为高优先级运算符时,让栈顶元素出栈进入后缀表达式后,当前运算符再入栈
                    postQueue[j] = opStack[top] + "";
                    j++;
                    opStack[top] = str.charAt(i);
                }
                else
                {
                    top++;
                    opStack[top] = str.charAt(i);// 当前元素入栈
                }
            }
        }
        while (top != -1) {// 遍历结束后将栈中剩余元素依次出栈进入后缀表达式
            postQueue[j] = opStack[top] + "";
            j++;
            top--;
        }
        return postQueue;
    }

    //开方运算方法
    public String kfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.sqrt(a);
        result = String.valueOf(b);//将运算结果转换为string类型并赋给string类型的变量result
        return result;
    }

    //平方运算方法
    public String pfys(String str) {
        String result = "";
        double a = Double.parseDouble(str), b = 0;
        b = Math.pow(a, 2);
        result = String.valueOf(b);
        return result;
    }

    // 计算后缀表达式,并返回最终结果
    public String Result(String[] str) {
        String[] Result = new String[100];// 顺序存储的栈,数据类型为字符串
        int Top = -1;// 静态指针Top
        for (int i = 0; str[i] != null; i++) {
            if ("+-*%/".indexOf(str[i]) < 0) {  //遇到数字,直接入栈
                Top++;
                Result[Top] = str[i];
            }
            if ("+-*%/".indexOf(str[i]) >= 0)// 遇到运算符字符,将栈顶两个元素出栈计算并将结果返回栈顶
            {
                double x, y, n;
                x = Double.parseDouble(Result[Top]);// 顺序出栈两个数字字符串,并转换为double类型
                Top--;
                y = Double.parseDouble(Result[Top]);
                Top--;
                if ("*".indexOf(str[i]) >= 0) {
                    n = y * x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈

                }
                if ("/".indexOf(str[i]) >= 0)
                {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y / x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("%".indexOf(str[i]) >= 0)
                {
                    if (x == 0)// 被除数不允许为0
                    {
                        String s = "error!";
                        return s;
                    } else {
                        n = y % x;
                        Top++;
                        Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                    }
                }
                if ("-".indexOf(str[i]) >= 0) {
                    n = y - x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }
                if ("+".indexOf(str[i]) >= 0) {
                    n = y + x;
                    Top++;
                    Result[Top] = String.valueOf(n);// 将运算结果重新入栈
                }
            }
        }
        return Result[Top];// 返回最终结果
    }

    // 主函数
    public static void main(String[] args) {
        Calculator a = new Calculator();
    }
}



这里有一个做得很好的,可以修改一下:
https://blog.csdn.net/m0_61926454/article/details/124828202

1、ATM 柜员机模拟程序

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class ATM extends JFrame {
    private static final long serialVersionUID = 1L;

    // 卡号和密码
    private static final String CARD_NUMBER = "123456";
    private static final String PASSWORD = "123456";

    // 初始余额
    private static final int INITIAL_BALANCE = 10000;

    // 每次取款金额为 100 的倍数,总额不超过 5000 元
    private static final int WITHDRAW_AMOUNT = 100;
    private static final int MAX_WITHDRAW_AMOUNT = 5000;

    // 当前余额
    private int balance;

    // 卡号输入框
    private JTextField cardNumberField;

    // 密码输入框
    private JPasswordField passwordField;

    // 取款金额输入框
    private JTextField withdrawAmountField;

    // 存款金额输入框
    private JTextField depositAmountField;

    // 新密码输入框
    private JPasswordField newPasswordField;

    // 确认新密码输入框
    private JPasswordField confirmPasswordField;

    public ATM() {
        super("ATM 柜员机模拟程序");

        balance = INITIAL_BALANCE;

        // 卡号输入面板
        JPanel cardNumberPanel = new JPanel();
        cardNumberPanel.add(new JLabel("卡号:"));
       
        cardNumberField = new JTextField(20);
        cardNumberPanel.add(cardNumberField);

        // 密码输入面板
        JPanel passwordPanel = new JPanel();
        passwordPanel.add(new JLabel("密码:"));
        passwordField = new JPasswordField(20);
        passwordPanel.add(passwordField);

        // 登录按钮
        JButton loginButton = new JButton("登录");
        loginButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String cardNumber = cardNumberField.getText();
                String password = new String(passwordField.getPassword());

                if (CARD_NUMBER.equals(cardNumber) && PASSWORD.equals(password)) {
                    showMainMenu();
                } else {
                    showErrorMessage("卡号或密码错误");
                }
            }
        });

        // 登录面板
        JPanel loginPanel = new JPanel(new GridLayout(3, 1));
        loginPanel.add(cardNumberPanel);
        loginPanel.add(passwordPanel);
        loginPanel.add(loginButton);

        add(loginPanel, BorderLayout.CENTER);

        setSize(300, 150);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    // 展示主菜单
    private void showMainMenu() {
        // 查询余额按钮
        JButton balanceButton = new JButton("查询余额");
        balanceButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showBalance();
            }
        });

        // ATM 取款按钮
        JButton withdrawButton = new JButton("ATM 取款");
        withdrawButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showWithdrawMenu();
            }
        });

        // ATM 存款按钮
        JButton depositButton = new JButton("ATM 存款");
        depositButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showDepositMenu();
            }
        });

        // 修改密码按钮
        JButton changePasswordButton = new JButton("修改密码");
        changePasswordButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showChangePasswordMenu();
            }
        });

        // 退出按钮
        JButton exitButton = new JButton("退出");
        exitButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        // 主菜单面板
        JPanel mainMenuPanel = new JPanel(new GridLayout(5, 1));
        mainMenuPanel.add(balanceButton);
        mainMenuPanel.add(withdrawButton);
        mainMenuPanel.add(depositButton);
        mainMenuPanel.add(changePasswordButton);
        mainMenuPanel.add(exitButton);

        remove(loginPanel);
        add(mainMenuPanel, BorderLayout.CENTER);
        setVisible(true);
    }

    // 展示余额
    private void showBalance() {
        JLabel balanceLabel = new JLabel("余额: " + balance);
        JButton backButton = new JButton("返回");
        backButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                showMainMenu();
            }
        });

        // 余额面板
        JPanel balancePanel = new JPanel(new GridLayout(2, 1));
        balancePanel.add(balanceLabel);
        balancePanel.add(backButton);

        remove(mainMenuPanel);
        add(balancePanel, BorderLayout.CENTER);
        setVisible(true);
    }

    // 展示取款菜单
    private void showWithdrawMenu() {
        JPanel withdrawPanel = new JPanel(new GridLayout(3, 1));
        withdrawPanel.add(new JLabel("输入取款金额(100的倍数, 不超过5000元):"));

        // 取款金额输入框
        JTextField amountField = new JTextField(20);
        withdrawPanel.add(amountField);

        // 确认按钮
        JButton confirmButton = new JButton("确认");
        confirmButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String amountStr = amountField.getText();
                int amount = 0;
                try {
                    amount = Integer.parseInt(amountStr);
                } catch (NumberFormatException ex) {
                    showErrorMessage("金额格式不正确");
                    return;
                }

                if (amount % 100 != 0) {
                    showErrorMessage("金额必须为100的倍数");
                    return;
                }
                if (amount > 5000) {
                    showErrorMessage("一次取款不能超过5000元");
                    return;
                }
                if(amount > balance) {
                    showErrorMessage("余额不足");
                    return;
                }
                balance -= amount;
                showSuccessMessage("取款成功, 当前余额: " + balance);
            }
        });
        withdrawPanel.add(confirmButton);
        remove(mainMenuPanel);
        add(withdrawPanel, BorderLayout.CENTER);
        setVisible(true);
    }

    // 展示存款菜单
    private void showDepositMenu() {
        JPanel depositPanel = new JPanel(new GridLayout(3, 1));
        depositPanel.add(new JLabel("输入存款金额:"));

        // 存款金额输入框
        JTextField amountField = new JTextField(20);
        depositPanel.add(amountField);

        // 确认按钮
        JButton confirmButton = new JButton("确认");
        confirmButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String amountStr = amountField.getText();
                int amount = 0;
                try {
                    amount = Integer.parseInt(amountStr);
                } catch (NumberFormatException ex) {
                    showErrorMessage("金额格式不正确");
                    return;
                }

                if (amount < 0) {
                    showErrorMessage("存款金额不能为负数");
                    return;
                }
                balance += amount;
                showSuccessMessage("存款成功, 当前余额: " + balance);
            }
        });
        depositPanel.add(confirmButton);

        remove(mainMenuPanel);
        add(depositPanel, BorderLayout.CENTER);
        setVisible(true);
    }

    // 展示修改密码菜单
    private void showChangePasswordMenu() {
        JPanel changePasswordPanel = new JPanel(new GridLayout(5, 1));
        changePasswordPanel.add(new JLabel("输入旧密码:"));

        // 旧密码输入框
        JPasswordField oldPasswordField = new JPasswordField(20);
        changePasswordPanel.add(oldPasswordField);

        changePasswordPanel.add(new JLabel("输入新密码(不能全为相同的数字, 长度不小于6位):"));

        // 新密码输入框
        JPasswordField newPasswordField = new JPasswordField(20);
        changePasswordPanel.add(newPasswordField);

        changePasswordPanel.add(new JLabel("确认新密码:"));

        // 确认新密码输入框
        JPasswordField confirmPasswordField = new JPasswordField(20);
        changePasswordPanel.add(confirmPasswordField);

        // 确认按钮
        JButton confirmButton = new JButton("确认");
        confirmButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                char[] oldPassword = oldPasswordField.getPassword();
                if (!Arrays.equals(oldPassword, password)) {
                    showErrorMessage("旧密码不正确");
                    return;
                }
                char[] newPassword = newPasswordField.getPassword();
                if (newPassword.length < 6) {
                    showErrorMessage("新密码长度不能小于6位");
                    return;
                }

                boolean allSame = true;
                char first = newPassword[0];
                for (int i = 1; i < newPassword.length; i++) {
                    if (newPassword[i] != first) {
                        allSame = false;
                        break;
                    }
                }
                if (allSame) {
                    showErrorMessage("新密码不能全为相同的数字");
                    return;
                }

                char[] confirmPassword = confirmPasswordField.getPassword();
                if (!Arrays.equals(newPassword, confirmPassword)) {
                    showErrorMessage("两次输入的新密码不一致");
                    return;
                }

                password = newPassword;
                showSuccessMessage("密码修改成功");
            }
        });
        changePasswordPanel.add(confirmButton);

        remove(mainMenuPanel);
        add(changePasswordPanel, BorderLayout.CENTER);
        setVisible(true);
    }

    // 展示错误信息
    private void showErrorMessage(String message) {
        JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE);
    }

    // 展示成功信息
    private void showSuccessMessage(String message) {
        JOptionPane.showMessageDialog(this, message, "成功", JOptionPane.INFORMATION_MESSAGE);
    }

    public static void main(String[] args) {
        new ATM();
    }
}