目录

界面的设计:

事件的响应:

计算:

详细代码如下:

总结:


要制作一个简单的计算器,首先就是对于界面的设计,然后就是其功能的实现。

对于事件的实现大概就分下面几个步骤。

  1. 确定事件源和监听源
  2. 实现监听器的接口
  3. 将事件源注册到监听器

然后就一起进入代码的编写吧,我是分成了几个发放来编写功能,最后有最终的代码,可以直接运行,这要注意的是,直接粘贴的话,类名和文件名要一样哦。

界面的设计:

他最上面是要有一个文本框,中间要有很多的按钮,我这里大的框架是采用BorderLayout类布局管理器,其中他的NORTH(容器顶部)是添加了一个FlowLayout类布局管理器,FlowLayout里面是一个文本框,CENTER(容器的中间)是添加了一个GirdLayout类布局管理器,形成网格状的按钮,WEST(容器的左侧),EAST(容器的右侧),SOUTH(容器底部),这些是通过添加一个空白的标签来占位置的,让界面更加好看一点。

 //创建显示器面板,采用默认的流布局final JPanel viewPanel =new JPanel();//创建显示器final JTextField textField=new JTextField();//创建按钮面板final JPanel buttonPanel=new JPanel();//创建网络布局管理器对象final GridLayout gridLayout=new GridLayout(0,4);//按钮里面的内容String [][]names= {{"**","ln","lg","clear"},{"sin","cos","tan","X"},{"PI","//","%","/"},{"7","8","9","*"},{"4","5","6","-"},{"1","2","3","+"},{"_/``","0",".","="}};//创建按钮对象JButton[][] buttons=new JButton[names.length][4];//创建左侧的占位标签final JLabel leftLabel=new JLabel();//创建右侧的占位标签final JLabel rightLabel=new JLabel();//创建下侧的占位标签final JLabel bottomLabel=new JLabel();
//初始化组件public void initModule() {//初始化显示器相关数据textField.setEditable(false);//设置显示器不可编辑textField.setHorizontalAlignment(SwingConstants.RIGHT);textField.setColumns(35);//调节文本框的宽度textField.setPreferredSize(new Dimension(500,40));//初始化面板按钮gridLayout.setVgap(10);//设置组件的水平间距gridLayout.setHgap(10);//设置组件的垂直间距//初始化按钮对象for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {buttons[row][col]=new JButton(names[row][col]);//创建按钮}}//设置左侧标签的宽度leftLabel.setPreferredSize(new Dimension(10,0));//设置右侧标签的宽度rightLabel.setPreferredSize(new Dimension(10,0));//设置底部标签的宽度,组件的有高度,可以没宽度,和两边相反bottomLabel.setPreferredSize(new Dimension(0,10));}
//初始化面板public void initPanel() {//初始化组件initModule();viewPanel.add(textField);viewPanel.setPreferredSize(new Dimension(100,80));this.getContentPane().add(viewPanel,BorderLayout.NORTH);buttonPanel.setLayout(gridLayout);//按钮面板采用网络布局this.getContentPane().add(buttonPanel,BorderLayout.CENTER);//将按钮面板添加到窗体中间//把按钮添加到按钮面板中,虽然可以和初始化按钮写一起,但是便于理解还是把他们分开写了for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {buttonPanel.add(buttons[row][col]);}}this.getContentPane().add(leftLabel,BorderLayout.WEST);this.getContentPane().add(rightLabel,BorderLayout.EAST);this.getContentPane().add(bottomLabel,BorderLayout.SOUTH);}
    //初始化窗体public void initFrame() {//设置窗体的标题this.setTitle("计算器");//设置窗体大小不可改变this.setResizable(false);//设置界面置顶(就是页面不会别其他页面覆盖,界面始终在最上面)this.setAlwaysOnTop(true);//设置窗体的位置和大小,位置应该失效了,因为设置了居中//this.setBounds(300,150,400,500);//那还是改成setSize吧,设置窗体的大小就行了this.setSize(400,500);//居中this.setLocationRelativeTo(null);//设置窗体关闭按钮的动作作为退出this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//将显示器面板添加到窗体顶部this.getContentPane().add(viewPanel,BorderLayout.NORTH);}

遇到的问题:

问题1:上层的文本框的大小的宽度设置不了,然后一直没有变化。

解决:通过修改setColumns();调节成功了,这个我还不知道原理,有知道的希望大家可以告诉我呢,之前一直在修改setPreferredSize();然后没反应,修改流布局管理器也只是把空白的地方变多了。

问题2:底部宽度bottomLabel.setPreferredSize(new Dimension(10,0));用这个修改没反应。

解决:这个当然不会有反应,添加加底部的宽是10,高是0,结果当然不会显示,之前偷懒直接复制左右侧的导致没显示,所以应该是bottomLabel.setPreferredSize(new Dimension(0,10));才对。

事件的响应:

具体的方法就看方法内部的调用吧,有应该都有写方法的作用的,接下来就是确定事件源和监听源,我是打算通过键盘输入一些字符和通过鼠标点击按钮来实现。

1.确定事件源和监听源

事件源:JButton[][] buttons=new JButton[names.length][4];按钮,和自己本身框架

监听源:ActionListener,KeyListener

2.实现监听器的接口

