目录

一.界面设计

二.功能设计

 三.代码实现

 四.注意事项


一.界面设计

设计计算器界面时,首先需要建立一个Frame容器,作为显示窗口,之后的界面设计即围绕在该显示窗口中添加功能组件来进行后续操作。

在显示窗口上,可将该界面分为两部分,第一部分即为最上方的文本域组件,用于显示要进行计算的式子,所有的计算式与最终结果均在此文本域中显示。第二部分即为下方的按钮组件,在实现下方的按钮组件,设计思路为,新建若干个Panel容器,将其设置为FlowLayout分布式,以行为单位添加每一行的按钮组件,最后采用Box容器,向其添加之前新建的Panel容器,由于Frame容器默认为BorderLayout分布方式,将文本域组件放置于NORTH,将按钮组件放置于CENTER,之后调整Frame容器的可见性以及大小参数,此时即完成了计算器的界面设计,得到效果图如下:

二.功能设计

在计算器的功能设计中,分为输入过程功能设计与计算过程功能设计。

第一步,输入过程功能设计。该过程主要实现在点击按钮后,在文本域组件中显示点击的按钮内容,以此构成要计算的算式。在这过程中要注意,不能连续出现两个运算符,否则为错误的算式。

此过程采用的实现方式为采用自定义事件监听器的方式,分别对数字按钮和运算符按钮设计自定义事件监听器。

//定义数字按钮的事件监听器类
class myListener_01 implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.append(e.getActionCommand());
            }
        }
//定义运算符的事件监听器类
/*
    1.不能多个运算符相连,否则则不显示后添加的运算符
    2.除号后不能只写0,若除号后只写0,再输入运算符时,会将0删除
*/
class myListener_02 implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e) {
                String str = ta.getText();
                String chs = String.valueOf(str.charAt(str.length() - 1));
                String ch = String.valueOf(str.charAt(str.length()-2));
                if(chs.equals("/") || chs.equals("-") || chs.equals("*") || chs.equals("+"));
                else if(chs.equals("0") && ch.equals("/"))
                {
                    StringBuilder sb = new StringBuilder(str);
                    sb.delete(str.length()-1,str.length());
                    ta.setText(sb.toString());
                }
                else{
                    ta.append(e.getActionCommand());
                }
            }
        }

第二步,计算过程功能设计。通过输入过程的功能设计可以保证输入的算式符合运算规则,在计算过程功能设计中,主要针对在用户点击“=”后按照运算规则进行计算,得出正确结果。

在此过程中采用的方法为,首先取到文本域中此时的算式内容,由于此内容为String类型无法进行直接运算,所以应将其中的数字和算术符进行分离,转化为正确的格式,此处采取遍历的方式进行初步筛选,以此就实现了文本域组件中的内容提取。

/*
    此方法需要传入取得的文本域内容,一个用于存储数字的数组,一个用于存储运算符的数组
*/
public void Traverse(String str,ArrayList<Double> arr,ArrayList<String> chs)
    {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<str.length();++i)
        {
            String ch = String.valueOf(str.charAt(i));
            if(ch.equals("/") || ch.equals("*") || ch.equals("+") || ch.equals("-") || ch.equals("="))
            {
                arr.add(Double.valueOf(sb.toString()));
                chs.add(ch);
                sb.setLength(0);
                continue;
            }
            else
            {
                sb.append(ch);
            }
        }
    }

 之后按照运算规则,为“=”号添加事件监听器,按照上文进行内容提取后,建立运算符在数组中对应的下标与其左右的数字在数组中下标的对应关系,按照先乘除,后加减的顺序进行计算,最终得出运算结果,并显示在文本域中,以此完成此次运算。

b44.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.append(e.getActionCommand());
                ArrayList<Double> arr = new ArrayList<Double>();
                ArrayList<String> chs = new ArrayList<String>();
                Traverse(ta.getText(),arr,chs);

                Double[] d = new Double[arr.size()];
                String[] s = new String[chs.size()];
