页面设置
package jisuanqi;
//AWT包提供:
// 图形界面组件:如:窗口、按钮、菜单等
// 容器 :是GUI元素的容器,实现组件管理、布局管理
// 布局管理器:用来安排图形界面组件的位置
// Graphics:在组件上进行图形绘制所使用的图形环境的父类
// 事件处理对象:用来处理图形界面组件所触发的事件
import java.awt.*;
import java.awt.event.*; // java.awt.event.*提供处理由 AWT 组件所激发的各类事件的接口和类
import javax.swing.*; //swing是图形可视包,导入这个包后才能进行GUI图形化软件的开发
import javax.swing.border.Border; //border - 要为此组件呈现的边框
import javax.swing.event.*;
public class mainJFrame extends JFrame { //JFrame类的实例是一个底层容器,即通常所称的窗口,可以向窗口添加组件
void run() { //执行程序
System.out.println("这是计算器模型");
}
boolean flag = false;
Button btn[] = new Button[] {
//new Button(string text):创建一个带文本的按钮
new Button("x²"), new Button("√"), new Button("mod"), new Button("log"), new Button("("), new Button(")"),
new Button("cls"), new Button("Dele"), new Button("7"), new Button("8"), new Button("9"), new Button("+"),
new Button("4"), new Button("5"), new Button("6"), new Button("-"), new Button("1"), new Button("2"),
new Button("3"), new Button("*"), new Button("0"), new Button("."), new Button("="), new Button("/"),
};
//JPanel:面板组件,非顶层容器
private JPanel content1 = new JPanel();
private JPanel content = new JPanel();
private JPanel jbt = new JPanel(); //按钮设置
private JPanel jpb = new JPanel(); //最下面按钮那个框框
private JPanel jpa = new JPanel(); //最右边的框框
private JTextField jtf = new JTextField(); //上面主框框
private JTextArea jta = new JTextArea("欢迎使用王思臣专用计算机"); //最右边的框框
public mainJFrame() {
content.setLayout(new BorderLayout()); //设置布局为边框布局
content1.setLayout(new BorderLayout());
jta.setEditable(false);//设置对该象或组件不可编辑
jta.setBackground(Color.white); //右边框框的设置 颜色
jta.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 100)); //字体
jpa.setLayout(new BorderLayout()); //边框
Border border = BorderFactory.createLineBorder(Color.BLUE); //右边框框内框的颜色
//字与内框间距
jta.setBorder(BorderFactory.createCompoundBorder(border, BorderFactory.createEmptyBorder(10, 10, 10, 10)));
jta.setLineWrap(true); 激活自动换行功能
JScrollPane huayang = new JScrollPane( //JScrollPane是一个滚动面板
jta,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, 确定垂直滚动条何时显示在滚动窗格 并且是总是出现
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER //确定水平滚动条何时显示在滚动窗格 并且是从不出现
);
add(huayang);
content1.add(jpa); //把弄好的jpa加入到主框架里
this.add(content1, BorderLayout.EAST); //BorderLayout 将容器分为 EAST 、 SOUTH 、 WEST 、 NORTH 、 CENTER五个区域,普通组件可以被放置在这 5 个区域的任意一个中 。 BorderLayout布局 管理器的布局示意图如图所示
JMenuBar menu = new JMenuBar(); //创建菜单
//初始化菜单
setJMenuBar(menu); //上面的那个大框框
jtf.setPreferredSize(new Dimension(700, 200)); //设置上面那个大框框的长和宽
jtf.setEditable(false); //设置对该象或组件不可编辑
jtf.setBackground(Color.white); //背景颜色
jtf.setFont(new Font("宋体", Font.LAYOUT_LEFT_TO_RIGHT, 150)); //输入字体设置
jtf.setHorizontalAlignment(JTextField.RIGHT); //在主框输入的字右对齐
jpb.setLayout(new BorderLayout()); //设置框架
jpb.add(jtf);
content.add(jpb, BorderLayout.NORTH); //南边(即下面)
jbt.setLayout(new GridLayout(6, 4)); //6行4列
for (int i = 0; i < btn.length; i++) { // btn.length按钮的数量
jbt.add(btn[i]);
if (i != 22 && i != 7 && i != 6 && i != 0)
btn[i].addActionListener(new listen());
else
btn[i].addActionListener(new result());
}
content.add(jbt, BorderLayout.CENTER); //将当前类的对象实例加到content的中间位置
this.add(content, BorderLayout.WEST); //框架左边
setTitle("巨无霸计算器"); //整体的那个框框
setSize(1000, 800); //整体高和宽
setResizable(false); //禁止用户通过拖拽边框改变窗口的大小
//setLocationRelativeTo 是 Java Swing 中的一个方法,
// 用于设置窗口(如 JFrame、JDialog 或其他图形用户界面组件)相对于屏幕上的某个组件的位置。如果传递给该方法的参数是 null,则窗口会被置于屏幕中央。
setLocationRelativeTo(null);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //退出窗口设置
//setVisible(boolean)方法是用来显示/隐藏GUI组件的。
//需要显示则使用true,需要隐藏则使用false。
setVisible(true);
}
class listen implements ActionListener { //这个方法就是你希望触发事件时程序要做什么
@Override
public void actionPerformed(ActionEvent e) {
Button temped = (Button) e.getSource(); //
//getText() 提取用户输入到EditText中的文本信息并暂时储存
//getLabel() 从LabelValue类的TupleClassObject中获取标签
jtf.setText(jtf.getText() + temped.getLabel());
}
}
class result implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btn[22]) //=
{
String check = jtf.getText();
String pp = String.valueOf(new Solution().calculate(check));
jtf.setText(pp);
flag = true;
}
else if (e.getSource() == btn[6]) //cls
{
jtf.setText("");
}
else if (e.getSource() == btn[7]) //Dele
{
String tempStr = jtf.getText();
jtf.setText(tempStr.substring(0, tempStr.length() - 1));
}
else if (e.getSource() == btn[0]) //x²
{
jtf.setText(String.valueOf(new Solution().calculate(jtf.getText() + "*" + jtf.getText())));
}
}
}
}
算法
package jisuanqi;
//Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算
import java.math.BigDecimal;
public class Solution {
@SuppressWarnings("null")
public double calculate(String s) {
int j = 0;
char str[] = s.toCharArray(); //将字符串中的字符转换成字符数组
char str1[] = new char[str.length]; //开辟一个数组长度为str.length
for (int i = 0; i < str.length;) { //去空
while (i < str.length && str[i] == ' ')
i++;
while (i < str.length && str[i] != ' ')
str1[j++] = str[i++];
while (i < str.length && str[i] == ' ')
i++;
}
int st = 0;
String ans = String.valueOf(str1) + ' '; //将字符数组str1转换成字符串
return new BigDecimal(Calcular(ans, st)).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue(); //double类型最多保留4位小数 双精度数返回
}
int end = 0;
public double Calcular(String s, int i) { //
double num = 0.0;
double prev = 0.0;
double sum = 0.0;
int choose = 0;
int a=0;
String target1="";
String target2="";
String target="";
int flag=0; //记录是否target
char prevOp = '+';
double indexcount=1.0;
while (i < s.length())
{
target=s.substring(i,i+1); //取字串 将串中第i个字符取出来
if(i+2<s.length())
target2=s.substring(i,i+3); //将i和i+1和i+2取出来
//target.equals("")判断target是否为空
if((target.equals("√")||target2.equals("log")||target2.equals("mod"))&&flag==0)
{
if(target.equals("√"))
{
a=1;
i+=1;
System.out.println("i"+i);
}
else if(target2.equals("log"))
{
a=2;
i+=3;
}
else if(target2.equals("mod"))
{
a=3;
i+=2;
}
flag=1;
}
//Character.isDigit(s.charAt(i)判断该字符是不是数字
if (Character.isDigit(s.charAt(i))||s.charAt(i) == '.')
{
if (s.charAt(i) == '.') {
choose = 1;
i++;
indexcount=1;
}
if (choose == 0) {
num = num * 10 + (s.charAt(i++)- '0');
}
else
{
indexcount*=0.1;
num = num + (double)(s.charAt(i++)- '0')* indexcount;
}
}
else if (s.charAt(i) == '(')
{
num = Calcular(s, ++i);
i = end;
}
else
{
switch(a)
{
case 1:
num=Math.sqrt(num);
break;
case 2:
num=Math.log(num)/Math.log(10);
break;
case 0:
break;
}
switch (prevOp) { //+ - * / % 运算
case '+':
sum += prev;
prev = num;
break;
case '-':
sum += prev;
prev = -num;
break;
case '*':
prev *= num;
break;
case '/':
if(num==0)
{
prev=-99999999;
}
else
{
prev /= num;
break;
}
case 'd':
prev=prev%num;
break;
}
if (s.charAt(i) == ')')
{
i++;
break;
}
prevOp = s.charAt(i); // 操作符
num = 0; // 数字重置
choose = 0;
a=0;
target1="";
target2="";
target="";
flag=0;
i++;
}
}
end = i;
return (sum + prev); //返回最终结果
}
}
主函数(运行)
package jisuanqi;
public class Calculator {
public static void main(String args[]) {
new mainJFrame().run();
}
}