package java计算器;
import java.awt.*; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;
import javax.swing.*; @SuppressWarnings("serial")
public class Main extends JFrame implements ActionListener{
/**********************成员变量的申明与实例化***********************/
//按钮
JButton b[] = new JButton[19];
//面板
JPanel JP1=new JPanel();
JPanel JP2=new JPanel();
JPanel JP3=new JPanel();
JPanel JP4=new JPanel();
JPanel JP5=new JPanel();
JPanel JP6=new JPanel();
JPanel JP7=new JPanel();
JPanel JP8=new JPanel();
//标签和文本框
JLabel JL1=new JLabel("输入框:");
JTextArea JA1=new JTextArea(1,12);
JLabel JL2=new JLabel("十进制:");
JTextField JT2=new JTextField(12); JLabel JL3=new JLabel("二进制:");
JTextField JT3=new JTextField(12);
//创建一个数组,向其中添加输入的表达式
//char[] arraychar=new char[30];
/**********************成员变量的申明与实例化***********************/
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**构造方法*/
public Main() {
initialize();//调用初始化方法
this.setTitle("Calculator");
this.setBounds(1100, 200, 320, 500);
this.setVisible(true);
this.setLayout(new GridLayout(8,1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体关闭模式
}//构造方法结束
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**初始化方法*/
public void initialize() { //定义与添加按钮
String button_name[]={"clear","←","%","/","7","8","9","*","4","5","6","-","1","2","3","+","0",".","="};
for(int i=0;i<button_name.length;i++) {
b[i] = new JButton(button_name[i]);
b[i].setForeground(Color.BLUE);//数字键 设置前景色为 蓝颜色
b[i].setFont(new Font("宋体",Font.PLAIN,30));//设置字体格式
b[i].addActionListener(this);
if(i>=0&&i<=3)
JP4.add(b[i]);
else if(i>=4&&i<=7)
JP5.add(b[i]);
else if(i>=8&&i<=11)
JP6.add(b[i]);
else if(i>=12&&i<=15)
JP7.add(b[i]);
else if(i>=16&&i<=18)
JP8.add(b[i]);
}
//添加面板
JP1.add(JL1);JP1.add(JA1);//添加输入框标签
JP2.add(JL2);JP2.add(JT2);//添加十进制框和标签
JP3.add(JL3);JP3.add(JT3);//添加二进制框和标签
//设置文本区字体
JA1.setFont(new Font("宋体",Font.ITALIC,30));
JT2.setFont(new Font("宋体",Font.ITALIC,30));
JT3.setFont(new Font("宋体",Font.ITALIC,30));
this.add(JP1);this.add(JP2);this.add(JP3);this.add(JP4);
this.add(JP5);this.add(JP6);this.add(JP7);this.add(JP8);
b[1].setEnabled(false);//刚开始设置单选删除键不可操作 }//初始化方法结束
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
public static void main(String[] args) {
new Main();
//operandStack.pop()
}//主方法结束
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**事件监听方法*/
public void actionPerformed(ActionEvent e) {
if(e.getSource()==b[0]) {
JA1.setText("");//清空文本区
JT2.setText("");//清空文本框
JT3.setText("");//清空文本框
JA1.setEnabled(true);
isJA1empty();
}
else if(e.getSource()==b[1]) {
int length=JA1.getText().length();
JA1.setText(JA1.getText().substring(0,length-1));
length--;
isJA1empty();
}
else if(e.getSource()==b[2]) {
JA1.append(b[2].getText());
isJA1empty();
}
else if(e.getSource()==b[3]) {
JA1.append(b[3].getText()); isJA1empty(); }
else if(e.getSource()==b[4]) {
JA1.append(b[4].getText());
isJA1empty();
}
else if(e.getSource()==b[5]) {
JA1.append(b[5].getText());
isJA1empty();
}
else if(e.getSource()==b[6]) {
JA1.append(b[6].getText());
isJA1empty();
}
else if(e.getSource()==b[7]) {
JA1.append(b[7].getText());
isJA1empty();
}
else if(e.getSource()==b[8]) {
JA1.append(b[8].getText());
isJA1empty();
}
else if(e.getSource()==b[9]) {
JA1.append(b[9].getText());
isJA1empty();
}
else if(e.getSource()==b[10]) {
JA1.append(b[10].getText());
isJA1empty();
}
else if(e.getSource()==b[11]) {
JA1.append(b[11].getText());
isJA1empty();
}
else if(e.getSource()==b[12]) {
JA1.append(b[12].getText());
isJA1empty();
}
else if(e.getSource()==b[13]) {
JA1.append(b[13].getText());
isJA1empty();
}
else if(e.getSource()==b[14]) {
JA1.append(b[14].getText());
isJA1empty();
}
else if(e.getSource()==b[15]) {
JA1.append(b[15].getText());
isJA1empty();
}
else if(e.getSource()==b[16]) {
JA1.append(b[16].getText());
isJA1empty();
}
else if(e.getSource()==b[17]) {
JA1.append(b[17].getText());
isJA1empty();
}
else if(e.getSource()==b[18]) {
//JA1.append(b[18].getText());
//arraychar=JA1.getText().toCharArray();
isJA1empty();
isCharacter();
//count();
} }//事件监听方法结束 ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**@这个方法的作用就是使用空格分割字符串,以便后面使用分割函数使得将字符串分割成数组*/
public String resetExpression(String s) {
String result = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(' || s.charAt(i) == ')' ||
s.charAt(i) == '+' || s.charAt(i) == '-'
|| s.charAt(i) == '*' || s.charAt(i) == '/'|| s.charAt(i) == '%')
result += " " + s.charAt(i) + " ";
else
result += s.charAt(i);
}
//System.out.println(result);
return result;
}//重置表达式方法结束
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**@进行运算符和数据符的判断入栈操作*/
public int evaluateExpression(String expression) {
Stack<Integer> operandStack = new Stack<>();//创建一个数据栈
Stack<Character> operatorStack = new Stack<>();//创建一个运算符栈
expression = resetExpression(expression);//处理表达式,运算符前后加空格
String[] tokens = expression.split(" ");//根据匹配给定的正则表达式来拆分此字符串。 返回值是字符串数组
//该方法的作用就像是使用给定的表达式和限制参数 0 来调用两参数 split 重载方法。因此,所得数组中不包括结尾空字符串。
for (String token : tokens) {//单个运算符字符就是一个字符串
if (token.length() == 0) //如果是空格的话就继续循环,什么也不操作
continue;
//如果是加减的话,因为加减的优先级最低,因此这里的只要遇到加减号,无论操作符栈中的是什么运算符都要运算
else if (token.charAt(0) == '+' || token.charAt(0) == '-') {
//当栈不是空的,并且栈中最上面的一个元素是加减乘除的任意一个
while (!operatorStack.isEmpty()&&(operatorStack.peek() == '-' || operatorStack.peek() == '+'
|| operatorStack.peek() == '/' || operatorStack.peek() == '*'|| operatorStack.peek() == '%')) {
processAnOperator(operandStack, operatorStack); //开始运算
}
operatorStack.push(token.charAt(0)); //运算完之后将当前的运算符入栈
}//else if语句结束
//当前运算符是乘除的时候,因为优先级高于加减,因此要判断最上面的是否是乘除,如果是乘除就运算,否则的话直接入栈
else if (token.charAt(0) == '*' || token.charAt(0) == '/' || token.charAt(0) == '%') {
while (!operatorStack.isEmpty()&&(operatorStack.peek() == '/' || operatorStack.peek() == '*'|| operatorStack.peek() == '%')) {
processAnOperator(operandStack, operatorStack);
}
operatorStack.push(token.charAt(0)); //将当前操作符入栈
}//else if语句结束
//如果是左括号的话直接入栈,什么也不用操作,trim()函数是用来去除空格的,由于上面的分割操作可能会令运算符带有空格
else if (token.trim().charAt(0) == '(') {
operatorStack.push('(');
}
//如果是右括号的话,清除栈中的运算符直至左括号
else if (token.trim().charAt(0) == ')') {
while (operatorStack.peek() != '(') {
processAnOperator(operandStack, operatorStack); //开始运算
}
operatorStack.pop(); //这里的是运算完之后清除左括号,让左括号出运算符栈
}
//这里如果是数字的话直接入数据的栈
else {
operandStack.push(Integer.parseInt(token)); //将数字字符串转换成数字然后压入栈中
}
}//for循环结束
//最后当运算符栈中不是空的时候继续运算,直到栈中为空即可
while (!operatorStack.isEmpty()) {
processAnOperator(operandStack, operatorStack);
}
return operandStack.pop(); //此时数据栈中的数据就是运算的结果
}//运算符合数据符入栈方法结束 ////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**
* @这个方法的作用是计算弹出的两个数据
* */
public void processAnOperator(Stack<Integer> operandStack, Stack<Character> operatorStack) {
char op = operatorStack.pop(); //弹出一个操作符
int op1 = operandStack.pop(); //从存储数据的栈中弹出连个两个数用来和操作符op运算
int op2 = operandStack.pop();
if (op == '+') //如果操作符为+就执行加运算
operandStack.push(op2 + op1);
else if (op == '-')
operandStack.push(op2 - op1); //因为这个是栈的结构,自然是上面的数字是后面的,因此用op2-op1
else if (op == '*')
operandStack.push(op2 * op1);
else if (op == '/')
operandStack.push(op2 / op1);
else if (op == '%')
operandStack.push(op2 % op1);
}
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
/**@判断文本区JA1是否为空的方法*/
public void isJA1empty() {
if("".equals(JA1.getText()))
b[1].setEnabled(false);
else
b[1].setEnabled(true);
}//判断文本区是否为空的方法结束
/**@判断文本区输入的第一个字符是否为数字的方法
* @1.如果不是则设置文本区为无效输入
* @2.如果是则继续
* */
public void isCharacter() {
if(JA1.getText().charAt(0)=='+'||JA1.getText().charAt(0)=='-'
||JA1.getText().charAt(0)=='*'||JA1.getText().charAt(0)=='/'
||JA1.getText().charAt(0)=='%') {
JA1.setText("无效输入");
JA1.setEnabled(false); }
else {
JT2.setText(Integer.toString(evaluateExpression(JA1.getText())));
JT3.setText(Integer.toBinaryString(evaluateExpression(JA1.getText())));
}
}
}

Java实现图形化计算器的更多相关文章