//                System.out.println(arr);
//                System.out.println(chs);
                boolean flag = true;
                for(int i=0;i<arr.size();++i)
                {
                    d[i] = arr.get(i);
                }
                for(int i=0;i<chs.size();++i)
                {
                    s[i] = chs.get(i);
                }

                for(int i=0;i < s.length;++i)
                {
                    if(s[i].equals("*"))
                    {
                        d[i] = d[i] * d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }

                    if(s[i].equals("/") && d[i+1] != 0)
                    {
                        d[i] = d[i] / d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                    else if (s[i].equals("/") && d[i+1] == 0)
                    {
                        ta.setText("非法输入");
                        flag = false;
                    }
                }

                for(int i=0;i < s.length;++i)
                {
                    if(s[i].equals("+"))
                    {
                        d[i] = d[i] + d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                    if(s[i].equals("-"))
                    {
                        d[i] = d[i] - d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                }
                if(flag) {
                    BigDecimal bd = new BigDecimal(d[0]);
                    bd = bd.setScale(2, RoundingMode.HALF_UP);
                    ta.append(bd.toString());
                }
            }
        });

 三.代码实现

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;

public class Counter {
    //定义一个Window窗口
    Frame frame = new Frame("计算器");

    //组装界面
    public void Init()
    {
        //创建计算器的按键
        Panel p1 = new Panel(new FlowLayout(FlowLayout.LEFT,40,10));
        Button b11 = new Button("C");
        Button b12 = new Button("/");
        Button b13 = new Button("*");
        Button b14 = new Button("del");
        p1.add(b11);
        p1.add(b12);
        p1.add(b13);
        p1.add(b14);

        Panel p2 = new Panel(new FlowLayout(FlowLayout.LEFT,40,10));
        Button b21 = new Button("7");
        Button b22 = new Button("8");
        Button b23 = new Button("9");
        Button b24 = new Button("-");
        p2.add(b21);
        p2.add(b22);
        p2.add(b23);
        p2.add(b24);

        Panel p3 = new Panel(new FlowLayout(FlowLayout.LEFT,40,10));
        Button b31 = new Button("4");
        Button b32 = new Button("5");
        Button b33 = new Button("6");
        Button b34 = new Button("+");
        p3.add(b31);
        p3.add(b32);
        p3.add(b33);
        p3.add(b34);

        Panel p4 = new Panel(new FlowLayout(FlowLayout.LEFT,40,10));
        Button b41 = new Button("1");
        Button b42 = new Button("2");
        Button b43 = new Button("3");
        p4.add(b41);
        p4.add(b42);
        p4.add(b43);

        Panel p5 = new Panel(new FlowLayout(FlowLayout.LEFT,40,10));
        Button b51 = new Button("%");
        Button b52 = new Button("0");
        Button b53 = new Button(".");
        p5.add(b51);
        p5.add(b52);
        p5.add(b53);

        //组装按键
        Box vbox1 = Box.createVerticalBox();
        vbox1.add(p4);
        vbox1.add(p5);
        Box hbox1 = Box.createHorizontalBox();
        Button b44 = new Button("=");
        b44.setSize(25,128);
        hbox1.add(vbox1);
        hbox1.add(b44);
        hbox1.add(Box.createHorizontalStrut(45));


        Box vbox2 = Box.createVerticalBox();
        vbox2.add(p1);
        vbox2.add(p2);
        vbox2.add(p3);
        vbox2.add(hbox1);

        //组装计算器界面
        Panel panel = new Panel(new BorderLayout());
        TextArea ta = new TextArea(5,10);
        panel.add(ta,BorderLayout.NORTH);
        panel.add(vbox2);
        panel.setSize(421,521);

        frame.add(panel);
        frame.pack();
        frame.setLocation(200,200);
        frame.setResizable(false);
        frame.setVisible(true);

        //添加事件监听器
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        b11.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.setText("");
            }
        });

        class myListener_01 implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.append(e.getActionCommand());
            }
        }

        myListener_01 myListener_01 = new myListener_01();
        b21.addActionListener(myListener_01);
        b22.addActionListener(myListener_01);
        b23.addActionListener(myListener_01);
        b31.addActionListener(myListener_01);
        b32.addActionListener(myListener_01);
        b33.addActionListener(myListener_01);
        b41.addActionListener(myListener_01);
        b42.addActionListener(myListener_01);
        b43.addActionListener(myListener_01);
        b52.addActionListener(myListener_01);
        b53.addActionListener(myListener_01);

        b14.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StringBuilder sb = new StringBuilder(ta.getText());
                sb.delete(sb.length()-1,sb.length());
                ta.setText(sb.toString());
            }
        });

        class myListener_02 implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e) {
                String str = ta.getText();
                String chs = String.valueOf(str.charAt(str.length() - 1));
                String ch = String.valueOf(str.charAt(str.length()-2));
                if(chs.equals("/") || chs.equals("-") || chs.equals("*") || chs.equals("+"));
                else if(chs.equals("0") && ch.equals("/"))
                {
                    StringBuilder sb = new StringBuilder(str);
                    sb.delete(str.length()-1,str.length());
                    ta.setText(sb.toString());
                }
                else{
                    ta.append(e.getActionCommand());
                }
            }
        }

        myListener_02 myListener_02 = new myListener_02();
        b12.addActionListener(myListener_02);
        b13.addActionListener(myListener_02);
        b24.addActionListener(myListener_02);
        b34.addActionListener(myListener_02);

        b44.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.append(e.getActionCommand());
                ArrayList<Double> arr = new ArrayList<Double>();
                ArrayList<String> chs = new ArrayList<String>();
                Traverse(ta.getText(),arr,chs);

                Double[] d = new Double[arr.size()];
                String[] s = new String[chs.size()];
