Java GUI图形编程 使用awt和swing 制作简易计算器的工具包含源码和讲解 / java练习项目
创始人
2024-02-17 00:16:01
0

系列文章目录

提示:阅读本章之前,请先阅读目录


文章目录

  • 系列文章目录
  • 前言
  • 一、常规配置
    • 1. 设置窗口大小
    • 2. 获取当前屏幕的尺寸
    • 3. 窗口居中
    • 4. 设置窗口名称
    • 5. 添加监听器,关闭窗口
    • 6. 设置窗口可见性
    • 7. 设置文本框不可编辑
    • 8. 设置文本框提示
    • 9. 设置文本框的尺寸大小
    • 10. 设置文本框的字体样式
    • 11. 设置文本域的滚动条
    • 12. 弹出框提示
    • 13. 警告弹出框提示
  • 二、目录结构
  • 三、Calculator.java,入口
  • 四、MyFrame.java 创建窗口frame
  • 五、WindowClose.java,监听关闭
  • 六、WindowVisible.java,设置窗口可见性
  • 七、SetComponent.java,绘制各种组件
  • 八、ButtonListener.java 按键监听器,处理按键事件
  • 九、异常处理
  • 十、exe4j Wizard 使用生成exe
    • 1. 先在 IntelliJ IDEA 安装Handy Export Jar![在这里插入图片描述](https://img.pic99.top/dingtaihe/202402/dc489ee726e2f2a.png)
    • 2. 然后导出为jar包
    • 3. 打开exe4j Wizard
  • 更新日志


前言

通过学习java 的gui编程,可以快速学习java基础语法,让我们来看看如何制作一个简易计算器,以下包含全部源码。

简易计算器 v1.2 图形界面

在这里插入图片描述
计算过程的界面

在这里插入图片描述


一、常规配置

1. 设置窗口大小

setSize(600, 590);

2. 获取当前屏幕的尺寸

int screenWidth = (int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int screenHeight = (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
// 最后可用于设置窗口位置
setLocation(screenWidth/3, screenHeight/6);

3. 窗口居中

setLocationRelativeTo(null);

4. 设置窗口名称

setTitle(title);

5. 添加监听器,关闭窗口

frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}
});

6. 设置窗口可见性

 frame.setVisible(true);

7. 设置文本框不可编辑

jTextField1.setEditable(false);

8. 设置文本框提示

jTextField1.setToolTipText("请输入计算数字");

9. 设置文本框的尺寸大小

jTextField1.setPreferredSize(new Dimension(580, 40));

10. 设置文本框的字体样式

jTextField1.setFont(new Font("", Font.BOLD, 20));

11. 设置文本域的滚动条

JTextArea jTextArea1 = new JTextArea();
JScrollPane sp = new JScrollPane(jTextArea1);
sp.setPreferredSize(new Dimension(580, 160));
p7.add(sp);

12. 弹出框提示

JOptionPane.showMessageDialog(null,"暂时不支持超过10位数字的计算");

13. 警告弹出框提示

JOptionPane.showMessageDialog(null, "系统出现了计算错误", "系统报错 " + "可联系管理员处理", JOptionPane.ERROR_MESSAGE);

二、目录结构

ButtonListener.java   按键监听器,主要进行处理各种按键之后的事件,算法
Calculator.java   入口程序
MyFrame.java   创建一个frame窗口
SetComponent.java   绘制界面,按钮,面板,输入框
WindowClose.java  监听窗口关闭
WindowVisible.java  设置窗口为可见性

三、Calculator.java,入口

package com.tools;public class Calculator {public static void main(String[] args) {// 初始化窗口MyFrame myFrame = new MyFrame("Smobee Calculator v1.2");// 初始化组件new SetComponent(myFrame);// 设置监听关闭new WindowClose(myFrame);// 设置窗口加载完,就显示可见new WindowVisible(myFrame);}
}

四、MyFrame.java 创建窗口frame

package com.tools;import java.awt.*;public class MyFrame extends Frame {MyFrame(String title) {// 设置窗口大小setSize(600, 590);// 窗口居中setLocationRelativeTo(null);// 设置窗口名称setTitle(title);}
}

五、WindowClose.java,监听关闭

package com.tools;import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;public class WindowClose {WindowClose(Frame frame) {frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {// 监听到点击关闭按钮,关闭程序System.exit(0);}});}
}

六、WindowVisible.java,设置窗口可见性

要在所有的组件添加完毕之后,再设置窗口可见性,要不然,第一次显示窗口,会是一片空白

package com.tools;import java.awt.*;public class WindowVisible {WindowVisible(Frame frame) {// 设置frame窗口,为可见frame.setVisible(true);}
}

七、SetComponent.java,绘制各种组件

package com.tools;import javax.swing.*;
import javax.swing.text.Highlighter;
import java.awt.*;public class SetComponent {JButton jButton1,jButton2,jButton3,jButton4,jButton5,jButton6,jButton7,jButton8,jButton9,jButton10,jButton11,jButton12,jButton13,jButton14,jButton15,jButton16,jButton17,jButton18,jButton19,jButton20;JTextField jTextField1;JTextArea jTextArea1;// 两个数double number1, number2;// 当前第几个数int selectNumber = 1;// 是否为小数点boolean isFloat = false;// 当前算法 0 无 1 加 2 减 3 乘 4 除 5 除...余String algo = "no";// 第一个数字激活状态boolean number1State = false;// 第二个数字激活状态boolean number2State = false;// 是否计算结束boolean calcState = false;SetComponent(Frame frame) {// 创建整体的面板Panel panel = new Panel();// 第一层Panel p1 = new Panel(new FlowLayout());jTextField1 = new JTextField();jTextField1.setEditable(false);jTextField1.setToolTipText("请输入计算数字");jTextField1.setPreferredSize(new Dimension(580, 40));jTextField1.setFont(new Font("", Font.BOLD, 20));p1.add(jTextField1);// 第二层Panel p2 = new Panel(new GridLayout(1, 4));jButton1 = new JButton("C");jButton2 = new JButton("÷");jButton3 = new JButton("*");jButton4 = new JButton("Del");jButton1.setPreferredSize(new Dimension(145, 60));jButton1.addActionListener(new ButtonListener(this));jButton2.addActionListener(new ButtonListener(this));jButton3.addActionListener(new ButtonListener(this));jButton4.addActionListener(new ButtonListener(this));// 第三层Panel p3 = new Panel(new GridLayout(1, 4));jButton5 = new JButton("7");jButton6 = new JButton("8");jButton7 = new JButton("9");jButton8 = new JButton("-");jButton5.setPreferredSize(new Dimension(145, 60));jButton5.addActionListener(new ButtonListener(this));jButton6.addActionListener(new ButtonListener(this));jButton7.addActionListener(new ButtonListener(this));jButton8.addActionListener(new ButtonListener(this));// 第四层Panel p4 = new Panel(new GridLayout(1, 4));jButton9 = new JButton("4");jButton10 = new JButton("5");jButton11 = new JButton("6");jButton12 = new JButton("+");jButton9.setPreferredSize(new Dimension(145, 60));jButton9.addActionListener(new ButtonListener(this));jButton10.addActionListener(new ButtonListener(this));jButton11.addActionListener(new ButtonListener(this));jButton12.addActionListener(new ButtonListener(this));// 第五层Panel p5 = new Panel(new GridLayout(1, 4));jButton13 = new JButton("1");jButton14 = new JButton("2");jButton15 = new JButton("3");jButton16 = new JButton("√");jButton13.setPreferredSize(new Dimension(145, 60));jButton13.addActionListener(new ButtonListener(this));jButton14.addActionListener(new ButtonListener(this));jButton15.addActionListener(new ButtonListener(this));jButton16.addActionListener(new ButtonListener(this));// 第六层Panel p6 = new Panel(new GridLayout(1, 4));jButton17 = new JButton("%");jButton18 = new JButton("0");jButton19 = new JButton(".");jButton20 = new JButton("=");jButton17.setPreferredSize(new Dimension(145, 60));jButton17.addActionListener(new ButtonListener(this));jButton18.addActionListener(new ButtonListener(this));jButton19.addActionListener(new ButtonListener(this));jButton20.addActionListener(new ButtonListener(this));// 第七层Panel p7 = new Panel(new GridLayout(1, 1));jTextArea1 = new JTextArea();JScrollPane sp = new JScrollPane(jTextArea1);sp.setPreferredSize(new Dimension(580, 160));jTextArea1.setText("历史计算:");jTextArea1.setEditable(false);// 放进容器panel.add(p1);p2.add(jButton1);p2.add(jButton2);p2.add(jButton3);p2.add(jButton4);p3.add(jButton5);p3.add(jButton6);p3.add(jButton7);p3.add(jButton8);p4.add(jButton9);p4.add(jButton10);p4.add(jButton11);p4.add(jButton12);p5.add(jButton13);p5.add(jButton14);p5.add(jButton15);p5.add(jButton16);p6.add(jButton17);p6.add(jButton18);p6.add(jButton19);p6.add(jButton20);p7.add(sp);panel.add(p2);panel.add(p3);panel.add(p4);panel.add(p5);panel.add(p6);panel.add(p7);frame.add(panel);}
}

八、ButtonListener.java 按键监听器,处理按键事件

这里主要进行各种算法的运算,其中,就用到比较简单的方法,没有用Math进行算法,主要是为了练习,如果您追求细节,可以尝试修改代码,使其更加符合标准计算器的算法


本程序,还尚有许多bug,主要是时间不够,各位同学如发现有计算bug,可以提交到评论区或私信,同学们也可以发挥个人能力

package com.tools;import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;public class ButtonListener implements ActionListener {SetComponent setComponent;ButtonListener(SetComponent setComponent) {this.setComponent = setComponent;}private void setText(Double result) {if (this.setComponent.isFloat || this.setComponent.algo.equals("÷")) {DecimalFormat df = new DecimalFormat("0.00");this.setComponent.jTextField1.setText(Double.toString(Double.parseDouble(df.format(result))));} else {int x = (int) Math.round(result);this.setComponent.jTextField1.setText(Integer.toString(x));}}private void clearNunber(Boolean clearText, Boolean clearCalc) {if (clearText) {this.setComponent.jTextField1.setText("");}if (clearCalc) {this.setComponent.calcState = false;}this.setComponent.selectNumber = 1;this.setComponent.number1 = 0;this.setComponent.number2 = 0;this.setComponent.number1State = false;this.setComponent.number2State = false;this.setComponent.isFloat = false;this.setComponent.algo = "no";}private void calcNumber() {double result = 0;// 判断两个数,是否都输入了if (this.setComponent.number1State && this.setComponent.number2State) {String algo = this.setComponent.algo;if (algo.equals("*")) {result = this.setComponent.number1 * this.setComponent.number2;} else if (algo.equals("÷")) {result = this.setComponent.number1 / this.setComponent.number2;} else if (algo.equals("-")) {result = this.setComponent.number1 - this.setComponent.number2;} else if (algo.equals("+")) {result = this.setComponent.number1 + this.setComponent.number2;} else if (algo.equals("%")) {result = this.setComponent.number1 % this.setComponent.number2;} else if (algo.equals("√")) {result = Math.sqrt(this.setComponent.number1);}this.setText(result);this.addHistory();// 恢复初始化this.clearNunber(false, false);} else if (this.setComponent.number1State && this.setComponent.algo.equals("√")) {String algo = this.setComponent.algo;result = Math.sqrt(this.setComponent.number1);this.setText(result);this.addHistory();// 恢复初始化this.clearNunber(false, false);}}private void addHistory() {this.setComponent.calcState = true;if (this.setComponent.isFloat) {double a = this.setComponent.number1;String b = "";if (!this.setComponent.algo.equals("√")) {b = Double.toString(this.setComponent.number2);}String text = "\n" + a + this.setComponent.algo + b + "=" + this.setComponent.jTextField1.getText();this.setComponent.jTextArea1.setText(this.setComponent.jTextArea1.getText() + text);} else {int a = (int) Math.round(this.setComponent.number1);String b = "";if (!this.setComponent.algo.equals("√")) {b = Integer.toString((int)Math.round(this.setComponent.number2));}String text = "\n" + a + this.setComponent.algo + b + "=" + this.setComponent.jTextField1.getText();this.setComponent.jTextArea1.setText(this.setComponent.jTextArea1.getText() + text);}}private void addHistory(String text) {this.setComponent.jTextArea1.setText(this.setComponent.jTextArea1.getText() + text);}@Overridepublic void actionPerformed(ActionEvent e) {String name = e.getActionCommand();String numberS = "1234567890";String funcS = "÷*-+√%";String text = this.setComponent.jTextField1.getText();// 清除内容if (name.equals("C")) {this.clearNunber(true, true);}// 加减乘除if (funcS.contains(name)) {if (this.setComponent.jTextField1.getText().length() == 0 && name.equals("-")) {this.setComponent.jTextField1.setText("-");} else {this.setComponent.jTextField1.setText("");}if (this.setComponent.calcState) {this.setComponent.number1State = true;this.setComponent.number1 = Double.parseDouble(text);}if (this.setComponent.number1State) {this.setComponent.algo = name;this.setComponent.selectNumber = 2;}}// 小数点if (name.equals(".")) {// 判断是否已经存在小数点if (!text.contains(".") && text.length() > 0) {this.setComponent.jTextField1.setText(text + ".");}this.setComponent.isFloat = true;}// 删除最后一个字符if (name.equals("Del")) {if (text.length() > 0) {String newText = text.substring(0, text.length()-1);this.setComponent.jTextField1.setText(newText);}}// 判断等于号if (name.equals("=")) {// 计算try {this.calcNumber();} catch (Throwable ex) {String textError = "\n【系统错误】程序运行发生错误\n【错误信息】" + ex + "\n【计算参数】" + this.setComponent.number1 + this.setComponent.algo + this.setComponent.number2 + "\n【联系方式】请将该情况反馈给管理员处理!Smobee";System.out.println(textError);addHistory(textError);JOptionPane.showMessageDialog(null, textError, "系统报错 " + "可联系管理员处理 Smobee", JOptionPane.ERROR_MESSAGE);}}// 判断按键0~9if (numberS.contains(name)) {// 判断是不是超过10位if (text.length() >= 10) {JOptionPane.showMessageDialog(null,"暂时不支持超过10位数字的计算");return;}// 判断如果当前已经为0,输入0,则不继续增加if(text.equals("0")) {return;}// 判断是不是结束了计算状态if (this.setComponent.calcState) {this.setComponent.jTextField1.setText("");this.setComponent.calcState = false;}// 获取当前文本框的值String text3 = this.setComponent.jTextField1.getText();this.setComponent.jTextField1.setText(text3 + name);String text1 = this.setComponent.jTextField1.getText();// 判断是第一个数字,还是第二个数字if (this.setComponent.selectNumber == 1) {this.setComponent.number1State = true;this.setComponent.number1 = Double.parseDouble(text1);} else if (this.setComponent.selectNumber == 2) {this.setComponent.number2State = true;this.setComponent.number2 = Double.parseDouble(text1);}}}
}

九、异常处理

我在计算的关键地方,加了异常处理,这样的话,程序就不会闪退,并且提示用户

// 判断等于号
if (name.equals("=")) {// 计算try {this.calcNumber();} catch (Throwable ex) {String textError = "\n【系统错误】程序运行发生错误\n【错误信息】" + ex + "\n【计算参数】" + this.setComponent.number1 + this.setComponent.algo + this.setComponent.number2 + "\n【联系方式】请将该情况反馈给管理员处理!Smobee";System.out.println(textError);addHistory(textError);JOptionPane.showMessageDialog(null, textError, "系统报错 " + "可联系管理员处理 Smobee", JOptionPane.ERROR_MESSAGE);}
}

在这里插入图片描述

十、exe4j Wizard 使用生成exe

1. 先在 IntelliJ IDEA 安装Handy Export Jar在这里插入图片描述

2. 然后导出为jar包

在这里插入图片描述

通过jar包,我们就可以直接生成exe文件

在这里插入图片描述

3. 打开exe4j Wizard

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

最后一步,生成exe

在这里插入图片描述

在这里插入图片描述

可以直接打开

在这里插入图片描述


更新日志

提示:将会持续优化更新

相关内容

热门资讯

山东省司法厅多维度发力让法律援... 法律援助法实施以来,山东省各级司法行政机关和法律援助机构锚定落地见效目标,推动法律援助惠及更多群众。...
河南:扩大生育保险保障范围 落... 河南印发《河南省加快完善生育支持政策体系推动建设生育友好型社会若干政策措施》,措施提出,扩大生育 保...
龙建股份:董事会将综合考虑国内... 有投资者在互动平台向龙建股份提问:“贵公司大股东建投集团下属建筑安装集团中标哈尔滨冰雪大世界工程,贵...
汇金股份:子公司提起3449万... 12月22日,汇金股份(300368)发布公告,控股子公司深圳市汇金天源数字技术有限公司已向福州世纪...
多岗位招聘“限男性”!一地人社... 安徽省马鞍山市当涂县一网络招聘服务网站发布的信息中,多个岗位存在“限男性”等性别歧视性内容,当地检察...
一次性信用修复政策来了!这些法... 今天(22日),中国人民银行发布通知,实施一次性信用修复政策,支持信用受损但积极还款的个人高效便捷重...
“重庆调解在线”数字应用累计办... 12月19日,市人大监察司法委、市政协社法委和市司法局举办2025年联合开放日暨调研活动。据了解,本...
京尹律所律师王亭玉、刘杉代理侵... 01 基本案情 武汉某传媒公司是一家主要从事广告设计、动画设计、信息咨询、网络运营、数据处理等为主...
云南城投董事会通过内部机构调整... 观点网讯:12月22日,云南城投置业股份有限公司召开第十届董事会第三十八次会议。 会议审议并通过了三...