//重写鼠标点击事件@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJButton button =(JButton)e.getSource();//获得触发此次动作事件的按钮对象String buttonName =e.getActionCommand();//获得触发此次动作事件的按钮的标签文本if(buttonName.equals("X")) {//没有字符串之后就不能删除了if(sb.length()!=0) {sb.deleteCharAt(sb.length()-1);//textField.setText(output);//删除之后还需要立即显示一次,不然没有反应}}else if(buttonName.equals("R")){//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//删除之后还需要立即显示一次,不然没有反应//textField.setText(output);}else if(buttonName.equals("=")) {//计算结果result();}else {sb.append(buttonName);//textField.setText(output);}//反正每次响应事件之后都要更新,干脆直接放在最后outPut();//要重新使框架获得焦点,这要写呢,不写就按下按钮之后键盘就没反应了if(buttonName.equals("=")) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}this.requestFocus();}
            @Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}//按着按键不松时调用@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}//按键松开后执行@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub//System.out.println("我被调用了啦");int code = e.getKeyCode();//输出每次按下的键盘按钮对应的code//System.out.println(code);//用键盘添加数字//单纯输入数字,shift键没有被按下,不然就加减乘除无法被响应了if(code>=48 && code<=57 && !e.isShiftDown()) {sb.append((char)code);//outPut();}else if(code==56 && e.isShiftDown()) {sb.append("*");//outPut();}else if(code==47 && !e.isShiftDown()) {sb.append("/");}else if(code==8) {//Backspace键//删除最后的一个字符sb.deleteCharAt(sb.length()-1);}else if(code==53 && e.isShiftDown()) {sb.append("%");}else if(code==61 && e.isShiftDown()) {sb.append("+");}else if(code==61 && !e.isShiftDown()) {//"="//计算结果result();}else if(code==45 && !e.isShiftDown()) {sb.append("-");}else if(code==46 && !e.isShiftDown()) {sb.append(".");}else if(code==10) {//Enter键//计算结果result();}//每次键盘输入之后都要更新,所以干脆就直接放判断最后outPut();//"="和"Enter"键if(code==61 && !e.isShiftDown()||code==10) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}}}

3.将事件源注册到监听器

