一.界面设计
二.功能设计
三.代码实现
四.注意事项
一.界面设计
在设计计算器界面时,首先需要建立一个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演示)
在完成上述修改后,再运行程序,即可正常显示。