参考一 Win7 计算器使用
修改部分:
- 菜单栏修改了可选项,如二进制转换等等。
- 给各个按钮布局,可以如之前 java制作仿win7计算器之一计算器的图形界面的设计 的方式,即简单的赋值,然后逐个添加监听事件,更简洁的如下方式二,即采用数组和循环。
- actionPerformed(ActionEvent e){} 方法中,为了更方便知晓所取得的按钮值,采用了e.getActionCommand()方式。当然之前采用的e.getSource() == jmi[i] 也没有舍弃。
具体的代码如下:
package Calculator;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Calculator extends JFrame implements ActionListener{//自定义类文件,必须继承JFrame框架
//定义组件
JMenuBar jmb;
JMenu[] jm;
JMenuItem[] jmi;
JTextField[] jtf;
JButton[] jb;
//操作变量
String store;//缓存字符串
String jtf0str;//给第一、二个文本框存放操作过程
String jtf2str;//给第三个文本框存放操作数
boolean newDigital = true;//是否是输入新数的状态
double d;// 一元运算的变量
double d1;//二元运算的前操作数
double d2;//二元运算的后操作数
int optionValue ;//创建用于区分加减乘除运算到变量
public static void main(String[] args)// 添加主函数,并调用类的构造函数
{
new Calculator();
}
public Calculator()//添加构造函数
{
//操作的变量赋初值。
store = "";
jtf0str = "";
//创建组件
jmb = new JMenuBar();
jm = new JMenu[3];
jm[0] = new JMenu("查看(V)");
jm[1] = new JMenu("编辑(E)");
jm[2] = new JMenu("帮助(H)");
jmi = new JMenuItem[6];
jmi[0] = new JMenuItem("二进制转换");
jmi[1] = new JMenuItem("八进制转换");
jmi[2] = new JMenuItem("十六进制转换");
jmi[3] = new JMenuItem("复制(C)");
jmi[4] = new JMenuItem("粘贴(P)");
jmi[5] = new JMenuItem("关于计算器(A)");
for(int i = 0; i < 6; i++)
{
jmi[i].addActionListener(this);
}
jtf = new JTextField[3];
/*给各个按钮布局方式一
jb = new JButton[28];
jb[0] = new JButton("MC");
jb[1] = new JButton("MR");
jb[2] = new JButton("MS");
jb[3] = new JButton("M+");
jb[4] = new JButton("M-");
jb[5] = new JButton("Backspace");
jb[6] = new JButton("CE");
jb[7] = new JButton("C");
jb[8] = new JButton("+/-");
jb[9] = new JButton("sqrt");
jb[10] = new JButton("7");
jb[11] = new JButton("8");
jb[12] = new JButton("9");
jb[13] = new JButton("/");
jb[14] = new JButton("%");
jb[15] = new JButton("4");
jb[16] = new JButton("5");
jb[17] = new JButton("6");
jb[18] = new JButton("*");
jb[19] = new JButton("1/x");
jb[20] = new JButton("1");
jb[21] = new JButton("2");
jb[22] = new JButton("3");
jb[23] = new JButton("-");
jb[24] = new JButton("=");
jb[25] = new JButton("0");
jb[26] = new JButton(".");
jb[27] = new JButton("+");
for(int i = 0; i < 28; i++)//监听28个按钮
jb[i].addActionListener(this);
*/
/*给各个按钮布局简洁的方式二*/
String dsKey[] = {"MC","MR","MS","M+","M-","Backspace","CE","C","+/-","sqrt","7","8","9","/","%","4","5","6","*","1/x",
"1","2","3","-","=","0",".","+"};
jb = new JButton[28];
for(int i = 0; i< 28;i++)
{
jb[i] = new JButton(dsKey[i]);
jb[i].addActionListener(this);//给各个按钮添加监听处理器
}
initGUI();//设置布局,添加组件
//设置窗口属性
this.setTitle("使用java制作的简易计算器By毛二");//基础属性
this.setIconImage(new ImageIcon("熊猫.jpg").getImage());//设置窗口标题
this.setSize(400,350);//设置大小,按像素
this.setLocation(1000,200);//设置初始位置,默认是屏幕最左上角
this.setVisible(true);//让它显示,位置可变
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置默认到关闭操作,不然java虚拟机还没也关闭
}
//设置布局。
private void initGUI() {
this.setJMenuBar(jmb);
jmb.add(jm[0]);
jmb.add(jm[1]);
jmb.add(jm[2]);
jm[0].add(jmi[0]);
jm[0].add(jmi[1]);
jm[0].add(jmi[2]);
jm[1].add(jmi[3]);
jm[1].add(jmi[4]);
jm[2].add(jmi[5]);
//显示记忆索引值文本框
jtf[0] = new JTextField();
jtf[0].setEditable(false);
jtf[0].setHorizontalAlignment(JTextField.RIGHT);
//显示M
jtf[1] = new JTextField();
jtf[1].setEditable(false);
jtf[1].setHorizontalAlignment(JTextField.LEFT);
//显示文本输入结果
jtf[2] = new JTextField("0");
jtf[2].setEditable(false);
jtf[2].setHorizontalAlignment(JTextField.RIGHT);
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag);
c.weightx = 0.01;//容器上的计算器各个部件成一个布局,这个参数,可以把容器和窗体合二为一,不会出现窗体过大而容器还留有空隙
c.weighty = 0.01;
c.fill = GridBagConstraints.BOTH;
//文本框
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 5;
c.gridheight = 1;
add(jtf[0],c);
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
add(jtf[1],c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 4;
c.gridheight = 1;
add(jtf[2],c);
//MC
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1; // 横占一个单元格
c.gridheight = 1; // 列占一个单元格
addButton(jb[0],gridbag,c);//添加按钮到面板布局
//MR
c.gridx = 1; //换行,放置组件,只需要修改行的参数就行,其他参数暂时不变。
addButton(jb[1],gridbag,c);
//MS
c.gridx = 2;
addButton(jb[2],gridbag,c);
//M+
c.gridx = 3;
addButton(jb[3],gridbag,c);
//M-
c.gridx = 4;
addButton(jb[4],gridbag,c);
//Backspace
c.gridx = 0;
c.gridy = 3;
addButton(jb[5],gridbag,c);
//CE
c.gridx = 1;
addButton(jb[6],gridbag,c);
//C
c.gridx = 2;
addButton(jb[7],gridbag,c);
//+/-
c.gridx = 3;
addButton(jb[8],gridbag,c);
//Sqrt
c.gridx = 4;
addButton(jb[9],gridbag,c);
//7
c.gridx = 0;
c.gridy = 4;
addButton(jb[10],gridbag,c);
//8
c.gridx = 1;
addButton(jb[11],gridbag,c);
//9
c.gridx = 2;
addButton(jb[12],gridbag,c);
///
c.gridx = 3;
addButton(jb[13],gridbag,c);
//%
c.gridx = 4;
addButton(jb[14],gridbag,c);
//4
c.gridx = 0;
c.gridy = 5;
addButton(jb[15],gridbag,c);
//5
c.gridx = 1;
addButton(jb[16],gridbag,c);
//6
c.gridx = 2;
addButton(jb[17],gridbag,c);
//*
c.gridx = 3;
addButton(jb[18],gridbag,c);
//1/x
c.gridx = 4;
addButton(jb[19],gridbag,c);
//1
c.gridx = 0;
c.gridy = 6;
addButton(jb[20],gridbag,c);
//2
c.gridx = 1;
addButton(jb[21],gridbag,c);
//3
c.gridx = 2;
addButton(jb[22],gridbag,c);
//-
c.gridx = 3;
addButton(jb[23],gridbag,c);
//=
c.gridx = 4;
c.gridy = 6;
c.gridheight = 2; //重新设置列,列占二个单元格
addButton(jb[24],gridbag,c);
//0
c.gridx = 0;
c.gridy = 7;
c.gridwidth = 2; // 重新设置横,横占二个单元格
c.gridheight = 1; // 恢复列,列占一个单元格
addButton(jb[25],gridbag,c);
//.
c.gridx = 2;
c.gridwidth = 1; // 恢复横,横占一个单元格
addButton(jb[26],gridbag,c);
//+
c.gridx = 3;
addButton(jb[27],gridbag,c);
}
//添加按钮到面板布局
private void addButton(JButton jButton, GridBagLayout gridbag,
GridBagConstraints c) {
gridbag.setConstraints(jButton, c);
add(jButton);
}
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();//判断按此动作相关到字符串
jtf2str = jtf[2].getText();// 获取文本框中到字符串
if(e.getSource() == jmi[0]){//二进制转换
int n = Integer.parseInt(jtf2str);
jtf[2].setText(Integer.toBinaryString(n));
}
if(e.getSource() == jmi[1]){//八进制转换
int n = Integer.parseInt(jtf2str);
jtf[2].setText(Integer.toOctalString(n));
}
if(e.getSource() == jmi[2]){//十六进制转换
int n = Integer.parseInt(jtf2str);
jtf[2].setText(Integer.toHexString(n));
}
if(e.getSource() == jmi[3]){//复制
store = jtf2str;
}
if(e.getSource() == jmi[4]){//粘贴
jtf2str = store;
if(jtf2str == "")
{
jtf[2].setText("0");
}
else
{
jtf[2].setText(jtf2str);
}
}
if(e.getSource() == jmi[5]){//关于计算器
JOptionPane.showMessageDialog(null, "仿制Win7简易计算器By毛二");
}
/*M表示Memory,是指一个中间数据缓存器,MC=Memory Clear,
MR=Memory Read, MS=Memory Save, M+=Memory Add, M-=Memory Minus
可以用一个例子来演示:(7-2) * (8-2)=
先输入7,按MS保存,输入2,按M-与缓存器中的7相减,此时缓存器中的值为5;
然后计算8-2,得出结果为6,输入*相乘,按MR读出之前保存的数5,按=得出结果30,算完后按MC清除缓存器。
*/
if(s.equals("MC"))
{
jtf[1].setText("");
}
if(s.equals("MR"))
{
jtf[2].setText(store);
}
if(s.equals("MS"))
{
jtf[1].setText("M");
store = jtf2str;
}
if(s.equals("M+"))
{
d1 = Double.parseDouble(store);
d2 = Double.parseDouble(jtf2str);
store = String.valueOf(d1 + d2);
}
if(s.equals("M-"))
{
d1 = Double.parseDouble(store);
d2 = Double.parseDouble(jtf2str);
store = String.valueOf(d1 - d2);
}
if(s.equals("Backspace"))//Backspace,退格上一次到最后一个数。
{
jtf[2].setText(jtf2str.substring(0,jtf2str.length()- 1)); //截取最后一个操作数不要。但是不要改变标志位。
}
if(s.equals("CE"))//清除本次输入的错误。比如你输入1+2之后,按CE会清除第二个参数2,你可以继续输入其他数和第一个参数1相加
{
jtf[2].setText("0");
newDigital = true;
}
if(s.equals("C"))//清零。比如你输入1+2之后,按C则整个的删除1+2这个计算,你需要重新开始一个计算。
{
jtf[0].setText("");
jtf[1].setText("");
jtf[2].setText("0");
optionValue = 0;//把之前按下到操作到运算符到键清除
newDigital = true;
}
//操作运算数。整数,正负数,小数
if(s.equals("0")|| s.equals("1")|| s.equals("2")|| s.equals("3")|| s.equals("4")|| s.equals("5")|| s.equals("6")|| s.equals("7")|| s.equals("8")|| s.equals("9"))
{
if(!newDigital)//判断是否是新数
{ //连续输入的数
jtf[2].setText(jtf2str + s);
}
else //新数
{
jtf[2].setText(s);
newDigital = false;//不是新数,将标志设为假
}
return;//保证下次输入的数仍然是最后一次改变的标志位。即输入一个数的话,文本框值就是这个数,并把标志位变为假。下次如果还是输入数字的话,如果上次的标志位为假,文本框的值是这两个数的拼接,
}
if(s.equals("."))//小数点
{
if(jtf[2].getText().indexOf(".") == -1)//如果不存在小数点
{//判断数字是否是以零开头
if(jtf[2].getText().trim().startsWith("0"))
{
jtf[2].setText("0.");
newDigital = false;//因为0.是旧数。如果不设置标志位,下一次遇到数字,由于标志位还是真,那么就抛弃前缀0.
}
else
{
jtf[2].setText( jtf2str + ".");
}
}
return;//保持输入的数添加小数点后仍然是一个旧数。如果不返回,那么程序继续走完此actionPerformed方法,会执行到一句newDigital = true,下一次遇到数字,会抛弃前缀xx.
}
if(s.equals("+/-"))//正负号
{
d = Double.parseDouble(jtf2str.trim());
jtf[2].setText(String.valueOf(-d));
return;//保证下次输入的数字是旧数。不改变标志位。
}
newDigital = true;//保证下次按键被触发输入的数都是新数。位置可以从此往下随意放到各个if分支中或者所有if分支之后,只要确保以下进行的加减乘除等操作后面接的新输入的数字都是新数
//运算操作 + - * / =
if(s.equals("+"))
{
d1 = Double.parseDouble(jtf[2].getText());
optionValue = 1;
jtf0str = d1 + "+";
jtf[0].setText(jtf0str);
}
if(s.equals("-"))
{
d1 = Double.parseDouble(jtf[2].getText());
optionValue = 2;
jtf0str = d1 + "-";
jtf[0].setText(jtf0str);
}
if(s.equals("*"))
{
d1 = Double.parseDouble(jtf[2].getText());
optionValue = 3;
jtf0str = d1 + "*";
jtf[0].setText(jtf0str);
}
if(s.equals("/"))
{
d1 = Double.parseDouble(jtf[2].getText());
optionValue = 4;
jtf0str = d1 + "/";
jtf[0].setText(jtf0str);
}
if(s.equals("="))
{
d2 = Double.parseDouble(jtf[2].getText());
if(d2 < 0)
{
jtf0str += "("+ d2 +")" + "=" ;
}
else
{
jtf0str += d2 + "=" ;
}
jtf[0].setText(jtf0str);
switch(optionValue)
{
case 1:
jtf[2].setText(String.valueOf(d1 + d2));
break;
case 2:
jtf[2].setText(String.valueOf(d1 - d2));
break;
case 3:
jtf[2].setText(String.valueOf(d1 * d2));
break;
case 4:
if(d2 != 0)
jtf[2].setText(String.valueOf(d1 / d2));
else
{
jtf[2].setText("除数不能为零");
return;
}
break;
}
}
//单操作符 根号、百分号和倒数运算
d = Double.parseDouble(jtf[2].getText().trim());// 获取操作数
if(s.equals("sqrt"))
{
if (d >= 0) {
jtf[2].setText(String.valueOf(Math.sqrt(d)));// 是不小于0的数就获取平方根
} else {
jtf[2].setText("小于0的数不能进行根号运算");// 小于0的数不能进行根号运算,报错
}
}
if(s.equals("%"))
{
jtf[2].setText(String.valueOf(d*0.01));
}
if(s.equals("1/x"))
{
jtf[2].setText(String.valueOf(1/d));
}
}
}