public void buttonAction() {//按钮绑定动作事件,和自己绑定,自己实现的监听的方法for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {(buttons[row][col]).addActionListener(this);}}  //给整个界面添加键盘监听事件this.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}//按着按键不松时调用@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}//按键松开后执行@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub//System.out.println("我被调用了啦");int code = e.getKeyCode();//输出每次按下的键盘按钮对应的code//System.out.println(code);//用键盘添加数字//单纯输入数字,shift键没有被按下,不然就加减乘除无法被响应了if(code>=48 && code<=57 && !e.isShiftDown()) {sb.append((char)code);//outPut();}else if(code==56 && e.isShiftDown()) {sb.append("*");//outPut();}else if(code==47 && !e.isShiftDown()) {sb.append("/");}else if(code==8) {//Backspace键//删除最后的一个字符sb.deleteCharAt(sb.length()-1);}else if(code==53 && e.isShiftDown()) {sb.append("%");}else if(code==61 && e.isShiftDown()) {sb.append("+");}else if(code==61 && !e.isShiftDown()) {//"="//计算结果result();}else if(code==45 && !e.isShiftDown()) {sb.append("-");}else if(code==46 && !e.isShiftDown()) {sb.append(".");}else if(code==10) {//Enter键//计算结果result();}//每次键盘输入之后都要更新,所以干脆就直接放判断最后outPut();//"="和"Enter"键if(code==61 && !e.isShiftDown()||code==10) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}}});}public void buttonAction() {//按钮绑定动作事件,和自己绑定,自己实现的监听的方法for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {(buttons[row][col]).addActionListener(this);}}   //给整个界面添加键盘监听事件this.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}//按着按键不松时调用@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}//按键松开后执行@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub//System.out.println("我被调用了啦");int code = e.getKeyCode();//输出每次按下的键盘按钮对应的code//System.out.println(code);//用键盘添加数字//单纯输入数字,shift键没有被按下,不然就加减乘除无法被响应了if(code>=48 && code<=57 && !e.isShiftDown()) {sb.append((char)code);//outPut();}else if(code==56 && e.isShiftDown()) {sb.append("*");//outPut();}else if(code==47 && !e.isShiftDown()) {sb.append("/");}else if(code==8) {//Backspace键//删除最后的一个字符sb.deleteCharAt(sb.length()-1);}else if(code==53 && e.isShiftDown()) {sb.append("%");}else if(code==61 && e.isShiftDown()) {sb.append("+");}else if(code==61 && !e.isShiftDown()) {//"="//计算结果result();}else if(code==45 && !e.isShiftDown()) {sb.append("-");}else if(code==46 && !e.isShiftDown()) {sb.append(".");}else if(code==10) {//Enter键//计算结果result();}//每次键盘输入之后都要更新,所以干脆就直接放判断最后outPut();//"="和"Enter"键if(code==61 && !e.isShiftDown()||code==10) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}}});}

问题3:因为没有响应之后都要有对应的应答,有时候要输出,但是输入的按钮有些是含义多个字符的字符串,在计算和删除的时候删除的是单个的字符不是整个的字符串,比如sin输入的是“sin”删除只能删除最后的'n’。

解决:我这里是用到了HashMap来解决,在程序里面是单个的字符,输出是输出字符表示的字符串,这样删除计算等操作都方便了。

问题4:键盘输入对于*,+等的字符无法得到。

解决:我是通过 e.getKeyCode();来得到键盘输入的code,但是对于*和8是同一个code,都是56,不同的是shift键是否按下,之前是想写在 keyPressed里面来响应,但是感觉也实现不来,后面就是看到了e.isShiftDown();来判断shift键是否按下,也确实抱着试一试的态度,结果发现还真可以,就加上了e.isShiftDown();的判断。就解决了'*'和'8'有相同code的情况。

 //按钮里面的内容String [][]names= {{"**","ln","lg","clear"},{"sin","cos","tan","X"},{"PI","//","%","/"},{"7","8","9","*"},{"4","5","6","-"},{"1","2","3","+"},{"_/``","0",".","="}};//程序里面的内容String [][]target= {{"A","N","G","R"},{"S","C","T","X"},{"P","B","%","/"},{"7","8","9","*"},{"4","5","6","-"},{"1","2","3","+"},{"D","0",".","="}};    //用来对应文本框的输出,还是选择用HashMap来存储Map<String ,String>map=new HashMap<String,String>();//通过哈希表实现输出字符串和里面的字符串的不同标识public void Stringbind() {//map.put(getWarningString(), getName())for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {map.put(target[row][col], names[row][col]);//System.out.println("执行成功");}}//用来判断值有没有填写进去//System.out.println(map.size());}

问题5:在查找的时候输出的是null,不是目标的字符串。

解决:这我找了挺久的,最后还看了HashMap里面的元素有多少,发现是存进去的,问题出现在字符串“A”和'A'不是一样的东西,所以哈希表没找到。

输出是通过一个函数来实现

    //用来更新文本框输出的字符串StringBuffer sb=new StringBuffer();//用来对应文本框的输出,还是选择用HashMap来存储Map<String ,String>map=new HashMap<String,String>();//输出的字符串放这个里面,每次使用都需要清零哈String output="";//记录每次将输出的字符串public void outPut() {output="";for(int i=0;i<sb.length();i++) {//这我可能知道原因了,字符串"A"和'A'不一样output= output+map.get(String.valueOf(sb.charAt(i)));}//每次更新都要输出,我直接写到方法里面算了textField.setText(output);}

问题6:键盘的输入失灵。

解决:要通过聚焦,才能实现,调用this.setFocusable(true);

问题7:开始输入可以通过键盘输出,但是在按下面板中的按钮之后键盘无法输入。

解决:在每次按下按钮之后重新聚焦this.requestFocus();要重新使框架获得焦点,这要写呢,不写就按下按钮之后键盘就没反应了。

最后就是计算器功能实现的部分了,比较好实现的就是除‘=’号的按钮,直接添加到字符串里面,在最后打印就行。我这里采用的是StringBuffer因为要添加和更新什么的。

删除按钮和清空按钮分别就是删除字符串最后一个字符和删除字符串所有的字符。

//删除最后一个字符
if(sb.length()!=0) {sb.deleteCharAt(sb.length()-1);//textField.setText(output);//删除之后还需要立即显示一次,不然没有反应
}
//删除所有的字符,确定是范围是[0,length)
sb.delete(0, sb.length());

问题8:按下按钮之后没有显示删除。

解决:这个是因为没有显示,在程序中已经删除了,但是呢,用户看到是还没删除的样子,所以还是要更新一下输出。

计算:

接下来就是最后的计算环节了。

首先确定计算的优先级,我这里没有引入括号了,所以把lg,ln,sin,cos,tan,开根号都是和右边的操作数看成一个整体的。

字符串的运算就是通过运算符来分割,通过寻找到他的运算数,进行运算,把运算结果的字符串和运算前的字符串进行替换即可。

    //计算每次的结果public void result() {//对应关系//**--->A  ln--->N  lg--->G  sin--->S   cos--->C//tan--->T  PI--->P  //--->B  /``--->D//计算是按照优先级来的//PI不算运算,直接填进去吧//也不行,本来就是用一个符号来表示,这突然变成一长串数字,那还是运算的时候展开吧//展开PItry {pi();//ln,lg,sin,cos,tan,开根号的运算special();//乘方运算power();//乘除,整除,求余运算multiplyDivide();//加减计算addAndSubtract();}catch(Exception e) {//弹出警告的弹窗warning();}finally {System.out.println("今天又是元气满满的一天");}}

PI就是一个替换,把PI在计算的时候换成Math.PI就行了,因为我用哈希表的初衷就是希望在程序中字符串是用一个的字符表示,所以PI我是在计算的时候才进行展开。

    //展开PIpublic void pi() {for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='P') {double res=Math.PI;String resString=res+"";//更新字符串sb=sb.replace(i, i+1, resString);i=resString.length()-1;continue;}}}

这些我不是用什么名字,就用这个表示了,这些的特点就是只需要一个操作数即可。

所以只需要往右边找操作数,统计操作数的长度,把找到的数进行相应的修改和替换。

问题9:sin和tan不好用,用PI直接报错了。

解决:这个弧度制好像是越界了,我又没加括号,那还是Math.toRadians(num)输入角度制转成弧度制来运算吧。

//ln,lg,sin,cos,tan,开根号的运算public void special() {//都是用右边一个操作数的运算for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='N'||sb.charAt(i)=='G'||sb.charAt(i)=='S'||sb.charAt(i)=='C'||sb.charAt(i)=='T'||sb.charAt(i)=='D') {double num=0;int len=0;//记录字符串长度,之后还要进行字符串的替换呢//只需要应该一边的数字即可for(int j=i+1;j<sb.length();j++) {//是j不是i,咋又错在这里了if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'||sb.charAt(j)=='A'||sb.charAt(j)=='N'||sb.charAt(j)=='G'||sb.charAt(j)=='S'||sb.charAt(j)=='C'||sb.charAt(j)=='T'||sb.charAt(j)=='D') {String s1=sb.substring(i+1,j);num=Double.parseDouble(s1);len=s1.length();break;}//找到最右边咯,中间没有运算符那也要停止了if(j==sb.length()-1) {//这边是到j+1哈,找错误找了半天//如果右边是一位的数字,就会导致运算是数是空//如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)String s1=sb.substring(i+1,j+1);num=Double.parseDouble(s1);len=s1.length();break;}}//进行运算//ln运算if(sb.charAt(i)=='N') {double res=Math.log(num);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//lg运算if(sb.charAt(i)=='G') {//换底公式double res=Math.log(num)/Math.log(10);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//sin运算if(sb.charAt(i)=='S') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.sin(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//cos运算if(sb.charAt(i)=='C') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.cos(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//tan运算if(sb.charAt(i)=='T') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.tan(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//开根号运算if(sb.charAt(i)=='D') {double res=Math.sqrt(num);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}}}}

接下来就是两个操作数的啦。以乘方为例。

往左边和右边寻找操作数,左边的话需要考虑优先级低的操作字符以及字符串越界的情况,但是右边不仅是需要考虑这个还需要考虑本身这个字符。

就是往左边判断是(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'),而右边判断是(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'||sb.charAt(j)=='A'),这也要理解吧,因为字符串吧遍历是从左往右,右边还有这个‘A’没有判断,但是左边已经判断结束了。

    //乘方运算public void power(){for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='A') {double num1=0,num2=0;int len1=0,len2=0;//记录字符串长度,之后还要进行字符串的替换呢for(int j=i-1;j>=0;j--) {//得到第一个操作数,遇到加减乘除就停止了,相当于分隔了操作数if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-') {String s1=sb.substring(j+1,i);num1=Double.parseDouble(s1);len1=s1.length();break;}//找到边界了,只能停止了咯if(j==0) {String s1=sb.substring(j,i);num1=Double.parseDouble(s1);len1=s1.length();break;}}//往右边找第二个操作数,第二个操作数的话遇到乘除也需要提前终止,第一个不需要//因为如果第一个操作数有乘除这种符号,就已经提前终止了,只有第二个操作数才需要考虑for(int j=i+1;j<sb.length();j++) {if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'||sb.charAt(j)=='A') {String s1=sb.substring(i+1,j);num2=Double.parseDouble(s1);len2=s1.length();break;}//找到最右边咯,中间没有运算符那也要停止了if(j==sb.length()-1) {//这边是到j+1哈,找错误找了半天//如果右边是一位的数字,就会导致运算是数是空//如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)String s1=sb.substring(i+1,j+1);num2=Double.parseDouble(s1);len2=s1.length();break;}}//进行运算double res=Math.pow(num1, num2);String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}}}

加减乘除就和这个一样了。

问题10:会出现多个异常抛出的情况。

解答:循环里面操作数的判断,里面是sb.charAt(j)写成了sb.charAt(i);第二种就是在第二个操作数边界判断的时候String s1=sb.substring(i+1,j+1);写成了String s1=sb.substring(i+1,j);这也是直接复制前面的结果,因为之前停止是遇到运算符停止的,所以边界判断不需要考虑到j+1,但是这已经到底了,指针指向的就是数,如果右边是一位的数字,就会导致运算是数是空,如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)。

