📄 calculator.java
字号:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.math.BigDecimal;
public class Calculator extends MyDialog implements ActionListener
{
final int INIT =0, RUN = 1, ERROR = 2, ADD = 1, SUB = 2, MUL = 3, DIV = 4;
JTextField screen;
JButton button[] = new JButton[20];
JPanel panel;
String buttonName[] = { "7", "8", "9", "/", "C", "4", "5", "6", "×", "S",
"1", "2", "3", "-", "%", "0", ".", "←","+", "=" };
BigDecimal accumulator = new BigDecimal( 0 );//累加器
BigDecimal number = new BigDecimal( 0 );//第二个操作数
boolean decimal = false;//小数标记
int state = INIT, operate = INIT;//状态标记和操作标记
boolean countFinish = true, inputFinish = true;//计算完成标记和操作数输入完成标记
public Calculator(JFrame frame)
{
super(frame);
setTitle("计算器");
Container container = getContentPane();
screen = new JTextField();
screen.addKeyListener(
new KeyAdapter()
{
public void keyTyped( KeyEvent ke )
{
char ch = ke.getKeyChar();
JButton action = null;
switch( ch )
{
case '7': action = button[0];break;
case '8': action = button[1];break;
case '9': action = button[2];break;
case '/': action = button[3];break;
case '4': action = button[5];break;
case '5': action = button[6];break;
case '6': action = button[7];break;
case '*': action = button[8];break;
case '1': action = button[10];break;
case '2': action = button[11];break;
case '3': action = button[12];break;
case '-': action = button[13];break;
case '0': action = button[15];break;
case '.': action = button[16];break;
case '+': action = button[18];break;
default : action = null;
}
if( ke.getKeyChar() == KeyEvent.VK_ENTER ) action = button[19];
if( ke.getKeyChar() == KeyEvent.VK_BACK_SPACE ) action = button[17];
actionManage( action, ch + "" );
}
}
);
screen.setText( "0." );
screen.setHorizontalAlignment( JTextField.RIGHT );
screen.setBackground( Color.white );
screen.setEditable( false );
container.add( screen, BorderLayout.NORTH );
panel = new JPanel();
panel.setLayout( new GridLayout( 4, 5, 5, 5 ) );
for( int i = 0; i < buttonName.length; i ++ )
{
button[i] = new JButton( buttonName[i] );
button[i].addActionListener( this );
panel.add( button[i] );
}
container.add( panel, BorderLayout.CENTER );
setSize( 270, 190 );
setLocation();
}
public void actionPerformed( ActionEvent ae )
{
JButton action = ( JButton ) ae.getSource();
actionManage( action, ae.getActionCommand() );
screen.grabFocus();
}
private void actionManage( JButton action, String num )
{
if( !( state == ERROR && action != button[4] ) )
{//当状态是ERROR时,只有C按钮有效
stop1: for( int i = 0; i < button.length; i ++ )
{
if( action == button[i] )
{
switch( i )
{
case 3:///
manageOperation();
operate = DIV;
break stop1;
case 4://c
init();
break stop1;
case 8://*
manageOperation();
operate = MUL;
break stop1;
case 9://s
squareRoot();
break stop1;
case 13://-
manageOperation();
operate = SUB;
break stop1;
case 14://%
pressEquals();
if( operate == DIV )//只有除操作时%才有意义
{
accumulator = accumulator.movePointRight( 2 );
setScreenText( accumulator );
}
break stop1;
case 16://.
decimal = true;
break stop1;
case 17://<-只有刚输入的数据才可以退格
//当countFinish=true时说明显示为计算结果,不能退格
if( !countFinish ) backSpace();
break stop1;
case 18://+
manageOperation();
operate = ADD;
break stop1;
case 19://=
pressEquals();
break stop1;
default ://数字
pressNumber( num );
break stop1;
}
}
}
}
}
public void setVisible(boolean isVisible)
{
super.setVisible(isVisible);
if(isVisible) init();
}
private void init()
{
screen.setText( "0." );
operate = INIT;
state = INIT;
decimal = false;
accumulator = BigDecimal.valueOf( 0 );
number = BigDecimal.valueOf( 0 );
countFinish = true;
inputFinish = true;
}
private void squareRoot()
{
String result = screen.getText();
double num =Double.parseDouble( result );
if( num < 0 )
{
state = ERROR;
screen.setText( "负数不能开根号!" );
}
else
{
num = Math.sqrt( num );
result = num + "";
char ch = result.charAt( result.length() - 1 );
while( ch == '0' )
{
result = result.substring( 0, result.length() - 1 );
ch = result.charAt( result.length() - 1 );
}
screen.setText( result );
}
inputFinish = true;
}
private void pressEquals()
{
inputFinish = true;
decimal = false;
//当countFinish=false时说明计算没完成,屏幕显示为第二个操作数,要取下此操作数
//当countFinish=true并且state=RUN时说明第一个操作数和操作输入后按等号,此时没有第二个操作数
if( !countFinish || countFinish && state == RUN )
number = new BigDecimal( screen.getText() );
state = INIT;//按等号后一般说明计算结果,状态为初始化状态
count( operate );
}
private void manageOperation()
{
inputFinish = true;
decimal = false;
//当countFinish=true时说明输入的是下一次计算的操作,只记下下一次计算操作,不计算
if( !countFinish )
{
//当state!=INIT时说明要计算,取第二个操作数计算
if( state != INIT )
{
number = new BigDecimal( screen.getText() );
count( operate );
}
//当state=INIT时说明第一次输入操作,不用计算
else
{
state = RUN;//进入计算状态
countFinish = true;//防止初始化并输入第一个数据之后连续按两下运算时计算出结果
accumulator = new BigDecimal( screen.getText() );
}
}
}
private void count( int operate )
{
switch( operate )
{
case 1://+
accumulator = accumulator.add( number );
break;
case 2://-
accumulator = accumulator.subtract( number );
break;
case 3://*
accumulator = accumulator.multiply( number );
break;
case 4:///
try
{
accumulator = accumulator.divide( number, 15, 5 );
}catch( ArithmeticException ae )
{
state = ERROR;
}
break;
}
setScreenText( accumulator );
if( state == ERROR ) screen.setText( "除数不能为零!" );
countFinish = true;
}
private void setScreenText( BigDecimal number )//去掉小数中最右边的0后显示
{
String result = number.toString();
if( result.indexOf( "." ) != -1 )
{
char ch = result.charAt( result.length() - 1 );
while( ch == '0' )
{
result = result.substring( 0, result.length() - 1 );
ch = result.charAt( result.length() - 1 );
}
}
else
{
result += ".";
}
screen.setText( result );
}
private void backSpace()
{
try
{
//只输入一位的整数的长度是2,小数是3,退格后清0
if( screen.getText().length() == 2 ||
screen.getText().length() == 3 && decimal == true )
screen.setText( "0." );
else if( decimal == false )
{
screen.setText( screen.getText( 0, screen.getText().length() - 2 ) + "." );
}
else if( decimal == true )
{
//当小数退格到最后一位是.时再按退格时小数标设为假
if( screen.getText( screen.getText().length() - 1, 1 ).equals( "." ) )
decimal = false;
else
screen.setText( screen.getText( 0, screen.getText().length() - 1 ) );
}
}catch( Exception e ){ }
}
private void pressNumber( String num )
{
//当inputFinish=true时说明上一步按了操作,现在要输入第二个操作数,屏幕清0
if( inputFinish )
{
screen.setText( "0." );
inputFinish = false;
}
countFinish = false;//当输入操作数时说明有新的计算,计算完成标记设为假
//输入第一位整数的处理
if( screen.getText().equals( "0." ) && decimal == false ) screen.setText( num + "." );
else
{
if( decimal == false )//输入为整数的处理
{
try
{
screen.setText( screen.getText( 0, screen.getText().length() - 1 )
+ num + "." );
}catch( Exception e ){ }
}
else//输入为小数的处理
{
screen.setText( screen.getText() + num );
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -