模仿 Windows 自带的计算器,实现标准型计算器功能。界面参考如下图:
要求使用 Java Swing 包中 JFrame、JButton、JLabel、JTextField、JMenu、
JMenuItem 等组件和相关的布局管理器完成图形界面绘制,并能够独立思考并完
成计算器的逻辑代码。
你好,看这个符合不:
package 计算器;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* 一个计算器,与Windows附件自带计算器的标准版功能、界面相仿。 但还不支持键盘操作。
*/
public class Calculator extends JFrame implements ActionListener {
/** 计算器上的键的显示名字 */
private final String[] KEYS = { "7", "8", "9", "/", "sqrt", "4", "5", "6",
"*", "%", "1", "2", "3", "-", "1/x", "0", "+/-", ".", "+", "=" };
/** 计算器上的功能键的显示名字 */
private final String[] COMMAND = { "Backspace", "CE", "C" };
/** 计算器左边的M的显示名字 */
private final String[] M = { " ", "MC", "MR", "MS", "M+" };
/** 计算器上键的按钮 */
private JButton keys[] = new JButton[KEYS.length];
/** 计算器上的功能键的按钮 */
private JButton commands[] = new JButton[COMMAND.length];
/** 计算器左边的M的按钮 */
private JButton m[] = new JButton[M.length];
/** 计算结果文本框 */
private JTextField resultText = new JTextField("0");
// 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字
private boolean firstDigit = true;
// 计算的中间结果。
private double resultNum = 0.0;
// 当前运算的运算符
private String operator = "=";
// 操作是否合法
private boolean operateValidFlag = true;
/**
* 构造函数
*/
public Calculator() {
super();
// 初始化计算器
init();
// 设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("计算器");
// 在屏幕(500, 300)坐标处显示计算器
this.setLocation(500, 300);
// 不许修改计算器的大小
this.setResizable(false);
// 使计算器中各组件大小合适
this.pack();
}
/**
* 初始化计算器
*/
private void init() {
// 文本框中的内容采用右对齐方式
resultText.setHorizontalAlignment(JTextField.RIGHT);
// 不允许修改结果文本框
resultText.setEditable(false);
// 设置文本框背景颜色为白色
resultText.setBackground(Color.WHITE);
// 初始化计算器上键的按钮,将键放在一个画板内
JPanel calckeysPanel = new JPanel();
// 用网格布局器,4行,5列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
calckeysPanel.setLayout(new GridLayout(4, 5, 3, 3));
for (int i = 0; i < KEYS.length; i++) {
keys[i] = new JButton(KEYS[i]);
calckeysPanel.add(keys[i]);
keys[i].setForeground(Color.blue);
}
// 运算符键用红色标示,其他键用蓝色表示
keys[3].setForeground(Color.red);
keys[8].setForeground(Color.red);
keys[13].setForeground(Color.red);
keys[18].setForeground(Color.red);
keys[19].setForeground(Color.red);
// 初始化功能键,都用红色标示。将功能键放在一个画板内
JPanel commandsPanel = new JPanel();
// 用网格布局器,1行,3列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
commandsPanel.setLayout(new GridLayout(1, 3, 3, 3));
for (int i = 0; i < COMMAND.length; i++) {
commands[i] = new JButton(COMMAND[i]);
commandsPanel.add(commands[i]);
commands[i].setForeground(Color.red);
}
// 初始化M键,用红色标示,将M键放在一个画板内
JPanel calmsPanel = new JPanel();
// 用网格布局管理器,5行,1列的网格,网格之间的水平方向间隔为3个象素,垂直方向间隔为3个象素
calmsPanel.setLayout(new GridLayout(5, 1, 3, 3));
for (int i = 0; i < M.length; i++) {
m[i] = new JButton(M[i]);
calmsPanel.add(m[i]);
m[i].setForeground(Color.red);
}
// 下面进行计算器的整体布局,将calckeys和command画板放在计算器的中部,
// 将文本框放在北部,将calms画板放在计算器的西部。
// 新建一个大的画板,将上面建立的command和calckeys画板放在该画板内
JPanel panel1 = new JPanel();
// 画板采用边界布局管理器,画板里组件之间的水平和垂直方向上间隔都为3象素
panel1.setLayout(new BorderLayout(3, 3));
panel1.add("North", commandsPanel);
panel1.add("Center", calckeysPanel);
// 建立一个画板放文本框
JPanel top = new JPanel();
top.setLayout(new BorderLayout());
top.add("Center", resultText);
// 整体布局
getContentPane().setLayout(new BorderLayout(3, 5));
getContentPane().add("North", top);
getContentPane().add("Center", panel1);
getContentPane().add("West", calmsPanel);
// 为各按钮添加事件侦听器
// 都使用同一个事件侦听器,即本对象。本类的声明中有implements ActionListener
for (int i = 0; i < KEYS.length; i++) {
keys[i].addActionListener(this);
}
for (int i = 0; i < COMMAND.length; i++) {
commands[i].addActionListener(this);
}
for (int i = 0; i < M.length; i++) {
m[i].addActionListener(this);
}
}
/**
* 处理事件
*/
public void actionPerformed(ActionEvent e) {
// 获取事件源的标签
String label = e.getActionCommand();
if (label.equals(COMMAND[0])) {
// 用户按了"Backspace"键
handleBackspace();
} else if (label.equals(COMMAND[1])) {
// 用户按了"CE"键
resultText.setText("0");
} else if (label.equals(COMMAND[2])) {
// 用户按了"C"键
handleC();
} else if ("0123456789.".indexOf(label) >= 0) {
// 用户按了数字键或者小数点键
handleNumber(label);
// handlezero(zero);
} else {
// 用户按了运算符键
handleOperator(label);
}
}
/**
* 处理Backspace键被按下的事件
*/
private void handleBackspace() {
String text = resultText.getText();
int i = text.length();
if (i > 0) {
// 退格,将文本最后一个字符去掉
text = text.substring(0, i - 1);
if (text.length() == 0) {
// 如果文本没有了内容,则初始化计算器的各种值
resultText.setText("0");
firstDigit = true;
operator = "=";
} else {
// 显示新的文本
resultText.setText(text);
}
}
}
/**
* 处理数字键被按下的事件
*
* @param key
*/
private void handleNumber(String key) {
if (firstDigit) {
// 输入的第一个数字
resultText.setText(key);
} else if ((key.equals(".")) && (resultText.getText().indexOf(".") < 0)) {
// 输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
resultText.setText(resultText.getText() + ".");
} else if (!key.equals(".")) {
// 如果输入的不是小数点,则将数字附在结果文本框的后面
resultText.setText(resultText.getText() + key);
}
// 以后输入的肯定不是第一个数字了
firstDigit = false;
}
/**
* 处理C键被按下的事件
*/
private void handleC() {
// 初始化计算器的各种值
resultText.setText("0");
firstDigit = true;
operator = "=";
}
/**
* 处理运算符键被按下的事件
*
* @param key
*/
private void handleOperator(String key) {
if (operator.equals("/")) {
// 除法运算
// 如果当前结果文本框中的值等于0
if (getNumberFromText() == 0.0) {
// 操作不合法
operateValidFlag = false;
resultText.setText("除数不能为零");
} else {
resultNum /= getNumberFromText();
}
} else if (operator.equals("1/x")) {
// 倒数运算
if (resultNum == 0.0) {
// 操作不合法
operateValidFlag = false;
resultText.setText("零没有倒数");
} else {
resultNum = 1 / resultNum;
}
} else if (operator.equals("+")) {
// 加法运算
resultNum += getNumberFromText();
} else if (operator.equals("-")) {
// 减法运算
resultNum -= getNumberFromText();
} else if (operator.equals("*")) {
// 乘法运算
resultNum *= getNumberFromText();
} else if (operator.equals("sqrt")) {
// 平方根运算
resultNum = Math.sqrt(resultNum);
} else if (operator.equals("%")) {
// 百分号运算,除以100
resultNum = resultNum / 100;
} else if (operator.equals("+/-")) {
// 正数负数运算
resultNum = resultNum * (-1);
} else if (operator.equals("=")) {
// 赋值运算
resultNum = getNumberFromText();
}
if (operateValidFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultNum;
t2 = resultNum - t1;
if (t2 == 0) {
resultText.setText(String.valueOf(t1));
} else {
resultText.setText(String.valueOf(resultNum));
}
}
// 运算符等于用户按的按钮
operator = key;
firstDigit = true;
operateValidFlag = true;
}
/**
* 从结果文本框中获取数字
*
* @return
*/
private double getNumberFromText() {
double result = 0;
try {
result = Double.valueOf(resultText.getText()).doubleValue();
} catch (NumberFormatException e) {
}
return result;
}
public static void main(String args[]) {
Calculator calculator1 = new Calculator();
calculator1.setVisible(true);
calculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
package calculator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Calculator2 extends JFrame implements ActionListener {
// 准备好东西
// 显示计算机上4行5列区域的按键
private String[] Keys = { "7", "8", "9", "/", "sqrt", "4", "5", "6", "*", "%", "1", "2", "3", "-", "1/x", "0",
"+/-", ".", "+", "=" };
// 定义5行1列的存储M键的按钮
private String[] M = { "", "MC", "MR", "MS", "M+" };
// 定义1行3列的命令行按钮
private String[] Cmd = { "BackSpace", "CE", "C" };
// 定义4行5列键的按钮
private JButton[] keys = new JButton[Keys.length];
// 定义5行1列M键的按钮
private JButton[] m = new JButton[M.length];
// 定义1行3列的功能命令按钮
private JButton[] cmd = new JButton[Cmd.length];
// 计算结果的文本框
private JTextField resultText = new JTextField("0");
// 第一个数字和运算符后的第一个数字的标识
private boolean firstDigit = true;
// 当前运算的运算符
private String operator = "=";
// 操作合法的标识
private boolean operatorFlag = true;
// 运算的中间结果
private double resultMid = 0.0;
public Calculator2() {
super();
init();
// 设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("计算器");
// 在屏幕中间位置显示计算器
this.setLocationRelativeTo(null);
// 不许修改计算器的大小,即不可拉伸
this.setResizable(false);
// 设置可见性
this.setVisible(true);
//设置默认关闭
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 使计算器中各组件大小合适
this.pack();
this.setLocationRelativeTo(null);
}
/*
* 进行整个计算器的初始化工作 即整个界面的布置
*/
private void init() {
// 创建面板1来放置4行5列,并设置其布局管理器为网格布局,四行5列.且每一个格子的间距为3
JPanel KEYS = new JPanel();
KEYS.setLayout(new GridLayout(4, 5, 3, 3));
// 实行放置,即实例化,并设置前景色
for (int i = 0; i < Keys.length; i++) {
keys[i] = new JButton(Keys[i]);
// 设置按钮背景颜色
if (i == 3 || i == 8 || i == 13 || i == 18 || i == 19) {
keys[i].setForeground(Color.red);// 这些功能键为红色
} else {
keys[i].setForeground(Color.blue);// 其余的为红色
}
KEYS.add(keys[i]);
}
// 创建面板2用来放置M键,并设置前景色为红色
JPanel Mm = new JPanel();
Mm.setLayout(new GridLayout(5, 1, 3, 3));
for (int i = 0; i < M.length; i++) {
m[i] = new JButton(M[i]);
m[i].setForeground(Color.red);
Mm.add(m[i]);
}
// 创建面板3用来放置1行3列的命令行按钮按键
JPanel CMD = new JPanel();
CMD.setLayout(new GridLayout(1, 3, 3, 3));
for (int i = 0; i < Cmd.length; i++) {
cmd[i] = new JButton(Cmd[i]);
cmd[i].setForeground(Color.red);
CMD.add(cmd[i]);
}
// 创建面板4放置文本框,并设置布局管理器为边界布局
JPanel text = new JPanel();
text.setLayout(new BorderLayout());
// 先对文本框进行设置
// 1.设置文本框为不可编辑
resultText.setEditable(false);
// 2.设置背景色为白色
resultText.setBackground(Color.white);
// 3.设置文本框的内容向右对齐,参数为静态属性
resultText.setHorizontalAlignment(JTextField.RIGHT);
// 将文本框放置面板中
text.add(resultText, "Center");
//创建面板5将1行3列命令行功能键和4行5列按键放置一个大的面板中结为一起,采用边界布局,间距为3像素
JPanel big = new JPanel();
big.setLayout(new BorderLayout(3,3));
big.add(CMD,"North");
big.add(KEYS,"Center");
//进行整体布局
//虽然默认JFrame的布局管理器为边界布局,但是要设置其边距为3,故重新new一个
this.setLayout(new BorderLayout(3,3));
this.add(big,"Center");
this.add(Mm,"West");
this.add(text,"North");
//所有按钮添加事件监听器
for(int i=0;i<Keys.length;i++) {
keys[i].addActionListener(this);
}
for(int j=0;j<M.length;j++) {
m[j].addActionListener(this);
}
for(int i=0;i<Cmd.length;i++) {
cmd[i].addActionListener(this);
}
}
//进行事件处理,以按钮中的字符串内容为区分切入点
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String content = e.getActionCommand();
if(content.equals(Cmd[0])) {
//如果用户按下了退格键,执行BackSpace()函数操作
BackSpace();
firstDigit=true;
}else if(content.equals(Cmd[1])) {
//如果用户按下了CE键,还原文本框,其余不变
resultText.setText("0");
firstDigit=true;
}else if(content.equals(Cmd[2])) {
//如果用户按下了C键,即还原计算器初始状态
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
firstDigit = true;
}else if("0123456789.".indexOf(content)>=0){//从该content内容是否包含在"0123456789."中,从而判断用户按下的是数字或小数点
process(content);//按键数字处理的是文本框中的显示数据
}else {//运算符处理
//前面都不满足时执行这条语句,很巧妙
handOperator(content);//当按下的按钮内容是运算符时
}
}
//处理BackSpace键,这是计算器中的退格键,需要判断两个点,如果结果文本款中没有数字时则还原初始化计算器本身状态,如果有内容,则退去最后一个字符
public void BackSpace() {
String str = resultText.getText();//获取文本框的内容
//进行判断内容情况
if(str.length()>0) {
str = str.substring(0, str.length()-1);//将最后一个字符去掉
//去掉最后一个字符后如果新的文本框字符串中没有了字符则初始化计算器
if(str.length()==0) {
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
operatorFlag = true;
}else {
resultText.setText(str);
}
}
}
//process,进行数字和小数点的处理
public void process(String s) {
if(firstDigit) {//判断是否是键入键盘的第一个数,便于将文本的初始0去掉
resultText.setText(s);
}else if((s.equals("."))&&(resultText.getText().indexOf("."))<0) {//如果第一个键入的数字是小数点
resultText.setText(resultText.getText()+".");
}else if(!(s.equals("."))) {//如果键入的不是小数点
resultText.setText(resultText.getText()+s);
}
//此函数的代码执行到这里最后输入之后的数字便不再是第一个数字了。改变标志
firstDigit=false;
}
//处理用户按下的是运算符的操作
public void handOperator(String c) {
if(operator.equals("/")) {//除法操作的运算符时
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("分母不能为0");
}else {
resultMid /= getDoubleNum();//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("1/x")) {//如果按的是倒数运算符
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("0没有倒数");
}else {
resultMid = 1/resultMid;//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("+")) {//如果是加法操作
resultMid += getDoubleNum();
}else if(operator.equals("*")) {//乘法
resultMid *= getDoubleNum();
}else if(operator.equals("sqrt")) {
resultMid=Math.sqrt(getDoubleNum());
}else if(operator.equals("%")) {
//百分号操作
resultMid=resultMid/100;
}else if (operator.equals("+/-")) {
// 正数负数运算
resultMid = resultMid * (-1);
} else if (operator.equals("=")) {
// 赋值运算
resultMid = getDoubleNum();
}else if(operator.equals("-")) {
resultMid -= getDoubleNum();
}
//判断合法后将结果存储在结果文本框中
if (operatorFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultMid;//转化为long后,其后面的小数点会没有
t2 = resultMid - t1;//double-long
if (t2 == 0) {//说明此时resultMid是整数
resultText.setText(String.valueOf(t1));
} else {//double类型
resultText.setText(String.valueOf(resultMid));
}
}
//运算符等于用户按下的按钮
operator=c;
firstDigit = true;
operatorFlag = true;
}
//获取结果框中的数字字符串,并转化为double类型
public double getDoubleNum() {
try {
return Double.valueOf(resultText.getText()).doubleValue();
}catch(NumberFormatException e) {
return 0;
}
}
public static void main(String[] args) {
new Calculator2();
}
}
这个我可以,如果没人的话,我可以教你一下
package calculator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Calculator2 extends JFrame implements ActionListener {
// 准备好东西
// 显示计算机上4行5列区域的按键
private String[] Keys = { "7", "8", "9", "/", "sqrt", "4", "5", "6", "*", "%", "1", "2", "3", "-", "1/x", "0",
"+/-", ".", "+", "=" };
// 定义5行1列的存储M键的按钮
private String[] M = { "", "MC", "MR", "MS", "M+" };
// 定义1行3列的命令行按钮
private String[] Cmd = { "BackSpace", "CE", "C" };
// 定义4行5列键的按钮
private JButton[] keys = new JButton[Keys.length];
// 定义5行1列M键的按钮
private JButton[] m = new JButton[M.length];
// 定义1行3列的功能命令按钮
private JButton[] cmd = new JButton[Cmd.length];
// 计算结果的文本框
private JTextField resultText = new JTextField("0");
// 第一个数字和运算符后的第一个数字的标识
private boolean firstDigit = true;
// 当前运算的运算符
private String operator = "=";
// 操作合法的标识
private boolean operatorFlag = true;
// 运算的中间结果
private double resultMid = 0.0;
public Calculator2() {
super();
init();
// 设置计算器的背景颜色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("计算器");
// 在屏幕中间位置显示计算器
this.setLocationRelativeTo(null);
// 不许修改计算器的大小,即不可拉伸
this.setResizable(false);
// 设置可见性
this.setVisible(true);
//设置默认关闭
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 使计算器中各组件大小合适
this.pack();
this.setLocationRelativeTo(null);
}
/*
* 进行整个计算器的初始化工作 即整个界面的布置
*/
private void init() {
// 创建面板1来放置4行5列,并设置其布局管理器为网格布局,四行5列.且每一个格子的间距为3
JPanel KEYS = new JPanel();
KEYS.setLayout(new GridLayout(4, 5, 3, 3));
// 实行放置,即实例化,并设置前景色
for (int i = 0; i < Keys.length; i++) {
keys[i] = new JButton(Keys[i]);
// 设置按钮背景颜色
if (i == 3 || i == 8 || i == 13 || i == 18 || i == 19) {
keys[i].setForeground(Color.red);// 这些功能键为红色
} else {
keys[i].setForeground(Color.blue);// 其余的为红色
}
KEYS.add(keys[i]);
}
// 创建面板2用来放置M键,并设置前景色为红色
JPanel Mm = new JPanel();
Mm.setLayout(new GridLayout(5, 1, 3, 3));
for (int i = 0; i < M.length; i++) {
m[i] = new JButton(M[i]);
m[i].setForeground(Color.red);
Mm.add(m[i]);
}
// 创建面板3用来放置1行3列的命令行按钮按键
JPanel CMD = new JPanel();
CMD.setLayout(new GridLayout(1, 3, 3, 3));
for (int i = 0; i < Cmd.length; i++) {
cmd[i] = new JButton(Cmd[i]);
cmd[i].setForeground(Color.red);
CMD.add(cmd[i]);
}
// 创建面板4放置文本框,并设置布局管理器为边界布局
JPanel text = new JPanel();
text.setLayout(new BorderLayout());
// 先对文本框进行设置
// 1.设置文本框为不可编辑
resultText.setEditable(false);
// 2.设置背景色为白色
resultText.setBackground(Color.white);
// 3.设置文本框的内容向右对齐,参数为静态属性
resultText.setHorizontalAlignment(JTextField.RIGHT);
// 将文本框放置面板中
text.add(resultText, "Center");
//创建面板5将1行3列命令行功能键和4行5列按键放置一个大的面板中结为一起,采用边界布局,间距为3像素
JPanel big = new JPanel();
big.setLayout(new BorderLayout(3,3));
big.add(CMD,"North");
big.add(KEYS,"Center");
//进行整体布局
//虽然默认JFrame的布局管理器为边界布局,但是要设置其边距为3,故重新new一个
this.setLayout(new BorderLayout(3,3));
this.add(big,"Center");
this.add(Mm,"West");
this.add(text,"North");
//所有按钮添加事件监听器
for(int i=0;i<Keys.length;i++) {
keys[i].addActionListener(this);
}
for(int j=0;j<M.length;j++) {
m[j].addActionListener(this);
}
for(int i=0;i<Cmd.length;i++) {
cmd[i].addActionListener(this);
}
}
//进行事件处理,以按钮中的字符串内容为区分切入点
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String content = e.getActionCommand();
if(content.equals(Cmd[0])) {
//如果用户按下了退格键,执行BackSpace()函数操作
BackSpace();
firstDigit=true;
}else if(content.equals(Cmd[1])) {
//如果用户按下了CE键,还原文本框,其余不变
resultText.setText("0");
firstDigit=true;
}else if(content.equals(Cmd[2])) {
//如果用户按下了C键,即还原计算器初始状态
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
firstDigit = true;
}else if("0123456789.".indexOf(content)>=0){//从该content内容是否包含在"0123456789."中,从而判断用户按下的是数字或小数点
process(content);//按键数字处理的是文本框中的显示数据
}else {//运算符处理
//前面都不满足时执行这条语句,很巧妙
handOperator(content);//当按下的按钮内容是运算符时
}
}
//处理BackSpace键,这是计算器中的退格键,需要判断两个点,如果结果文本款中没有数字时则还原初始化计算器本身状态,如果有内容,则退去最后一个字符
public void BackSpace() {
String str = resultText.getText();//获取文本框的内容
//进行判断内容情况
if(str.length()>0) {
str = str.substring(0, str.length()-1);//将最后一个字符去掉
//去掉最后一个字符后如果新的文本框字符串中没有了字符则初始化计算器
if(str.length()==0) {
resultText.setText("0");
// 当前运算的运算符
operator = "=";
// 操作合法的标识
operatorFlag = true;
}else {
resultText.setText(str);
}
}
}
//process,进行数字和小数点的处理
public void process(String s) {
if(firstDigit) {//判断是否是键入键盘的第一个数,便于将文本的初始0去掉
resultText.setText(s);
}else if((s.equals("."))&&(resultText.getText().indexOf("."))<0) {//如果第一个键入的数字是小数点
resultText.setText(resultText.getText()+".");
}else if(!(s.equals("."))) {//如果键入的不是小数点
resultText.setText(resultText.getText()+s);
}
//此函数的代码执行到这里最后输入之后的数字便不再是第一个数字了。改变标志
firstDigit=false;
}
//处理用户按下的是运算符的操作
public void handOperator(String c) {
if(operator.equals("/")) {//除法操作的运算符时
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("分母不能为0");
}else {
resultMid /= getDoubleNum();//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("1/x")) {//如果按的是倒数运算符
if(getDoubleNum()==0.0) {//如果分母为0时
operatorFlag=false;//操作不合法
resultText.setText("0没有倒数");
}else {
resultMid = 1/resultMid;//使用的结果赋值给中间值,因为初始默认是‘=’操作时,就把中间值赋值为第一个数字了
}
}else if(operator.equals("+")) {//如果是加法操作
resultMid += getDoubleNum();
}else if(operator.equals("*")) {//乘法
resultMid *= getDoubleNum();
}else if(operator.equals("sqrt")) {
resultMid=Math.sqrt(getDoubleNum());
}else if(operator.equals("%")) {
//百分号操作
resultMid=resultMid/100;
}else if (operator.equals("+/-")) {
// 正数负数运算
resultMid = resultMid * (-1);
} else if (operator.equals("=")) {
// 赋值运算
resultMid = getDoubleNum();
}else if(operator.equals("-")) {
resultMid -= getDoubleNum();
}
//判断合法后将结果存储在结果文本框中
if (operatorFlag) {
// 双精度浮点数的运算
long t1;
double t2;
t1 = (long) resultMid;//转化为long后,其后面的小数点会没有
t2 = resultMid - t1;//double-long
if (t2 == 0) {//说明此时resultMid是整数
resultText.setText(String.valueOf(t1));
} else {//double类型
resultText.setText(String.valueOf(resultMid));
}
}
//运算符等于用户按下的按钮
operator=c;
firstDigit = true;
operatorFlag = true;
}
//获取结果框中的数字字符串,并转化为double类型
public double getDoubleNum() {
try {
return Double.valueOf(resultText.getText()).doubleValue();
}catch(NumberFormatException e) {
return 0;
}
}
public static void main(String[] args) {
new Calculator2();
}
}
【仅供参考,期望对你有所帮助】
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class CaculatorDemo {
public static void main(String[] args) {
JS win=new JS();
}
}
class JS extends JFrame implements ActionListener{
private StringBuilder sBuilder = new StringBuilder(); //利用StringBuilder类来显示,以及区分两个操作数
JTextArea text=new JTextArea();
double a,b;
Double sum;
int i;
public JS()
{
setBounds(100,100,400,400);
setTitle("计算器");
JMenuBar menubar=new JMenuBar();//创建菜单条
JMenu menu1=new JMenu("查看(V)");//创建和设置菜单名
JMenu menu2=new JMenu("编辑(E)");//创建和设置菜单名
JMenu menu3=new JMenu("帮助(H)");//创建和设置菜单名
menubar.add(menu1);//将菜单加入到菜单条中
menubar.add(menu2);
menubar.add(menu3);
this.setJMenuBar(menubar);//将设置好的菜单条放在窗口中
this.setLayout(new BorderLayout());//添加文本框
JPanel p1=new JPanel();
JPanel p2=new JPanel();
text.setPreferredSize(new Dimension (370,60));//设置组件大小
p2.setLayout(new FlowLayout());
p1.add(text);
this.add(p1,BorderLayout.NORTH);
p2.setLayout(new GridLayout(5,4)); //添加按钮
JButton button[]=new JButton[20];
button[0]=new JButton("C"); //清空
button[1]=new JButton("CE"); //清除之前输入的一个数据
button[2]=new JButton("%"); //取余
button[3]=new JButton("÷"); //除法
button[4]=new JButton("7");
button[5]=new JButton("8");
button[6]=new JButton("9");
button[7]=new JButton("x"); //乘号
button[8]=new JButton("4");
button[9]=new JButton("5");
button[10]=new JButton("6");
button[11]=new JButton("—"); //减号
button[12]=new JButton("1");
button[13]=new JButton("2");
button[14]=new JButton("3");
button[15]=new JButton("+"); //加号
button[16]=new JButton("e"); //乘方
button[17]=new JButton("0");
button[18]=new JButton("."); //小数点
button[19]=new JButton("="); //等于
for(int i=0;i<button.length;i++ ) //将组件加入容器
p2.add(button[i]);
button[19].setBackground(Color.ORANGE);//设置按钮的背景颜色为橙色
p2.add(button[19]);
add(p2,BorderLayout.CENTER);
for(int i=0;i<button.length;i++) //为每一个事件(按钮)添加监视器
button[i].addActionListener(this);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //点击X号可以关闭程序
}
public void actionPerformed(ActionEvent e) //事件处理
{
// TODO Auto-generated method stub
String lab=e.getActionCommand(); //得到当前的按钮字符,后面进行匹配
if(lab.equals("0")) //处理按钮 0~9
{
sBuilder.append("0"); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前所有输入的数据
}
else if(lab.equals("1"))
{
sBuilder.append("1"); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前所有输入的数据
}
else if(lab.equals("2"))
{
sBuilder.append("2"); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前所有输入的数据
}
else if(lab.equals("3"))
{
sBuilder.append("3"); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前所有输入的数据
}
else if(lab.equals("4"))
{
sBuilder.append("4");
text.setText(sBuilder.toString());
}
else if(lab.equals("5"))
{
sBuilder.append("5");
text.setText(sBuilder.toString());
}
else if(lab.equals("6"))
{
sBuilder.append("6");
text.setText(sBuilder.toString());
}
else if(lab.equals("7"))
{
sBuilder.append("7");
text.setText(sBuilder.toString());
}
else if(lab.equals("8"))
{
sBuilder.append("8");
text.setText(sBuilder.toString());
}
else if(lab.equals("9"))
{
sBuilder.append("9"); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前所有输入的数据
}
else if(lab.equals("CE")) //处理"CE"按钮事件 即清除当前的输入的数据
{
sBuilder.deleteCharAt(sBuilder.length() - 1); //StringBuilder的实例化对象调用方法下标减1即可
text.setText(sBuilder.toString());
}
else if(lab.equals("C")) //处理"CE"按钮事件 即清除之前的输入所有的数据
{
sBuilder = new StringBuilder(); //重新创建即可清除之前的输入所有的数据
text.setText(sBuilder.toString());
}
else if(lab.equals(".")) // 处理按钮 "." 事件
{
sBuilder.append("."); //利用StringBuilder类的对象调用方法,将数据存起来
text.setText(sBuilder.toString()); //显示之前输入的数据
}
else if(lab.equals("+")) //处理+"按钮乘法
{
a = Double.parseDouble(sBuilder.toString()); //将 运算符 之前的数据 作为第一个操作数 a
i=0;
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("+");
}
else if(lab.equals("—")) //处理"—"按钮乘法
{
a = Double.parseDouble(sBuilder.toString()); //将前面的输入的数 作为第一个操作数a
i=1; //标记运算类型 即"÷"之前的数据即将作为因数
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("—");
}
else if(lab.equals("x")) //处理"x"按钮乘法
{
a = Double.parseDouble(sBuilder.toString()); //将前面的输入的数 作为第一个操作数a
i=2; //标记运算类型 即"÷"之前的数据即将作为因数
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("x");
}
else if(lab.equals("÷")) //处理"÷"按钮事件
{
i=3; //标记运算类型 即"÷"之前的数据即将作为被除数
a = Double.parseDouble(sBuilder.toString()); //将除法的输入的数 作为第一个操作数a
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("÷");
}
else if(lab.equals("%")) //处理取余运算
{
a = Double.parseDouble(sBuilder.toString()); //将前面的输入的数 作为第一个操作数a
i=4; //标记取余运算
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("%");
}
else if(lab.equals("e")) //处理取余运算
{
a = Double.parseDouble(sBuilder.toString()); //将前面的输入的数 作为第一个操作数a
i=5; //标记取余运算
sBuilder = new StringBuilder(); //将数组清空来存储第二个操作数 b
text.setText("e");
}
else if(lab.equals("="))
{
b = Double.parseDouble(sBuilder.toString()); //一遇到"=",我们就能得到第二个操作数b
if (i == 0) //加法 a+b
{
sum=a+b;
text.setText(sum.toString()); //输出第二个操作数已经输入的数据
sBuilder = new StringBuilder(); //清空数据,为后面的操作数留空间
sBuilder.append(sum);
}
else if (i == 1) //加法 a-b
{
sum = a - b;
text.setText(sum.toString());
sBuilder = new StringBuilder(); //清空数据,为后面的操作数留空间
sBuilder.append(sum);
}
else if (i == 2) //乘法 a*b
{
sum = a * b;
text.setText(sum.toString());
sBuilder = new StringBuilder();
sBuilder.append(sum);
}
else if (i == 3) //除法 a÷b
{
sum = a / b;
text.setText(sum.toString());
sBuilder = new StringBuilder();
sBuilder.append(sum);
}
else if (i == 4) // 取余 a%b
{
sum=a % b;
int m=(int)a;
int n=(int)b;
sum=(double)m % n;
text.setText(sum.toString());
sBuilder = new StringBuilder();
sBuilder.append(sum);
}
else if (i == 5) // 次幂 a是底数 b是指数
{
sum=1.0;
if(b==0)
sum=1.0;
else
for(int i=1;i<=b;i++)
sum=sum*a;
text.setText(sum.toString());
sBuilder = new StringBuilder();
sBuilder.append(sum);
}
else
text.setText(sBuilder.toString());
}
}
}
这个需求有什么用处么,相同案例很多https://blog.csdn.net/AZLAWW/article/details/118638697,题主的需求是不是没有阐述明白
参考:https://blog.csdn.net/weixin_51625354/article/details/122211758
参考这个,写的很详细
https://blog.csdn.net/weixin_51625354/article/details/122211758
```java
package com.zkb;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.math.BigInteger;
//时间允许,可通过引入一下包,实现鼠标滑过按钮变色和键盘输入
//import java.awt.event.MouseAdapter;
//import java.awt.event.MouseEvent;
//import java.awt.event.KeyAdapter;
//import java.awt.event.KeyEvent;
import java.math.BigDecimal;//控制小数点后几位
public class Calculator implements ActionListener {
private JFrame frame = new JFrame();
//计算器上各按键的符号
private String[] keys = {" ", "CE", "C","%", "n!", "aⁿ", "cos", "sin", "1⁄x", "x²", "√x", "÷", "7", "8", "9",
"×", "4", "5", "6", "-", "1", "2", "3", "+", "+/-", "0", ".", "="};
private JButton button[] = new JButton[keys.length]; //计算器上按键的按钮(数组保存)
private JTextField resultText = new JTextField("0");//显示计算结果文本框
private JTextField processText = new JTextField();//显示计算过程文本框
private boolean firstDigit = true; // 标志用户按的是否是整个表达式的第一个数字,或者是运算符后的第一个数字
private double resultNum = 0.0000; // 计算的中间结果
private String operator = "="; // 当前运算的运算符(按键"C"时需要将其还原为"=")
private boolean operateValidFlag = true; // 判断操作是否合法
char charA;
public Calculator() {//本类Calculator的构造函数
init(); // 初始化计算器
frame.setTitle("计算器");
frame.setSize(350, 550);
frame.setLocation(500, 300);
frame.setResizable(true); // 允许修改计算器窗口的大小
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮后执行exit退出应用程序
}
private void init() {//初始化变量,创建面板,添加按钮,面板布局
Color color1 = new Color(181, 181, 181);
Color color2 = new Color(126, 192, 238); //等于号专属颜色
Color color3 = new Color(232, 232, 232); //背景颜色//功能键和运算符颜色
//Color color4 = new Color(132, 132, 232);//紫色
JPanel resultTextPanel = new JPanel();// 建立一个画板放文本框
resultTextPanel.setLayout(new BorderLayout());
resultTextPanel.setSize(400, 50);
resultTextPanel.add(resultText);
resultText.setFont(new Font("黑体", Font.BOLD, 55)); //设置文本框中文字的字体以及大小,加粗
resultText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式
resultText.setEditable(false); //不能修改结果文本框
resultText.setBorder(null); //删除文本框的边框
resultText.setBackground(color1);// 设置文本框背景颜色
JPanel processTextPanel = new JPanel();
processTextPanel.setLayout(new BorderLayout());
processTextPanel.setSize(400, 50);
processTextPanel.add(processText);
processText.setFont(new Font("黑体", Font.PLAIN, 25)); //设置文本框中文字的字体以及大小,加粗
processText.setHorizontalAlignment(JTextField.RIGHT); //文本框中的内容采用右对齐方式
processText.setEditable(false); //不能修改结果文本框
processText.setBorder(null); //删除文本框的边框
processText.setBackground(color1);
// 初始化计算器上键的按钮,将键放在一个画板内
JPanel keysPanel = new JPanel();
// 用网格布局器,6行,4列的网格,网格之间的水平方向垂直方向间隔均为2个像素
keysPanel.setLayout(new GridLayout(7, 4, 2, 2));
//初始化功能按钮
for (int i = 0; i < 12; i++) {
button[i] = new JButton(keys[i]);
Dimension preferredSize = new Dimension(95, 50);
button[i].setPreferredSize(preferredSize);
keysPanel.add(button[i]);
button[i].setBackground(color3);
button[i].setForeground(Color.black);//设置字体颜色
button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
if (i == 11 || i == 3) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30));
if (i == 1 || i == 2) button[i].setFont(new Font("黑体", Font.PLAIN, 18));
button[i].setBorderPainted(false); //去除按钮的边框
}
//初始化运算符及数字键按钮
for (int i = 12; i < keys.length; i++) {
button[i] = new JButton(keys[i]);
Dimension preferredSize = new Dimension(95, 50);
button[i].setPreferredSize(preferredSize);
keysPanel.add(button[i]);
if ((i + 1) % 4 == 0) {
button[i].setBackground(color3);//运算符按钮
button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 30));
} else {
button[i].setBackground(Color.white);//数字按钮
button[i].setFont(new Font("黑体", Font.BOLD, 20));
}
if (i == 19) button[i].setFont(new Font(Font.SERIF, Font.PLAIN, 18));
button[i].setForeground(Color.black);
button[i].setBorderPainted(false); //去除按钮的边框
}
button[27].setBackground(color2); // 用浅蓝色 覆盖更改 标记'='
keysPanel.setBackground(color1);
//将文本框所在的面板放在北部和中部,将keysPanel面板放在计算器的南部
frame.getContentPane().add("North", processTextPanel);
frame.getContentPane().add("Center", resultTextPanel);
frame.getContentPane().add("South", keysPanel);
processTextPanel.setBorder(BorderFactory.createMatteBorder(25, 3, 0, 3, color1));
resultTextPanel.setBorder(BorderFactory.createMatteBorder(0, 3, 5, 3, color1));
keysPanel.setBorder(BorderFactory.createMatteBorder(5, 3, 5, 3, color1));
for (int i = 0; i < keys.length; i++) {
button[i].addActionListener(this);// 为各按钮添加事件监听器,都使用同一个事件监听器。
}
}
public void actionPerformed(ActionEvent ev) {//监听函数,将得到的事件选择对应的函数
String command = ev.getActionCommand(); // 获取事件源
if (command.equals(keys[3])) doBackspace();// 用户按了"Back"键
else if (command.equals(keys[1])) resultText.setText("0");// 用户按了"CE"键
else if (command.equals(keys[2])) doC();// 用户按了"C"键
else if ("0123456789.".indexOf(command) >= 0) doNumber(command);// 用户按了数字键或者小数点键
else if (command.equals(keys[0]) || command.equals(keys[4]) || command.equals(keys[6])
|| command.equals(keys[7]) || command.equals(keys[8]) || command.equals(keys[9])
|| command.equals(keys[10]) || command.equals(keys[24])) doOperator1(command);
// 用户按了只需一个数的运算键(求倒数,%,开方,平方,取正负数)
else doOperator2(command);
}
private void doBackspace() {//删除键
String text = resultText.getText();
int i = text.length();
if (i > 0) {
text = text.substring(0, i - 1); // 退格,将文本最后一个字符去掉
if (text.length() == 0) {
resultText.setText("0");// 如果文本没有内容了,则初始化计算器的各种值
firstDigit = true;
operator = "=";
} else {
resultText.setText(text);// 显示新的文本
}
}
}
private void doC() {//清除键
// 初始化计算器的各种值
processText.setText(null);
resultText.setText("0");
firstDigit = true;
operator = "=";
}
private void doNumber(String key) {//得到数字,处理数字
if (firstDigit) {
// 输入的为第一个数
resultText.setText(null);
resultText.setText(key);
} else if ((key.equals(".")) && (resultText.getText().indexOf(".") < 0)) {
//indexOf() 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1
// 输入的是小数点,并且之前没有小数点,则将小数点附在结果文本框的后面
resultText.setText(resultText.getText() + ".");
} else if (!key.equals(".")) { // 如果输入的不是小数点,则将数字附在结果文本框的后面
resultText.setText(resultText.getText() + key);
}
firstDigit = false;
}
private void doOperator1(String key) {//进行单目运算
operator = key; // 运算符为用户按的按钮
if (operator.equals("1⁄x")) {// 倒数运算
if (resultNum == 0) {
operateValidFlag = false; //操作不合法
resultText.setText("除数不能为零");
} else {
resultNum = 1 / getNumberFromText();
processText.setText("1/(" + resultText.getText() + ")");
}
} else if (operator.equals("√x")) {// 平方根运算
if (resultNum < 0) {
operateValidFlag = false; //操作不合法
resultText.setText("无效输入");
} else {
resultNum = Math.sqrt(getNumberFromText());
processText.setText("√(" + resultText.getText() + ")");
//resultNum = getNumberFromText();
}
} else if (operator.equals("x²")) {// 平方运算X
resultNum = getNumberFromText() * getNumberFromText();
processText.setText("sqr(" + resultText.getText() + ")");
} else if (operator.equals("%")) {// 百分号运算,除以100
resultNum = getNumberFromText() / 100;
} else if (operator.equals("n!")) {
BigInteger num = new BigInteger("1");
BigInteger flat = new BigInteger("1");
for (int i = 0; i < getNumberFromText(); i++) {
flat = flat.multiply(num);
num = num.add(new BigInteger("1"));
}
resultNum = flat.floatValue();//BigInteger转换为float
processText.setText("fact(" + resultText.getText() + ")");
} else if (operator.equals("cos")) {
resultNum = Math.cos(getNumberFromText());
processText.setText("cos(" + resultText.getText() + ")");
} else if (operator.equals("sin")) {
resultNum = Math.sin(getNumberFromText());
processText.setText("sin(" + resultText.getText() + ")");
} else if (operator.equals("+/-")) {// 正数负数运算
resultNum = getNumberFromText() * (-1);
}
isOperateValidFlag(operateValidFlag);
firstDigit = true;//复位
if (operateValidFlag == false) processText.setText(null);
operateValidFlag = true;
}
private void doOperator2(String key) {//进行双目运算
if (operator.equals("÷")) {// 除法运算// 如果当前结果文本框中的值等于0
if (getNumberFromText() == 0.0) {
operateValidFlag = false; //操作不合法
//resultText.setFont(new Font("黑体", Font.BOLD, 40));
resultText.setText("除数不能为零");
//resultText.setFont(new Font("黑体", Font.BOLD, 55));
} else {
resultNum /= getNumberFromText();
}
} else if (operator.equals("+")) {// 加法运算
resultNum += getNumberFromText();
} else if (operator.equals("-")) {// 减法运算
resultNum -= getNumberFromText();
} else if (operator.equals("×")) {// 乘法运算
resultNum *= getNumberFromText();
} else if (operator.equals("=")) {// 赋值运算
resultNum = getNumberFromText();
processText.setText(null);
} else if (operator.equals("aⁿ")) {
resultNum = Math.pow(resultNum, getNumberFromText());
}
if (key.equals("+") || key.equals("×") || key.equals("÷") || key.equals("=")) {
processText.setText(processText.getText() + resultText.getText() + key);
} else if (key.equals("-")) {
processText.setText(processText.getText() + resultText.getText() + "-");
} else if (key.equals("aⁿ")) {
processText.setText(processText.getText() + resultText.getText() + "^");
}
isOperateValidFlag(operateValidFlag);
operator = key; // 运算符为用户按的按钮
firstDigit = true;
if (operateValidFlag == false) {
processText.setText(null);
}
operateValidFlag = true;
}
private void isOperateValidFlag(boolean operateValidFlag) {
if (operateValidFlag) {// 操作合法的情况下,将小数点后的位数进行处理
long t1 = (long) resultNum;
double t2 = resultNum - t1;//得到小数部分
BigDecimal bd = new BigDecimal(String.valueOf(resultNum));//得到小数位数
if (t2 == 0) {
resultText.setText(String.valueOf(t1));//转化为字符串
} else if (bd.scale() == 1) {
resultText.setText(String.valueOf(new DecimalFormat("0.0").format(resultNum)));
} else if (bd.scale() == 2) {
resultText.setText(String.valueOf(new DecimalFormat("0.00").format(resultNum)));
} else if (bd.scale() == 3) {
resultText.setText(String.valueOf(new DecimalFormat("0.000").format(resultNum)));
} else if (bd.scale() == 4) {
resultText.setText(String.valueOf(new DecimalFormat("0.0000").format(resultNum)));
} else if (bd.scale() == 5) {
resultText.setText(String.valueOf(new DecimalFormat("0.00000").format(resultNum)));
} else if (bd.scale() == 6) {
resultText.setText(String.valueOf(new DecimalFormat("0.000000").format(resultNum)));
} else if (bd.scale() == 7) {
resultText.setText(String.valueOf(new DecimalFormat("0.0000000").format(resultNum)));
} else if (bd.scale() == 8) {
resultText.setText(String.valueOf(new DecimalFormat("0.00000000").format(resultNum)));
} else {
resultText.setText(String.valueOf(new DecimalFormat("0.000000000").format(resultNum)));
}
}
}
private double getNumberFromText() {
double result = 0;
try {
result = Double.valueOf(resultText.getText()).doubleValue();
} catch (NumberFormatException e) {
}
return result;
}
public static void main(String[] args) {
new Calculator();
}
}
```