//                System.out.println(arr);
//                System.out.println(chs);
                boolean flag = true;
                for(int i=0;i<arr.size();++i)
                {
                    d[i] = arr.get(i);
                }
                for(int i=0;i<chs.size();++i)
                {
                    s[i] = chs.get(i);
                }

                for(int i=0;i < s.length;++i)
                {
                    if(s[i].equals("*"))
                    {
                        d[i] = d[i] * d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }

                    if(s[i].equals("/") && d[i+1] != 0)
                    {
                        d[i] = d[i] / d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                    else if (s[i].equals("/") && d[i+1] == 0)
                    {
                        ta.setText("非法输入");
                        flag = false;
                    }
                }

                for(int i=0;i < s.length;++i)
                {
                    if(s[i].equals("+"))
                    {
                        d[i] = d[i] + d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                    if(s[i].equals("-"))
                    {
                        d[i] = d[i] - d[i+1];
                        sort(d,i+1);
                        sort(s,i);
                    }
                }
                if(flag) {
                    BigDecimal bd = new BigDecimal(d[0]);
                    bd = bd.setScale(2, RoundingMode.HALF_UP);
                    ta.append(bd.toString());
                }
            }
        });

    }

    public  void sort(Object[] arr,int pos)
    {
        for(int j=pos;j<arr.length-1;++j)
        {
            arr[j] = arr[j+1];
        }
    }

    public void Traverse(String str,ArrayList<Double> arr,ArrayList<String> chs)
    {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<str.length();++i)
        {
            String ch = String.valueOf(str.charAt(i));
            if(ch.equals("/") || ch.equals("*") || ch.equals("+") || ch.equals("-") || ch.equals("="))
            {
                arr.add(Double.valueOf(sb.toString()));
                chs.add(ch);
                sb.setLength(0);
                continue;
            }
            else
            {
                sb.append(ch);
            }
        }
    }

    public static void main(String[] args) {
        new Counter().Init();
    }
}

 四.注意事项

由于编译器译码方式的不同,再不加修改的情况下运行上述代码,最后的界面中按钮部分内容无法正常显示,若想正常显示内容,可按照下图修改:(采用IDEA演示)

 

在完成上述修改后,再运行程序,即可正常显示。

 可能存在思虑不周的情况,若有更好的实现方式,欢迎斧正!

共同进步!

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