运算解决了,就是对异常的处理,之前的代码就有显示我加入了抛出异常的地方,如果错误是会出现一个弹窗。我还用finally来检验程序的健壮性。本来是对除数为0的情况加上了一个判断,因为是浮点数所以为0的判断条件设置成Math.abs(num2)<=1e-6,但是他没反应了,我干脆就直接不判断了这也算是异常,直接抛出弹出弹窗就行了。这还是方便一点。

注:这里有一个bug,因为操作数我最开始是设置成0,就导致如果只有一个数的时候也可以运算,比如“*1”是可以运行的,因为num1等于0,这个大家感兴趣可以自己完善一下哈

 //警告标签,放在弹窗里面final JLabel warningLabel=new JLabel();//警告,输入不合法的时候弹出public void warning() {JDialog jDialog=new JDialog();//创建弹窗对象jDialog.setTitle("警告");//设置弹窗标题,和Frame差不多,可能还要通过标签来提示jDialog.setSize(500,600);//设置弹窗的大小jDialog.setAlwaysOnTop(true);//让弹窗置顶jDialog.setLocationRelativeTo(null);//让弹窗居中jDialog.setModal(true);//弹窗不关闭则无法操作下面的界面//设置字体的类型,加粗,和大小warningLabel.setFont(new Font("Microsoft YaHei",Font.BOLD,30));//输出警告提示符warningLabel.setText("就是你小子在搞乱的是吧!!!");//标签的位置和大小warningLabel.setBounds(60,180,500,100);//这个也要取消布局管理器才行jDialog.getContentPane().setLayout(null);//往弹窗中添加标签jDialog.getContentPane().add(warningLabel);jDialog.setVisible(true);//让弹窗显示出来}

警告的弹窗和内容都是自己设计的,弹窗就和框架一样,里面也是一个面板,我取消了布局,通过x,y坐标的方法进行移动。弹窗弹出如下所示。

详细代码如下:

import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;public class CalculatorFrame extends JFrame implements ActionListener{//主方法public static void main(String[] args) {CalculatorFrame cf=new CalculatorFrame();}//创建显示器面板,采用默认的流布局final JPanel viewPanel =new JPanel();//创建显示器final JTextField textField=new JTextField();//创建按钮面板final JPanel buttonPanel=new JPanel();//创建网络布局管理器对象final GridLayout gridLayout=new GridLayout(0,4);//按钮里面的内容String [][]names= {{"**","ln","lg","clear"},{"sin","cos","tan","X"},{"PI","//","%","/"},{"7","8","9","*"},{"4","5","6","-"},{"1","2","3","+"},{"_/``","0",".","="}};//程序里面的内容String [][]target= {{"A","N","G","R"},{"S","C","T","X"},{"P","B","%","/"},{"7","8","9","*"},{"4","5","6","-"},{"1","2","3","+"},{"D","0",".","="}};//创建按钮对象JButton[][] buttons=new JButton[names.length][4];//创建左侧的占位标签final JLabel leftLabel=new JLabel();//创建右侧的占位标签final JLabel rightLabel=new JLabel();//创建下侧的占位标签final JLabel bottomLabel=new JLabel();//存储计算结果double result=0;//用来更新文本框输出的字符串StringBuffer sb=new StringBuffer();//用来对应文本框的输出,还是选择用HashMap来存储Map<String ,String>map=new HashMap<String,String>();//输出的字符串放这个里面,每次使用都需要清零哈String output="";//警告标签,放在弹窗里面final JLabel warningLabel=new JLabel();public CalculatorFrame(){//初始化窗体initFrame();//初始化面板initPanel();//初始化哈希表里面的数据Stringbind();//绑定事件.键盘绑定也放在里面buttonAction();//窗体可见,放最后吧,不然里面的东西不会显示呢this.setVisible(true);}//初始化窗体public void initFrame() {//设置窗体的标题this.setTitle("计算器");//设置窗体大小不可改变this.setResizable(false);//设置界面置顶(就是页面不会别其他页面覆盖,界面始终在最上面)this.setAlwaysOnTop(true);//设置窗体的位置和大小,位置应该失效了,因为设置了居中//this.setBounds(300,150,400,500);//那还是改成setSize吧,设置窗体的大小就行了this.setSize(400,500);//居中this.setLocationRelativeTo(null);//设置窗体关闭按钮的动作作为退出this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//将显示器面板添加到窗体顶部this.getContentPane().add(viewPanel,BorderLayout.NORTH);//添加屏幕焦点,没有这个用键盘输入没反应埃this.setFocusable(true);}//初始化面板public void initPanel() {//初始化组件initModule();viewPanel.add(textField);viewPanel.setPreferredSize(new Dimension(100,80));this.getContentPane().add(viewPanel,BorderLayout.NORTH);buttonPanel.setLayout(gridLayout);//按钮面板采用网络布局this.getContentPane().add(buttonPanel,BorderLayout.CENTER);//将按钮面板添加到窗体中间//把按钮添加到按钮面板中,虽然可以和初始化按钮写一起,但是便于理解还是把他们分开写了for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {buttonPanel.add(buttons[row][col]);}}this.getContentPane().add(leftLabel,BorderLayout.WEST);this.getContentPane().add(rightLabel,BorderLayout.EAST);this.getContentPane().add(bottomLabel,BorderLayout.SOUTH);}//初始化组件public void initModule() {//初始化显示器相关数据textField.setEditable(false);//设置显示器不可编辑textField.setHorizontalAlignment(SwingConstants.RIGHT);textField.setColumns(35);//调节文本框的宽度textField.setPreferredSize(new Dimension(500,40));//初始化面板按钮gridLayout.setVgap(10);//设置组件的水平间距gridLayout.setHgap(10);//设置组件的垂直间距//初始化按钮对象for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {buttons[row][col]=new JButton(names[row][col]);//创建按钮}}//静态的初始化设置一些,把多个单词的给标识起来/*buttons[0][0].setActionCommand("A");//"**"buttons[0][1].setActionCommand("N");//"ln"buttons[0][2].setActionCommand("G");//"lg"buttons[0][3].setActionCommand("R");//clearbuttons[1][0].setActionCommand("S");//sinbuttons[1][1].setActionCommand("C");//cosbuttons[1][2].setActionCommand("T");//tanbuttons[2][0].setActionCommand("P");//PTbuttons[2][1].setActionCommand("B");//"//"buttons[6][0].setActionCommand("D");//"+/-"*///还是用循环全部绑定吧,自己一个一个绑代码灵活性不高for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {buttons[row][col].setActionCommand(target[row][col]);}}//设置左侧标签的宽度leftLabel.setPreferredSize(new Dimension(10,0));//设置右侧标签的宽度rightLabel.setPreferredSize(new Dimension(10,0));//设置底部标签的宽度,组件的有高度,可以没宽度,和两边相反bottomLabel.setPreferredSize(new Dimension(0,10));}//通过哈希表实现输出字符串和里面的字符串的不同标识public void Stringbind() {//map.put(getWarningString(), getName())for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {map.put(target[row][col], names[row][col]);//System.out.println("执行成功");}}//用来判断值有没有填写进去//System.out.println(map.size());}public void buttonAction() {//按钮绑定动作事件,和自己绑定,自己实现的监听的方法for(int row=0;row<names.length;row++) {for(int col=0;col<names[row].length;col++) {(buttons[row][col]).addActionListener(this);}}    //给整个界面添加键盘监听事件this.addKeyListener(new KeyListener() {@Overridepublic void keyTyped(KeyEvent e) {// TODO Auto-generated method stub}//按着按键不松时调用@Overridepublic void keyPressed(KeyEvent e) {// TODO Auto-generated method stub}//按键松开后执行@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub//System.out.println("我被调用了啦");int code = e.getKeyCode();//输出每次按下的键盘按钮对应的code//System.out.println(code);//用键盘添加数字//单纯输入数字,shift键没有被按下,不然就加减乘除无法被响应了if(code>=48 && code<=57 && !e.isShiftDown()) {sb.append((char)code);//outPut();}else if(code==56 && e.isShiftDown()) {sb.append("*");//outPut();}else if(code==47 && !e.isShiftDown()) {sb.append("/");}else if(code==8) {//Backspace键//删除最后的一个字符sb.deleteCharAt(sb.length()-1);}else if(code==53 && e.isShiftDown()) {sb.append("%");}else if(code==61 && e.isShiftDown()) {sb.append("+");}else if(code==61 && !e.isShiftDown()) {//"="//计算结果result();}else if(code==45 && !e.isShiftDown()) {sb.append("-");}else if(code==46 && !e.isShiftDown()) {sb.append(".");}else if(code==10) {//Enter键//计算结果result();}//每次键盘输入之后都要更新,所以干脆就直接放判断最后outPut();//"="和"Enter"键if(code==61 && !e.isShiftDown()||code==10) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}}});}//重写鼠标点击事件@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJButton button =(JButton)e.getSource();//获得触发此次动作事件的按钮对象String buttonName =e.getActionCommand();//获得触发此次动作事件的按钮的标签文本if(buttonName.equals("X")) {//没有字符串之后就不能删除了if(sb.length()!=0) {sb.deleteCharAt(sb.length()-1);//textField.setText(output);//删除之后还需要立即显示一次,不然没有反应}}else if(buttonName.equals("R")){//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//删除之后还需要立即显示一次,不然没有反应//textField.setText(output);}else if(buttonName.equals("=")) {//计算结果result();}else {sb.append(buttonName);//textField.setText(output);}//反正每次响应事件之后都要更新,干脆直接放在最后outPut();//要重新使框架获得焦点,这要写呢,不写就按下按钮之后键盘就没反应了if(buttonName.equals("=")) {//就是把[0,length)的内容删除即可sb.delete(0, sb.length());//结果出来之后就是重新输入计算下一个}this.requestFocus();}//记录每次将输出的字符串public void outPut() {output="";for(int i=0;i<sb.length();i++) {//这我可能知道原因了,字符串"A"和'A'不一样output= output+map.get(String.valueOf(sb.charAt(i)));}//每次更新都要输出,我直接写到方法里面算了textField.setText(output);}//计算每次的结果public void result() {//对应关系//**--->A  ln--->N  lg--->G  sin--->S   cos--->C//tan--->T  PI--->P  //--->B  /``--->D//计算是按照优先级来的//PI不算运算,直接填进去吧//也不行,本来就是用一个符号来表示,这突然变成一长串数字,那还是运算的时候展开吧//展开PItry {pi();//ln,lg,sin,cos,tan,开根号的运算special();//乘方运算power();//乘除,整除,求余运算multiplyDivide();//加减计算addAndSubtract();}catch(Exception e) {//弹出警告的弹窗warning();}finally {System.out.println("今天又是元气满满的一天");}}//展开PIpublic void pi() {for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='P') {double res=Math.PI;String resString=res+"";//更新字符串sb=sb.replace(i, i+1, resString);i=resString.length()-1;continue;}}}//ln,lg,sin,cos,tan,开根号的运算public void special() {//都是用右边一个操作数的运算for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='N'||sb.charAt(i)=='G'||sb.charAt(i)=='S'||sb.charAt(i)=='C'||sb.charAt(i)=='T'||sb.charAt(i)=='D') {double num=0;int len=0;//记录字符串长度,之后还要进行字符串的替换呢//只需要应该一边的数字即可for(int j=i+1;j<sb.length();j++) {//是j不是i,咋又错在这里了if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'||sb.charAt(j)=='A'||sb.charAt(j)=='N'||sb.charAt(j)=='G'||sb.charAt(j)=='S'||sb.charAt(j)=='C'||sb.charAt(j)=='T'||sb.charAt(j)=='D') {String s1=sb.substring(i+1,j);num=Double.parseDouble(s1);len=s1.length();break;}//找到最右边咯,中间没有运算符那也要停止了if(j==sb.length()-1) {//这边是到j+1哈,找错误找了半天//如果右边是一位的数字,就会导致运算是数是空//如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)String s1=sb.substring(i+1,j+1);num=Double.parseDouble(s1);len=s1.length();break;}}//进行运算//ln运算if(sb.charAt(i)=='N') {double res=Math.log(num);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//lg运算if(sb.charAt(i)=='G') {//换底公式double res=Math.log(num)/Math.log(10);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//sin运算if(sb.charAt(i)=='S') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.sin(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//cos运算if(sb.charAt(i)=='C') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.cos(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//tan运算if(sb.charAt(i)=='T') {//还是采用角度制吧,弧度制取值用PI越界了,如果要除的话要加入括号的机制//偷懒一下就用角度值吧,不用加入括号double res=Math.tan(Math.toRadians(num));String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}//开根号运算if(sb.charAt(i)=='D') {double res=Math.sqrt(num);String resString=res+"";//更新字符串sb=sb.replace(i, i+len+1, resString);i=resString.length()-1;continue;}}}}//乘方运算public void power(){for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='A') {double num1=0,num2=0;int len1=0,len2=0;//记录字符串长度,之后还要进行字符串的替换呢for(int j=i-1;j>=0;j--) {//得到第一个操作数,遇到加减乘除就停止了,相当于分隔了操作数if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-') {String s1=sb.substring(j+1,i);num1=Double.parseDouble(s1);len1=s1.length();break;}//找到边界了,只能停止了咯if(j==0) {String s1=sb.substring(j,i);num1=Double.parseDouble(s1);len1=s1.length();break;}}//往右边找第二个操作数,第二个操作数的话遇到乘除也需要提前终止,第一个不需要//因为如果第一个操作数有乘除这种符号,就已经提前终止了,只有第二个操作数才需要考虑for(int j=i+1;j<sb.length();j++) {if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-'||sb.charAt(j)=='A') {String s1=sb.substring(i+1,j);num2=Double.parseDouble(s1);len2=s1.length();break;}//找到最右边咯,中间没有运算符那也要停止了if(j==sb.length()-1) {//这边是到j+1哈,找错误找了半天//如果右边是一位的数字,就会导致运算是数是空//如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)String s1=sb.substring(i+1,j+1);num2=Double.parseDouble(s1);len2=s1.length();break;}}//进行运算double res=Math.pow(num1, num2);String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}}}//乘除,整除,求余运算public void multiplyDivide() {for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='*'||sb.charAt(i)=='/'||sb.charAt(i)=='%'||sb.charAt(i)=='B') {double num1=0,num2=0;int len1=0,len2=0;//记录字符串长度,之后还要进行字符串的替换呢for(int j=i-1;j>=0;j--) {//得到第一个操作数,遇到加减就停止了,相当于分隔了操作数if(sb.charAt(j)=='+'||sb.charAt(j)=='-') {String s1=sb.substring(j+1,i);num1=Double.parseDouble(s1);len1=s1.length();break;}//找到边界了,只能停止了咯if(j==0) {String s1=sb.substring(j,i);num1=Double.parseDouble(s1);len1=s1.length();break;}}//往右边找第二个操作数,第二个操作数的话遇到乘除也需要提前终止,第一个不需要//因为如果第一个操作数有乘除这种符号,就已经提前终止了,只有第二个操作数才需要考虑for(int j=i+1;j<sb.length();j++) {if(sb.charAt(j)=='*'||sb.charAt(j)=='/'||sb.charAt(j)=='%'||sb.charAt(j)=='B'||sb.charAt(j)=='+'||sb.charAt(j)=='-') {String s1=sb.substring(i+1,j);num2=Double.parseDouble(s1);len2=s1.length();break;}//找到最右边咯,中间没有运算符那也要停止了if(j==sb.length()-1) {//这边是到j+1哈,找错误找了半天//如果右边是一位的数字,就会导致运算是数是空//如果右边是多位的数字,那么最右边的数不会参与运算,所以需要[i+1,j+1)String s1=sb.substring(i+1,j+1);num2=Double.parseDouble(s1);len2=s1.length();break;}}//进行运算if(sb.charAt(i)=='*') {double res=num1*num2;String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}if(sb.charAt(i)=='/') {//除数不能为0,有异常抛出的弹窗了,就去掉这个了/*if(Math.abs(num2)<=1e-6) {System.out.println("输出警告");continue;}*/double res=num1/num2;String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}if(sb.charAt(i)=='%') {//整数才能求余,第二个操作数也不能为0/*if(Math.abs(num2)<=1e-6) {System.out.println("输出警告");continue;}*///是求余%double res=(int)num1%(int)num2;String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}if(sb.charAt(i)=='B') {//整数的运算//除数不能为0/*if(Math.abs(num2)<=1e-6) {System.out.println("输出警告");continue;}*/double res=(int)num1/(int)num2;String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}}}}//加减运算public void addAndSubtract() {for(int i=0;i<sb.length();i++) {if(sb.charAt(i)=='+'||sb.charAt(i)=='-') {//运算符两边的操作数double num1=0,num2=0;//记录两个操作数的字符串长度int len1=0,len2=0;//寻找第一个操作数for(int j=i-1;j>=0;j--) {if(j==0) {String s1=sb.substring(j,i);//得到第一个操作数num1=Double.parseDouble(s1);len1=s1.length();break;}}for(int j=i+1;j<sb.length();j++) {if(sb.charAt(j)=='+'||sb.charAt(j)=='-') {String s1=sb.substring(i+1,j);//得到第二个操作数num2=Double.parseDouble(s1);len2=s1.length();break;}if(j==sb.length()-1) {String s1=sb.substring(i+1,j+1);num2=Double.parseDouble(s1);len2=s1.length();break;}}//进行加运算if(sb.charAt(i)=='+') {double res=num1+num2;//String s2=sb.substring(i-len1,i+len2+1);//String s3=res+ "";//sb=sb.replace(s2, s3);String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}//进行减运算if(sb.charAt(i)=='-') {double res=num1-num2;String resString=res+"";//更新字符串sb=sb.replace(i-len1, i+len2+1, resString);i=i-len1-1+resString.length();continue;}}}}//警告,输入不合法的时候弹出public void warning() {JDialog jDialog=new JDialog();//创建弹窗对象jDialog.setTitle("警告");//设置弹窗标题,和Frame差不多,可能还要通过标签来提示jDialog.setSize(500,600);//设置弹窗的大小jDialog.setAlwaysOnTop(true);//让弹窗置顶jDialog.setLocationRelativeTo(null);//让弹窗居中jDialog.setModal(true);//弹窗不关闭则无法操作下面的界面//设置字体的类型,加粗,和大小warningLabel.setFont(new Font("Microsoft YaHei",Font.BOLD,30));//输出警告提示符warningLabel.setText("就是你小子在搞乱的是吧!!!");//标签的位置和大小warningLabel.setBounds(60,180,500,100);//这个也要取消布局管理器才行jDialog.getContentPane().setLayout(null);//往弹窗中添加标签jDialog.getContentPane().add(warningLabel);jDialog.setVisible(true);//让弹窗显示出来}
}

