文章目录
- 前言
- 一、主界面部分
- 二、监听器部分
- 三、结果计算部分
- 总结
前言
最近在复习着Java Swing的使用,在布局这块反复又看了很久,然后突然发现GirdLayout机器适合来做一个计算器的简单样子,所以花了一点时间做了一下,最后没想到是在处理结果的算法这一块花的时间最多,这个简单的计算器目前来说支持的是加减乘除和括号运算,当然之后可能会扩展三角函数等功能吧。。。。
下面我将从各个模块来展示对应的代码
一、主界面部分
这个部分就是一个展示计算器的界面,只是简单的套用了GirdLayout和几个button(所以最后写完发现好像Swing没有复习到多少hhh)
package com.UI;
import com.UI.Listener.buttonListener;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class calcUI extends JFrame{
JButton resultButton = new JButton("");
JPanel[] panel = new JPanel[5];
public calcUI()
{
setSize(500,400);
setLayout(new GridLayout(6,1));
add(resultButton);
for(int i = 0;i < 5;i++){
panel[i] = new JPanel();
add(panel[i]);
GridLayout gridLayout = new GridLayout(1,4,3,3);
panel[i].setLayout(gridLayout);
}
String [] buttonNames = new String []{"<-","(",")","C","7", "8","9","/","4","5","6","*","1","2","3","-","0",".","=","+"};
for (int i=0;i<buttonNames.length;i++) {
JButton jButton = new JButton(buttonNames[i]);
panel[i/4].add(jButton);
jButton.addActionListener(new buttonListener(resultButton));
}
resultButton.setSize(200, 50);
resultButton.setHorizontalAlignment(SwingConstants.RIGHT);
resultButton.setEnabled(false);
setTitle("calcUI");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
calcUI demo = new calcUI();
demo.setVisible(true);
}
}
二、监听器部分
这部分使用的是按钮监听器,通过获取每个按钮对应的文字类型改变上方显示结果按钮给出的文字。
package com.UI.Listener;
import com.UI.Utils.Calc;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class buttonListener implements ActionListener {
JButton ansButton;
String text;
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
text = ansButton.getText();
if ("=".equals(actionCommand)) {
text = Calc.CalcAns(text);
}
else if(actionCommand.equals("C"))
{
text = "";
}
else if(actionCommand.equals("<-"))
{
if (text.length() <= 1) text = "";
else text = text.substring(0,text.length()-1);
}
else
{
text += actionCommand;
}
ansButton.setText(text);
}
public buttonListener(JButton ansButton) {
this.ansButton = ansButton;
}
}
三、结果计算部分
这个部分的代码量甚至比前两部分加起来还多了,主要是要加上正确性判断,结果求解等等,虽然似乎jdk已经给出来了对应的函数,但是既然已经做了,这部分的代码还是自己写为好,求解的部分就是通过双栈,一个符号栈一个数字栈来进行处理,避免了各种if情况的判断。(虽然没必要,但是把它设置为了静态类)
package com.UI.Utils;
import java.math.BigDecimal;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.regex.Pattern;
public class Calc {
public static String StringToNum(String str) {
Pattern patternSc = Pattern.compile("[+-]*\\d+\\.?\\d*[Ee]*[+-]*\\d+");
Pattern patternNum = Pattern.compile("-?[0-9]+\\.?[0-9]*");
if (patternSc.matcher(str).matches()) {
BigDecimal bd = new BigDecimal(str);
return bd.toPlainString();
} else if (patternNum.matcher(str).matches())
return str;
else
return "";
}
public static Queue<String> ReadInNums(String s) {
Queue<String> count = new LinkedList<String>();
double sum = -1;
double Point = -1;
int flag = 1;
for (int index = 0; index < s.length(); index++) {
if (s.charAt(index) >= '0' && s.charAt(index) <= '9' || s.charAt(index) == '.') {
if (index > 0 && s.charAt(index - 1) == '-')
flag = -1;
if (s.charAt(index) == '.') {
if (Point != -1 || sum == -1)
return null;
else
Point = 0;
} else {
if (Point != -1)
Point++;
if (sum == -1)
sum = s.charAt(index) - '0';
else
sum = sum * 10 + s.charAt(index) - '0';
}
} else {
if (Point != -1)
sum = sum / Math.pow(10, Point);
if (sum != -1)
count.offer(String.valueOf(flag * sum));
if (s.charAt(index) == '-') {
if (index < s.length() - 1 && s.charAt(index + 1) >= '0' && s.charAt(index + 1) <= '9'
&& index != 0 && s.charAt(index - 1) != '(')
count.offer(String.valueOf('+'));
else
count.offer(String.valueOf('-'));
} else
count.offer(String.valueOf(s.charAt(index)));
sum = -1;
Point = -1;
flag = 1;
}
if (index == s.length() - 1 && sum != -1) {
if (Point != -1) sum = sum / Math.pow(10, Point);
count.offer(String.valueOf(flag*sum));
}
}
return count;
}
public static boolean StRight(String[] countString) {
int countKuo = 0;
int countChar = 0;
for (int index = 0; index < countString.length; index++) {
String str = countString[index];
System.out.println(str);
if (str.equals("(")) {
countKuo++;
} else if (str.equals(")")) {
countKuo--;
} else if (StringToNum(str).length() != 0) {
countChar--;
} else
countChar++;
if (countKuo < 0) return false;
}
if (countKuo != 0 || countChar != -1) return false;
return true;
}
public static String CalcAns(String s) {
Queue<String> count = ReadInNums(s);
if (count == null || count.size() == 0) return "error!";
String[] countString = new String[count.size()];
int index = 0;
while (count.peek() != null) {
countString[index++] = count.poll();
System.out.println(countString[index - 1]);
}
boolean stRight = StRight(countString);
if (stRight)
return CalcNums(countString);
return "error!";
}
private static String CalcNums(String[] countString) {
Stack<String> operator = new Stack<String>();
Stack<Double> operatorNum = new Stack<Double>();
for (String sIndex : countString) {
String s = StringToNum(sIndex);
if (s != null && s.length() != 0)
operatorNum.push(Double.parseDouble(s));
else
switch (sIndex.charAt(0)) {
case '+':
case '-':
case '*':
case '/':
while (operator.size() != 0 && (operator.peek() != null && operator.peek().equals('*')
|| operator.peek().equals("/"))) {
if (operatorNum.size() < 2)
return "error";
else {
String opera = operator.pop();
double num2 = operatorNum.pop();
double num1 = operatorNum.pop();
if (opera.equals("/")) {
if (num2 == 0) return "error!";
else operatorNum.push(num1 / num2);
} else {
operatorNum.push(num1 * num2);
}
}
}
operator.push(sIndex);
break;
case '(':
operator.push(sIndex);
break;
case ')':
while (!operator.peek().equals("(")) {
if (unableToOperate(operator, operatorNum)) return "error";
}
operator.pop();
break;
}
}
while(operator.size() != 0)
{
if (unableToOperate(operator, operatorNum)) return "error";
}
if(operatorNum.size() != 1)
return "error";
else {
double nums = operatorNum.pop();
if(nums == (int)nums) return String.valueOf((int)nums);
return String.valueOf(nums);
}
}
private static boolean unableToOperate(Stack<String> operator, Stack<Double> operatorNum) {
if (operatorNum.size() < 2)
return true;
else {
String opera = operator.pop();
double num2 = operatorNum.pop();
double num1 = operatorNum.pop();
if (opera.equals("/")) {
if (num2 == 0) return true;
else
operatorNum.push(num1 / num2);
} else if (opera.equals("*"))
operatorNum.push(num1 * num2);
else if (opera.equals("+"))
operatorNum.push(num1 + num2);
else
operatorNum.push(num1 - num2);
}
return false;
}
}
总结
算是一个小练手?最近一直在学SSM导致没啥时间写代码了,不过想想其实SSM框架最终目的也只是为了更好地写代码,而不是喧宾夺主,没有它就不行,例如我这个代码好像根本没有用这个框架啥的,可能自己之前有点太过于看重这种形式了吧(当然也得学!)学完SSM后就回头去学JVM吧,把最基础的一些东西搞懂!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)