JAVA制作简单的计算器

您所在的位置:网站首页 java计算器的设计思路怎么写 JAVA制作简单的计算器

JAVA制作简单的计算器

2024-07-13 17:30| 来源: 网络整理| 查看: 265

今天我们来学习做一个桌面的简单计算器。之所以说简单,是因为能完成的运算简单,只有加减乘除四则运算,远远不能跟那些功能完备的科学计算器相比。而且其中实现的思路也很简单。

关键词:java计算器,简单计算器,java程序设计,设置监听器。

前期需要:IDE ,javafx包

思路:分为两个方面,第一是计算器的界面怎么做,需要什么元素、控件。第二是对运算的实现。

1、首先来分析一下计算器的基本界面,完成四则运算,基本上就是0~9十个按钮、一个小数点、一个等号、四个加减乘除按钮,还有一个显示文本的Text。大概就长这个样子:

这个布局首先是一个上下结构,上面是一个text文本框,下面是各种按钮,所以我们可以用一个VBox把text放上面,把下面的其他组件放下面。而下面是一个4*4的矩阵,矩阵里放着4*4个按钮(Button)。所以下面的按钮需要一个矩阵来装,这就要用到GridPane,大家可以去稍微看看这个布局管理器,主要是按照按照网格状进行布局。

GridPane的使用方法大概是这样:

gridpane = new GridPane();

gridpane.add(bt_4, 0,1); // 对其添加元素,第一个参数是控件,或者是其他东西,第二三个是其所在的竖直,水平位置。

需要注意的是,add的时候必须从0,0开始一直到n,n 。不能从中间 或者末尾开始,即n,n 到0,0

ok,布局的分析大概到这里,来数一下,大概就是用一个text,一个GridPane,一个VBox,还有4*4个Button。将button放进gridpane里,将text,gridpane放进vbox里。

2、接下来我们来分析一下运算怎么搞,大家可以先想想平时我们算四则运算需要什么,他们出现的先后顺序。没错,我们需要知道第一个数,然后一个操作,然后第二个数,最后只要点击了等号就会出现结果。所以我们需要几个串:firstInput,secondInput,ansOutput。同时我们需要判断一下当前是第一个还是第二个串输入,所以需要一个isSecond(boolean),最后需要一个operation(char)来记录选中的操作。

模拟一下:输入第一个串(点击一下数字在串的末尾加一个数),点击操作(点一下记录一下当前操作,把标志改为第二个串),输入第二个串,点击等号出结果(两个串转为double类型进行运算装在ansS(String)里再更新text内容)。

//--------------------------------------------------------------------------------------------------------------------------------

以上为大体分析,接下来对界面进行布置。

1、新建一个工程,创建包,再建一个.java文件

2、继承Application

然后大概是这样的:

import javafx.application.*; import javafx.stage.Stage; public class test2 extends Application{ public static void main(String[] args){ } @Override public void start(Stage arg0) throws Exception { // TODO Auto-generated method stub } }

3、将所有布局空间都声明出来:

import javafx.application.*; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class test2 extends Application{ public HBox hbox ; public VBox vbox ; public TextField tfAns; public GridPane gridpane; //--------------------------------- //----------Buttons---------------- public Button bt_add; public Button bt_sub; public Button bt_mul; public Button bt_div; public Button bt_ans; public Button bt_0; public Button bt_1; public Button bt_2; public Button bt_3; public Button bt_4; public Button bt_5; public Button bt_6; public Button bt_7; public Button bt_8; public Button bt_9; public Button bt_dot; public Scene scene ; //记录scene的宽高 public double Height; public double Width; public static void main(String[] args){ } @Override public void start(Stage arg0) throws Exception { } }

3、接下来对控件进行绑定,这里我们用两个函数(initBundles();  initGridPane();)绑定,这样好让结构清晰一点:

import javafx.application.*; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class test2 extends Application{ public HBox hbox ; public VBox vbox ; public TextField tfAns; public GridPane gridpane; //--------------------------------- //----------Buttons---------------- public Button bt_add; public Button bt_sub; public Button bt_mul; public Button bt_div; public Button bt_ans; public Button bt_0; public Button bt_1; public Button bt_2; public Button bt_3; public Button bt_4; public Button bt_5; public Button bt_6; public Button bt_7; public Button bt_8; public Button bt_9; public Button bt_dot; public Scene scene ; //记录scene的宽高 public double Height; public double Width; public static void main(String[] args){ Application.launch(args); } @Override public void start(Stage arg0) throws Exception { initBundles(); initGridPane(); //---------------------------------------- scene = new Scene(vbox,330,350); arg0.setTitle("Calculator!"); arg0.setScene(scene); arg0.show(); } public void initBundles() { tfAns = new TextField(); //禁止text可编辑 然后对button设置监听器 //这个TextField没有右对齐,需要右对齐的话改用 JTextField (javax.swing.JTextField) tfAns.setEditable(false); tfAns.setText("0"); //------------------------------------ hbox = new HBox(); gridpane = new GridPane(); //这两个方法可以设置gridpane里面的元素间的间隙,Vgap是垂直方向,Hgap是竖直方向 //gridpane.setHgap(4); //gridpane.setVgap(4); vbox = new VBox(tfAns,gridpane); //------------------------------------ //---------for button----------------- bt_add = new Button("+"); bt_sub = new Button("-"); bt_mul = new Button("*"); bt_div = new Button("/"); bt_0 = new Button("0"); bt_1 = new Button("1"); bt_2 = new Button("2"); bt_3 = new Button("3"); bt_4 = new Button("4"); bt_5 = new Button("5"); bt_6 = new Button("6"); bt_7 = new Button("7"); bt_8 = new Button("8"); bt_9 = new Button("9"); bt_dot = new Button("."); //所有的button一定要new出来,我看了半个钟的exception才找出来,eclipse的检查还是很粗糙的,大家写的时候一定要考虑周全 bt_ans = new Button("="); } public void initGridPane() { gridpane.add(bt_1, 0,0); gridpane.add(bt_2, 1,0); gridpane.add(bt_3, 2,0); gridpane.add(bt_add, 3,0); //------------------------- gridpane.add(bt_4, 0,1); gridpane.add(bt_5, 1,1); gridpane.add(bt_6, 2,1); gridpane.add(bt_sub, 3,1); //------------------------- gridpane.add(bt_7, 0,2); gridpane.add(bt_8, 1,2); gridpane.add(bt_9, 2,2); gridpane.add(bt_mul, 3,2); //------------------------- gridpane.add(bt_0, 0,3); gridpane.add(bt_dot, 1,3); gridpane.add(bt_ans, 2,3); gridpane.add(bt_div, 3,3); //------------------------- } }

4、初步效果是这样的,接下来我们要把按钮的大小设置一下,这时就要用到上面声明的宽高两个东西了:

@Override public void start(Stage arg0) throws Exception { initBundles(); initGridPane(); //---------------------------------------- scene = new Scene(vbox,330,350); //一定要在scene之后,因为函数内需要用到scene的宽高参数,如果放在之前会出现异常,大家可以试一下。 initBTSize(); arg0.setTitle("Calculator!"); arg0.setScene(scene); arg0.show(); }

为防止有占用篇幅的嫌疑,下面我一部分一部分的贴。

/** * 该函数用于设置button的大小 * 思路是从scene里拿到舞台的宽高,然后平分赋值给bt */ public void initBTSize() { Height = scene.getHeight(); Width = scene.getWidth(); bt_add.setMinSize(Width/4, Width/4); bt_sub.setMinSize(Width/4, Width/4); bt_mul.setMinSize(Width/4, Width/4); bt_div.setMinSize(Width/4, Width/4); bt_0.setMinSize(Width/4, Width/4); bt_1.setMinSize(Width/4, Width/4); bt_2.setMinSize(Width/4, Width/4); bt_3.setMinSize(Width/4, Width/4); bt_4.setMinSize(Width/4, Width/4); bt_5.setMinSize(Width/4, Width/4); bt_6.setMinSize(Width/4, Width/4); bt_7.setMinSize(Width/4, Width/4); bt_8.setMinSize(Width/4, Width/4); bt_9.setMinSize(Width/4, Width/4); bt_dot.setMinSize(Width/4, Width/4); bt_ans.setMinSize(Width/4, Width/4); }

效果:

到此为止,界面布局已经搞好了,还是蛮简单的,接下来就是内部运算的问题了。

//--------------------------------------------------------------------------------------------------------------------------------

布局做好了,是不是就要对按钮进行监听器设置了呢?对的,下面我们写一个函数统一对几个按钮设置监听器。

1、在这之前,我们需要声明好上面说的几个关于运算的变量:

//--------for textfield------- String firstInput = ""; String secondInput = ""; String ansOutput = ""; boolean isSecond; char operations;

2、用一个函数统一对按钮设置监听器,先给数字:

public void initListener() { //-----for number buttons------------- bt_0.setOnAction(e->{ if(!isSecond) { firstInput+="0"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="0"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_1.setOnAction(e->{ if(!isSecond) { firstInput+="1"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="1"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_2.setOnAction(e->{ if(!isSecond) { firstInput+="2"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="2"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_3.setOnAction(e->{ if(!isSecond) { firstInput+="3"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="3"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_4.setOnAction(e->{ if(!isSecond) { firstInput+="4"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="4"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_5.setOnAction(e->{ if(!isSecond) { firstInput+="5"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="5"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_6.setOnAction(e->{ if(!isSecond) { firstInput+="6"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="6"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_7.setOnAction(e->{ if(!isSecond) { firstInput+="7"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="7"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_8.setOnAction(e->{ if(!isSecond) { firstInput+="8"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="8"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_9.setOnAction(e->{ if(!isSecond) { firstInput+="9"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="9"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_dot.setOnAction(e->{ if(!isSecond) { firstInput+="."; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="."; ansOutput = secondInput; tfAns.setText(secondInput); } }); //------------------------------------}

设置数字的监听器很简单,思路是判断选择的是第一个串还是第二个串,然后对对应的串进行追加数字。

记得在start里面调用函数,效果:

还是在这个函数里,对四则运算加监听器:

//-------for operations--------------- bt_add.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "+"; operations = '+'; } }); bt_sub.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "-"; operations = '-'; } }); bt_mul.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "*"; operations = '*'; } }); bt_div.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "/"; operations = '/'; } });

这里注意,标志的变化,还有对操作的赋值。完成这步操作之后就已经完成了对两个串,一个操作数的安排了。接下来只需要一个等号就可以输出结果了。

//-------for ansString-------------- bt_ans.setOnAction(e->{ //将两个串转成double类型 然后根据不同的operations进行运算 double firstS = Double.parseDouble(firstInput); double secondS = Double.parseDouble(secondInput); double ansS = 0.0f; if(operations == '+') { ansS = firstS+secondS; }else if (operations == '-') { ansS = firstS - secondS; }else if (operations == '*') { ansS = firstS * secondS; }else if (operations == '/') { ansS = firstS / secondS; } //将ansS转串对tfAns赋值 则完成对结果的显示 tfAns.setText(ansS+""); //完成操作后还要对isSecond标志进行初始化即变为false //这里可以再改进一下,将上次的结果变为first串,这样就不用改标志isSecond,但是要加一个ClearButton来清零,表示运算重新开始 isSecond = false; //对两个串进行清零,不然下一个操作的时候会错误 firstInput = "";secondInput = ""; });

简单来说,这个监听器就是把两个串转double,运算,然后结果转String再贴到tfAns。

//--------------------------------------------------------------------------------------------------------------------------------

好啦,一个完整的简单计算器已经出来了,能够实现两数字的四则运算。

但是这里还有许多bug,比如说text的对其方式是左对齐,如何才能让他右对齐?添加运算的时候运算操作并不会显示在text里,如何让两个串完完整整的显示出来如:255*255这样子?如果用户误点击多次操作,比如255*-+/+255,他们最后做的运算是怎么样?

这些bug在这没有修改,希望有兴趣的同学可以自己琢磨修改一下。

下面我给大家贴一下整个.java文件,里面有很多注释在博客中没有点到,大家可以看看。

//--------------------------------------------------------------------------------------------------------------------------------

import javafx.application.*; import javafx.stage.Stage; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; import javafx.geometry.*; /** * 为了尽量让结构清晰,这个.java用来负责界面的渲染 * * @author Frankie To * * 计算器总体的结构为上下结构,上面是一个显示文本的Text,下面是一个Pane,所以我们可以用一个VBox来吧两个东西装进去 * 下半部分因为是4*4结构,所以可以用GridPane并且把Button一个个都new出来 因为不只是做一个UI * 界面,我们要把button全都new出来做运算 * * * =.= 这里被打脸了,这次是赶上学校要交一个计算器的UI的程序,所以想做一个功能基本能实现的简单计算器出来。 * 因为很少用eclipse,不清楚怎么对文件进行拆分,所以只能将所有东西放在一个.java里。正常工程里应该遵循软件工程的低耦合高聚合的理念来做 * 不过在这个工程里,也有一点点这种思想的体现,对不同模块的功能,都抽出来尽量做成一个方法或者类。 * 在以后的实战中这样的代码方便维护和理解。 */ public class ScaleView extends Application { public HBox hbox ; public VBox vbox ; public TextField tfAns; public GridPane gridpane; //--------------------------------- //----------Buttons---------------- public Button bt_add; public Button bt_sub; public Button bt_mul; public Button bt_div; public Button bt_ans; public Button bt_0; public Button bt_1; public Button bt_2; public Button bt_3; public Button bt_4; public Button bt_5; public Button bt_6; public Button bt_7; public Button bt_8; public Button bt_9; public Button bt_dot; public Scene scene ; //记录scene的宽高 public double Height; public double Width; //---------------------------- //--------for textfield------- String firstInput = ""; String secondInput = ""; String ansOutput = ""; boolean isSecond; char operations; //这几个变量主要是用来文本的输入输出的 //输入数分为第一个输入,第二个输入,所以夙瑶两个串来存,然后用一个串ans来更新 //用一个boolean 变量来记录是否是第二哥输入数,如果是第二个输入的数,则将第一个串跟第二个串变为整形计算输出到ans //---------------------------- //--------------------------------- @Override public void start(Stage arg0) throws Exception { //用一个函数initBundles()来对基本控件进行初始化 //结构上更加清晰 initBundles(); initGridPane(); //---------------------------------------- scene = new Scene(vbox,330,350); initBTSize(); initListener(); isSecond = false; arg0.setTitle("Calculator!"); arg0.setScene(scene); arg0.show(); } public void initListener() { //-----for number buttons------------- bt_0.setOnAction(e->{ if(!isSecond) { firstInput+="0"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="0"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_1.setOnAction(e->{ if(!isSecond) { firstInput+="1"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="1"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_2.setOnAction(e->{ if(!isSecond) { firstInput+="2"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="2"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_3.setOnAction(e->{ if(!isSecond) { firstInput+="3"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="3"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_4.setOnAction(e->{ if(!isSecond) { firstInput+="4"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="4"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_5.setOnAction(e->{ if(!isSecond) { firstInput+="5"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="5"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_6.setOnAction(e->{ if(!isSecond) { firstInput+="6"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="6"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_7.setOnAction(e->{ if(!isSecond) { firstInput+="7"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="7"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_8.setOnAction(e->{ if(!isSecond) { firstInput+="8"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="8"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_9.setOnAction(e->{ if(!isSecond) { firstInput+="9"; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="9"; ansOutput = secondInput; tfAns.setText(secondInput); } }); bt_dot.setOnAction(e->{ if(!isSecond) { firstInput+="."; ansOutput = firstInput; tfAns.setText(ansOutput); }else { secondInput+="."; ansOutput = secondInput; tfAns.setText(secondInput); } }); //------------------------------------ //-------for operations--------------- bt_add.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "+"; operations = '+'; } }); bt_sub.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "-"; operations = '-'; } }); bt_mul.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "*"; operations = '*'; } }); bt_div.setOnAction(e->{ if(!isSecond) { isSecond = true; ansOutput += "/"; operations = '/'; } }); //-------for ansString-------------- bt_ans.setOnAction(e->{ //将两个串转成double类型 然后根据不同的operations进行运算 double firstS = Double.parseDouble(firstInput); double secondS = Double.parseDouble(secondInput); double ansS = 0.0f; if(operations == '+') { ansS = firstS+secondS; }else if (operations == '-') { ansS = firstS - secondS; }else if (operations == '*') { ansS = firstS * secondS; }else if (operations == '/') { ansS = firstS / secondS; } //将ansS转串对tfAns赋值 则完成对结果的显示 tfAns.setText(ansS+""); //完成操作后还要对isSecond标志进行初始化即变为false //这里可以再改进一下,将上次的结果变为first串,这样就不用改标志isSecond,但是要加一个ClearButton来清零,表示运算重新开始 isSecond = false; //对两个串进行清零,不然下一个操作的时候会错误 firstInput = "";secondInput = ""; }); } /** * 该函数用于设置button的大小 * 思路是从scene里拿到舞台的宽高,然后平分赋值给bt */ public void initBTSize() { Height = scene.getHeight(); Width = scene.getWidth(); bt_add.setMinSize(Width/4, Width/4); bt_sub.setMinSize(Width/4, Width/4); bt_mul.setMinSize(Width/4, Width/4); bt_div.setMinSize(Width/4, Width/4); bt_0.setMinSize(Width/4, Width/4); bt_1.setMinSize(Width/4, Width/4); bt_2.setMinSize(Width/4, Width/4); bt_3.setMinSize(Width/4, Width/4); bt_4.setMinSize(Width/4, Width/4); bt_5.setMinSize(Width/4, Width/4); bt_6.setMinSize(Width/4, Width/4); bt_7.setMinSize(Width/4, Width/4); bt_8.setMinSize(Width/4, Width/4); bt_9.setMinSize(Width/4, Width/4); bt_dot.setMinSize(Width/4, Width/4); bt_ans.setMinSize(Width/4, Width/4); } public void initBundles() { tfAns = new TextField(); //禁止text可编辑 然后对button设置监听器 //这个TextField没有右对齐,需要右对齐的话改用 JTextField (javax.swing.JTextField) tfAns.setEditable(false); tfAns.setText("0"); //------------------------------------ hbox = new HBox(); gridpane = new GridPane(); //这两个方法可以设置gridpane里面的元素间的间隙,Vgap是垂直方向,Hgap是竖直方向 //gridpane.setHgap(4); //gridpane.setVgap(4); vbox = new VBox(tfAns,gridpane); //------------------------------------ //---------for button----------------- bt_add = new Button("+"); bt_sub = new Button("-"); bt_mul = new Button("*"); bt_div = new Button("/"); bt_0 = new Button("0"); bt_1 = new Button("1"); bt_2 = new Button("2"); bt_3 = new Button("3"); bt_4 = new Button("4"); bt_5 = new Button("5"); bt_6 = new Button("6"); bt_7 = new Button("7"); bt_8 = new Button("8"); bt_9 = new Button("9"); bt_dot = new Button("."); //所有的button一定要new出来,我看了半个钟的exception才找出来,eclipse的检查还是很粗糙的,大家写的时候一定要考虑周全 bt_ans = new Button("="); } public void initGridPane() { gridpane.add(bt_1, 0,0); gridpane.add(bt_2, 1,0); gridpane.add(bt_3, 2,0); gridpane.add(bt_add, 3,0); //------------------------- gridpane.add(bt_4, 0,1); gridpane.add(bt_5, 1,1); gridpane.add(bt_6, 2,1); gridpane.add(bt_sub, 3,1); //------------------------- gridpane.add(bt_7, 0,2); gridpane.add(bt_8, 1,2); gridpane.add(bt_9, 2,2); gridpane.add(bt_mul, 3,2); //------------------------- gridpane.add(bt_0, 0,3); gridpane.add(bt_dot, 1,3); gridpane.add(bt_ans, 2,3); gridpane.add(bt_div, 3,3); //------------------------- } public static void main(String[] args) { Application.launch(args); } }江湖再见!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3