总结:

这写下来还是写了挺长的时间了,目前还是比较满意的,因为是刚学JAVA语言,所以有很多地方都没太弄懂,有错误的地方,希望大家能够指正。对于计算器的功能编写其实还是能够添加很多功能也可以把Math.E添加进去,进行其他运算,大家可以根据自己的需求进行编写。写这个我的感受就是就是把我学的东西都用到了哈希表,异常抛出,控件都用上了,我对于他有一个比较清晰的认识,他要实现什么功能,虽然看着简单,但是卡在了很多地方,还有到处找资料来分析他的原因,尽管是有点简陋,我还加入了一些自己的东西,按下Backspace键和Enter键也有对应的响应,这也是努力的结果,希望未来越来越好吧。

用Java制作简单的计算器相关推荐

  1. JAVA制作简单的计算器

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

  2. Java制作简单小画板

    Java制作简单画板,包括两个类,一个主要画板类Drawpad,一个画板监听器DrawListener类. 1.Drawpad类,包括画板,画板功能设计,保存图片等 package Java课程设计; ...

  3. java仿windows7计算器界面,java制作仿win7计算器之一计算器的图形界面的设计

    再结合网上各路神人及之前写的博客Swing编程方面步骤,如下: package calPack; import javax.swing.*; import java.awt.*; import jav ...

  4. 用Java实现简单的计算器

    用Java实现简单的计算器 ​ 本计算器实现了最简单的四则运算,界面简洁,小伙伴可以根据自己的需要再此基础上进行修改,可拓展性强 效果图: 代码: public class Counter exten ...

  5. Java制作简单的单选和多选测试题

    Java制作简单的单选和多选测试题 题目: 定义考题类(Question)及其子类 完成考题类(Question),单选题(SingleChoice)和多选题(MultiChoice)是其子类 要求: ...

  6. Java实现简单的计算器(原创)

    初学Java中的Swing,写了一个简单的计算器,和大家分享一下! 支持键盘和鼠标操作 支持多个数运算.例如:输入1+2+3,结果是6! 源代码: import java.awt.*; import ...

  7. 【MATLAB-app】系列教程(含视频)第2课_实例:使用appdesigner 制作简单的计算器

    写作时间: 2020-12-24 我的教程目录 第1课:初步了解appdesigner 第2课:学会制作一个计算器 第3课:学习更多的控件 第4课:一个简单图像处理软件制作 第5课:学习APPdesi ...

  8. JAVA制作的简易计算器——傻瓜计算器

    用JAVA编写的傻瓜计算器 作用: 1.可以实现加法.减法.乘法.除法简单运算且是单一运算,不可混合使用. 2.CE为清除键 3.没有小数点O(∩_∩)O 思路: 创建JFrame窗口,设置标题,创建 ...

  9. 用Java制作简单的记事本

    目录 前言 主界面设计 功能实现 打开 另存为 保存 查找 替换 成员变量 其他方法 警告弹窗 不移动光标更新文本框内容 源代码 总结 转载请注明出处,尊重作者劳动成果. 前言 考完试想写敲一下代码就 ...