  1. java Swing图形化界面

    学过java的人应该对java的图形化界面很是反感,特别是接触java不久的人.如果想和其他语言那样用鼠标拖拽,可以使用wondosbulider插件.但是用起来也不是那么方便.当然对于不乐意写代码的 ...

  2. JAVA之旅(三十一)——JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件

    JAVA之旅(三十一)--JAVA的图形化界面,GUI布局,Frame,GUI事件监听机制,Action事件,鼠标事件 有段时间没有更新JAVA了,我们今天来说一下JAVA中的图形化界面,也就是GUI ...

  3. java的图形化界面 文本区JTextArea的程序例子

    package java1;     //使用时这个改成你的包名即可//文本区 JTextArea import javax.swing.*;import java.awt.*;import java ...

  4. Java四则运算——图形化界面

    一.前提 (1)作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2213 (2)GitHub地址:https://github ...

  5. java图形化编程

    转载 学习Java Swing图形化编程,我们首先要了解三个最基本的概念:顶层容器,控件,布局. 下面就来介绍一下这三个基本概念 1.顶层容器 什么是顶层容器?当我们使用Java进行图形编程的时候,图 ...

  6. [未完成]关于GUI Java图形化界

    "笔记内容完成,整体未完成" GUI 图形化用户界面 用java做图形化用户界面的程序不多,大多用C++和defy.因为,Java做图形化效率低. 首先你要安装一个虚拟机,C++是 ...

