项目一 计算器的创建

按钮输入运算符,界面显示等式,可输出运算结果。

可见查查运算历史,检查运算式的合法性。

可实现四则运算,加减乘除括号等。

可满足小数运算。

实验预习

Java Swing的简单操作

1.JPanel:

面板组件,非顶层容器
一个界面只有一个JFrame窗体组件,但可以有多个JPanel面板组件,而JPanel上也可以使用布局管理器,这样组合可以达到比较复杂的布局效果

注意事项:
1.JPanel是JComponent的子类
2.属于容器类组件,可以加入别的组件
3.默认布局管理器是FlowLayout

2.button:

 push”button.button 的实现可以通过操作进行配置,并在一定程度上进行控制。使用带按钮的动作有许多好处,不仅仅是直接配置按钮。

JButton():建立一个按钮。

JButton(Icon icon):建立一个有图像的按钮。

JButton(String icon):建立一个有文字的按钮。

JButton(String text,Icon icon):建立一个有图像与文字的按钮。
 

3.this.setTitle("多种布局格式");  //框架标题;

4.this.setSize(400,200);    //框架尺寸;

5.this.setLocation(300,300);    //框架坐标;

6.this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //关闭操作按钮的设置

7.this.setVisible(true);     //框架可视化

8.BorderLayout;          // 向边框里添加组件。边界布局展示了一个容器,安排和调整其组件以适应五个区域: 北部、南部、东部、西部和中心。每个区域可能包含不超过一个组成部分,并由一个相应的常量标识: 北、南、东、西和中心。当向具有边框布局的容器添加组件时,使用以下五个常量之一,例如: panel p = new panel () ; p.setlayout (new borderlayout ()) ; p.add (new button (“ okay”) ,borderlayout.south) ;

9.pack  //使窗口的大小适合其子组件的首选大小和布局。如果任何一个窗口的尺寸小于之前调用 setminimumsize 方法所指定的最小尺寸,则窗口的宽度和高度将自动放大。

10.setLayout创建一个布局管理器,

具有指定的对齐方式以及指定的水平和垂直间隙。
对齐参数的值必须是以下之一:FlowLayout.LEFT、FlowLayout.RIGHT、FlowLayout.CENTER、FlowLayout.LEADING 或 FlowLayout.TRAILING。
参数:
align - 对齐值
hgap - 组件之间以及组件与 Container 的边之间的水平间隙
vgap - 组件之间以及组件与 Container 的边之间的垂直间隙

11.JFrame 类与 Frame 稍微不兼容。 与所有其他 JFC/Swing 顶级容器一样,JFrame 包含一个 JRootPane 作为其唯一子项。 根窗格提供的内容窗格通常应包含 JFrame 显示的所有非菜单组件。 这与 AWT Frame 情况不同。 为方便起见,重写了此类的 add、remove 和 setLayout 方法,以便它们将调用委托给 ContentPane 的相应方法。

12.Java 框架教程:

如何制作框架(主窗口)(Java™教程>使用 Swing >创建 GUI 使用 Swing 组件) (oracle.com)

13.实现算法为双栈, public static Stack<String> num = new Stack<>();//定义数字栈。

                                 public static Stack<String> operator = new Stack<>();//定义运算符栈。

实现代码:

import java.awt.*;//包含用于创建用户界面和绘制图形和图像的所有类。
import java.awt.event.*;//提供接口和类来处理由 AWT 组件触发的不同类型的事件。
import java.util.Stack;
import javax.swing.*;
class Calculator extends JFrame implements ActionListener {//接收动作事件的监听器接口。
    static Calculator frm = new Calculator();//定义框架frm。
    static JPanel pan1 = new JPanel();//定义放置数字等按钮的容器。
    static JPanel pan2 = new JPanel();//定义放置其他按钮的容器。
    static JTextField pan3 =new JTextField();//可编辑的文本框显示历史记录。
    static JTextField tf = new JTextField("0");//定义计算结果显示框初始为'0'。
    static JTextField RET=new JTextField();//定义运算式的显示框。
    static JButton[] b = new JButton[10];//定义10个按钮数组。
    static JButton bp, ba, bs, bm, bd, be, bc, br,qf,ds;//定义其他运算符按钮。
    String expression = new String();//定义字符串,用于保存输入的表达式。
    int flash=0;
    public static void main(String[] args) {
        for (int i = 0; i <= 9; i++)
            b[i] = new JButton("" + i);//给每个按钮赋值。
        bp = new JButton(".");
        ba = new JButton("+");
        bs = new JButton("-");
        bm = new JButton("*");
        bd = new JButton("/");
        be = new JButton("=");
        bc = new JButton("c");
        br = new JButton("<--");
        qf=new JButton("(");
        ds=new JButton(")");
        frm.setTitle(" 天河三号");//给框架设标题。
        frm.setLayout(null);//设置布局管理器,具有指定的对齐方式以及指定的水平和垂直间隙。
        frm.setSize(450, 340);//设定frm的大小。
        frm.setResizable(false);//设定为大小不可更改。
        GridLayout grid1 = new GridLayout(4, 4);//用于在矩形网格中布置容器的组件。此处为四行四列的矩阵网格。
        GridLayout grid2 = new GridLayout(1, 4);//容器被分成大小相等一行四列的矩形,每个矩形中放置一个组件。
        pan1.setLayout(grid1);//将第一个按钮容器分为四行四列。
        pan2.setLayout(grid2);
        RET.setBounds(32,10,280,30);
        tf.setBounds(32,38, 280, 35);//设置结果框大小。
        pan1.setBounds(32, 80, 280, 160);
        pan2.setBounds(32, 240, 280, 40);//设置容器大小。
        pan3.setBounds(312,10,95,270);
        tf.setBackground(Color.green);//设置结果框背景颜色。
        tf.setHorizontalAlignment(JTextField.RIGHT);//设置结果框从右边输入。
        RET.setBackground(Color.cyan);//设置表达式框背景颜色。
        RET.setText("请输入正确的表达式");//RET框的默认显示。
        RET.setHorizontalAlignment(JTextField.RIGHT);//RET框从右边输出。
        pan3.setBackground(Color.lightGray);//上条历史记录框的颜色。
        pan1.add(b[7]);pan1.add(b[8]);pan1.add(b[9]);pan1.add(bd);
        pan1.add(b[4]);pan1.add(b[5]);pan1.add(b[6]);pan1.add(bm);
        pan1.add(b[1]);pan1.add(b[2]);pan1.add(b[3]);pan1.add(bs);
        pan1.add(b[0]);pan1.add(bp);pan1.add(be);pan1.add(ba);
        pan2.add(bc);pan2.add(qf);pan2.add(ds);pan2.add(br);//给容器矩阵中加入按钮。
        frm.add(tf);//将容器框都加入frm框架。
        frm.add(RET);
        frm.add(pan1);
        frm.add(pan2);
        frm.add(pan3);
        for (int i = 0; i <= 9; i++)//按钮与监听接口的连接。
            b[i].addActionListener(frm);
        bd.addActionListener(frm);
        bm.addActionListener(frm);
        bs.addActionListener(frm);
        ba.addActionListener(frm);
        bc.addActionListener(frm);
        br.addActionListener(frm);
        bp.addActionListener(frm);
        be.addActionListener(frm);
        qf.addActionListener(frm);
        ds.addActionListener(frm);
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setVisible(true);
    }        //界面设计;
    String S1;
    String S2;

static int f=0;
    public void actionPerformed(ActionEvent e) {//处理监听信号做出行为

        if(expression.isEmpty()){
            if(e.getActionCommand()=="."){//开头输'.'前面补“0".
                expression="0"+e.getActionCommand();
                flash=1;
            }
            else if(e.getActionCommand()=="-"){
                expression="0-"+expression;//开头输'-'变为负数。
                tf.setText(expression);
            }
            else if(e.getActionCommand()=="(")expression+=e.getActionCommand();//
        }
        if (e.getActionCommand().equals("=")) {

             if(expression.charAt(expression.length() - 1) == '.')expression=expression+"0";
             if(     expression.charAt(expression.length() - 1) != '-' &&
                    expression.charAt(expression.length() - 1) != '+' &&//等号之前不能有运算符及右括号。
                    expression.charAt(expression.length() - 1) != '*' &&
                    expression.charAt(expression.length() - 1) != '/' &&
                    expression.charAt(expression.length() - 1) != '(' )
            {
                S1=expression;
                RET.setText(expression+"=");
                expression = Calculate.count(expression);
                S2=expression;
                tf.setText(expression);
                if(expression.charAt(0)=='-')expression="0"+expression;
            } }
        else if (e.getActionCommand().equals("c")) {
            expression ="";    //按'c'键表达式置空
            tf.setText("0");
            flash=0;
            pan3.setText(S1+"="+S2);
            RET.setText("请输入正确的表达式");//RET框恢复默认。
        }

        else if (e.getActionCommand().equals("<--")) {
            expression = expression.substring(0, expression.length() - 1);
            tf.setText(expression);//用于删除表达式最后一个字符。
        }
        else if(e.getActionCommand().equals("+") ||
                e.getActionCommand().equals("-") ||
                e.getActionCommand().equals("*") ||
                e.getActionCommand().equals("/") ||
                e.getActionCommand().equals(")")
        )
        {

            if   (  expression.charAt(expression.length() - 1) != '-' &&
                    expression.charAt(expression.length() - 1) != '+' &&//设置符号不能连续输入。
                    expression.charAt(expression.length() - 1) != '*' &&
                    expression.charAt(expression.length() - 1) != '/'
            )
            {
                if(expression.charAt(expression.length() - 1) == '.'){
                    expression=expression+"0"+e.getActionCommand();//运算符前面是'.'自动补'0'。

                }
                else if(expression.charAt(expression.length()-1)=='('&&e.getActionCommand().equals("-")){
                    expression=expression+"0-";}//左括号后面允许输负号。
                else if(e.getActionCommand().equals("*")||
                        e.getActionCommand().equals("/")||
                        e.getActionCommand().equals("+"))
                { if(expression.charAt(expression.length()-1)!='(')//'('后不能输运算符。
                    expression=expression+e.getActionCommand();tf.setText(expression);

                }
                else if(e.getActionCommand().equals(")")){
                    if(expression.charAt(expression.length()-1)!='(' &&
                            expression.charAt(expression.length()-1)!=')'&&
                            expression.contains("(")) {
                        expression+=e.getActionCommand();//括号内容不能为空。

                    }
                }
                else expression+=e.getActionCommand();flash=0;
            }

            tf.setText(expression);
        }

        else if(e.getActionCommand().equals(".")) {
            if(flash==0){
                if (expression.charAt(expression.length() - 1) == '(' ||
                        expression.charAt(expression.length() - 1) == '+' ||
                        expression.charAt(expression.length() - 1) == '-' ||
                        expression.charAt(expression.length() - 1) == '*' ||
                        expression.charAt(expression.length() - 1) == '/' ){
                    expression = expression + "0" + e.getActionCommand();
            }
             //运算符后面输'.'自动补'0'。
                if(expression.charAt(expression.length() - 1) != '.'){
                    expression+=e.getActionCommand();//'.'不能连续输入。
                }
            }tf.setText(expression);
            flash=1;
        }
        else if(e.getActionCommand().equals("(")){
            if(expression.charAt(expression.length() - 1) == '+' ||
                    expression.charAt(expression.length() - 1) == '-' ||
                    expression.charAt(expression.length() - 1) == '*' ||
                    expression.charAt(expression.length() - 1) == '/'
            )expression=expression+e.getActionCommand();
            tf.setText(expression);
        }
        else {
            expression += e.getActionCommand();
            tf.setText(expression);
        }
    }
    static class Calculate {
        public static Stack<String> num = new Stack<>();//定义数字栈。
        public static Stack<String> operator = new Stack<>();//定义运算符栈。
        public static Stack<String> operator2=new Stack<>();
        public static Stack<String> num2=new Stack<>();
        public static void work() {//括号外的计算函数。
            String s2 = num.pop();
            String s1 = num.pop();
            float num2 = Float.parseFloat(s2);
            float num1 = Float.parseFloat(s1);
            String op = operator.pop();
            float num3;
            switch (op) {
                case "+":
                    num3 = num1 + num2;
                    num.push(num3 + "");
                    break;
                case "-":
                    num3 = num1 - num2;
                    num.push(num3 + "");
                    break;
                case "*":
                    num3 = num1 * num2;
                    num.push(num3 + "");
                    break;
                case "/":
                    num3 = num1 / num2;
                    num.push(num3 + "");
                    break;
            }
        }
        public static void work2() {//括号内的计算函数。
            String s2 = num2.pop();
            String s1 = num2.pop();
            float num4 = Float.parseFloat(s2);
            float num3= Float.parseFloat(s1);
            String op = operator2.pop();
            float num5;
            switch (op) {
                case "+":
                    num5 = num3 + num4;
                    num2.push(num5 + "");
                    break;
                case "-":
                    num5 = num3 - num4;
                    num2.push(num5 + "");
                    break;
                case "*":
                    num5 = num3 * num4;
                    num2.push(num5 + "");
                    break;
                case "/":
                    num5 = num3 / num4;
                    num2.push(num5 + "");
                    break;
            }
        }
        public static String count(String s) {
            int i = 0;
            while (i < s.length()) {
                switch (s.charAt(i)) {
                    case '+':
                    case '-':
                        while (!operator.empty()) {
                            work();//运算符栈非空进行运算。
                        }
                        operator.push(s.charAt(i) + "");
                        i++;
                        break;
                    case '*':
                    case '/':
                        while (!operator.empty() && (operator.peek().equals("*") || operator.peek().equals("/"))) {
                            work();
                            System.out.println("Ok");
                        }
                        operator.push(s.charAt(i) + "");
                        i++;
                        break;
                    case '('://计算括号内的值。
                        f=1;
                        i++;
                        while (s.charAt(i)!=')') {//
                            switch (s.charAt(i)) {
                                case '+':
                                case '-':
                                    while (!operator2.empty()) {
                                        work2();
                                    }
                                    operator2.push(s.charAt(i) + "");
                                    i++;
                                    break;
                                case '*':
                                case '/':
                                    while (!operator2.empty()&& (operator2.peek().equals("*")
                                            || operator2.peek().equals("/"))) {
                                        work2();
                                        System.out.println("Ok");
                                    }
                                    operator2.push(s.charAt(i) + "");
                                    i++;
                                    break;
                                default:
                                    String number = "";
                                    for (; s.charAt(i) != ')' && (s.charAt(i) >= '0' && s.charAt(i) <= '9'
                                            || s.charAt(i) == '.'); i++) {
                                        number = number + s.charAt(i);
                                    }
                                    num2.push(number);
                            }
                        }
                        if(s.charAt(i)==')')f=0;
                        i++;
                        while (!operator2.empty()) {
                            work2();
                        }
                        num.push(num2.peek());
                        break;
                    default:
                        String number = "";
                        for (; i < s.length() && (s.charAt(i) >= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.'); i++) {
                            number = number + s.charAt(i);
                        }
                        num.push(number);
                }
            }
            while (!operator.empty()) {
                work();
            }
            return num.peek();//返回栈顶的运算结果。
        }
    }
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡 布

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值