最新文章

  1. 科学家发现大脑动态评估信息重要性机制
  2. React App项目页面进出场动画
  3. python查看环境路径
  4. 一流投资人会关注什么样的区块链初创公司?
  5. 绿联 蓝牙适配器 linux,绿联蓝牙适配器
  6. HDU 6030 Happy Necklace
  7. ASP.NET MVC数据验证(上)
  8. Insertion Sort——打表找规律
  9. 在eclipse中指定启动时java的位置
  10. java类加载及new对象的过程
  11. 后台填充_单元格噩梦终于有救?500多行隔行填充,我就两步!
  12. iframe是什么?iframe用法详解。
  13. 赛马问题--最全面的解析
  14. java 小说系统_java 实现小说管理系统
  15. IBM FLEX刀箱忘记账号密码
  16. 皇太极有多宠爱宸妃海兰珠,从这三件事可以看出
  17. Adobe 认证证书怎么考
  18. google提供免费企业邮局
  19. SQL Server 异常 COM 类公司中CLSID 为 {10021F00-E260-11CF-AE68-00AA004A34D5} 的组件时失败,原因是出现以下错误: 80040154
  20. 大数据与云计算学习计划 (一) 云计算系统管理 6 Linux中RPM软件包管理操作 、 Yum软件包仓库操作(概念与实操)

热门文章

  1. java中的onresume_java – onActivityResult()之前调用onResume()?
  2. 【手把手教你薅羊毛(新闻APP)】
  3. 念白白 php,念白的四字精髓 :真、正、情、劲
  4. 推荐一部关于母亲的西语电影
  5. 如果外网访问不了ip主机记得关防火墙!血的教训
  6. linux 下卸载nginx的操作步骤
  7. 缓解电脑卡顿、释放内存的几种方法:
  8. 视频怎么做慢动作对比分析?视频动作分析软件哪个好?
  9. Oracle9i 自动管理PGA内存(zt)
  10. Subversion的安装与使用