  7. Java 图形化界面设计(GUI)实战练习(代码)

    关于Java图形化界面设计,基础知识网上可搜,下面简单介绍一下重点概念,然后就由浅入深代码实例. 程序是为了方便用户使用的,Java引入图形化界面编程. 1.JFrame 是容器类 2.AWT 是抽象 ...

  8. 01.Java 开发简单的计算器

    难度为一般,适合具有 Java 基础和 Swing 组件编程知识的用户学习一. 实验介绍1.1 实验内容本次实验利用Java开发一个可以进行简单的四则运算的图形化计算器,会使用到 Java Swing ...

  9. 转:二十七、Java图形化界面设计——容器(JFrame)

    转:http://blog.csdn.net/liujun13579/article/details/7756729 二十七.Java图形化界面设计——容器(JFrame) 程序是为了方便用户使用的, ...

随机推荐

  1. [hdu4599]期望DP

    思路:容易知道G(x)=6x,H(x)=6F(x).此题的关键是求出F(x)的通项,要求F(x)的通项,先建立递推式:F(x)=1/6 * (F(x-1)+1) + 5/6 * (F(x-1)+1+F ...

  2. angular js 分页

    一.编写实体类PageResult public class PageResult implements Serializable { private Long total;//总记录数 privat ...

  3. 对background: url("~assets/img/common/collect.svg") 0 0/14px 14px 的理解

    需求:给收藏数字前面通过::before伪元素添加图标 相关代码: .goods-info .collect { position: relative; } .goods-info .collect: ...

  4. Postman学习宝典(一)

    前言:网上看到的比较好的Postman教程,既然已经有了,我就不重复造轮子了,直接copy过来. 资源来源于:米阳MeYoung Postman 入门1- 安装.变量.代理 简介 Postman 是一 ...

  5. ql的python学习之路-day5

    文件操作 文件操作流程: 1.打开文件得到文件句柄并赋值变量 2.通过句柄对文件进行操作 3.关闭文件 打开的只是储存在计算机里的文件对象,必须赋值一个变量才能操作,变量通常用f表示,赋值f的文件对象 ...

  6. 【Django】rest_framework 序列化自定义替换返回值

    # 序列化设置 class PagerSerialiser(serializers.ModelSerializer): name = serializers.CharField(source=&quo ...

  7. 解惑求助-关于NetCore2.2中间件响应的问题

    背景介绍:基于netcore2.2开发api接口程序,自定义了一个异常捕获中间件,用于捕获未经处理的异常以及状态码404.500等访问(设计的出发点就是,出现了非200的响应,我这边全部会进行处理成2 ...

  8. redis集群复制和故障转移

    #### 一.集群的问题- 1.当某个主节点宕机后,对应的槽位没有节点承担,整个集群处于失败状态,不可用,怎么办- 2.如何判断某个主节点是否真正的岩机?- 3.如果从某个主节点的所有从节点中选举出一 ...

  9. poj3177 无向连通图加多少条边变成边双连通图

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15752   Accepted: 6609 ...

  10. Java并发(3)

    线程安全: 允许被多个线程同时执行的代码称作线程安全的代码.线程安全的代码不包含竞态条件.当多个线程同时更新共享资源时会引发竞态条件.因此,了解Java线程执行时共享了什么资源很重要. 局部变量: 局 ...