import?java.awt.BorderLayout;
import?java.awt.Color;
import?java.awt.GridLayout;
import?java.awt.event.ActionEvent;
import?java.awt.event.ActionListener;
import?javax.swing.JButton;
import?javax.swing.JFrame;
import?javax.swing.JPanel;
import?javax.swing.JTextField;
/**
*?壹個計算器,與Windows附件自帶計算器的標準版功能、界面相仿。?但還不支持鍵盤操作。 */public?class?JCalculator?extends?JFrame?implements?ActionListener?{
/**?計算器上的鍵的顯示名字?*/
private?final?String[]?KEYS?=?{?"7",?"8",?"9",?"/",?"sqrt",?"4",?"5",?"6",
"*",?"%",?"1",?"2",?"3",?"-",?"1/x",?"0",?"+/-",?".",?"+",?"="?};
/**?計算器上的功能鍵的顯示名字?*/
private?final?String[]?COMMAND?=?{?"Backspace",?"CE",?"C"?};
/**?計算器左邊的M的顯示名字?*/
private?final?String[]?M?=?{?"?",?"MC",?"MR",?"MS",?"M+"?};
/**?計算器上鍵的按鈕?*/
private?JButton?keys[]?=?new?JButton[KEYS.length];
/**?計算器上的功能鍵的按鈕?*/
private?JButton?commands[]?=?new?JButton[COMMAND.length];
/**?計算器左邊的M的按鈕?*/
private?JButton?m[]?=?new?JButton[M.length];
/**?計算結果文本框?*/
private?JTextField?resultText?=?new?JTextField("0");
//?標誌用戶按的是否是整個表達式的第壹個數字,或者是運算符後的第壹個數字
private?boolean?firstDigit?=?true;
//?計算的中間結果。
private?double?resultNum?=?0.0;
//?當前運算的運算符
private?String?operator?=?"=";
//?操作是否合法
private?boolean?operateValidFlag?=?true;
/**
?*?構造函數
?*/
public?JCalculator()?{
super();
//?初始化計算器
init();
//?設置計算器的背景顏色
this.setBackground(Color.LIGHT_GRAY);
this.setTitle("計算器");
//?在屏幕(500,?300)坐標處顯示計算器
this.setLocation(500,?300);
//?不許修改計算器的大小
this.setResizable(false);
//?使計算器中各組件大小合適
this.pack();
}
/**
?*?初始化計算器
?*/
private?void?init()?{
//?文本框中的內容采用右對齊方式
resultText.setHorizontalAlignment(JTextField.RIGHT);
//?不允許修改結果文本框
resultText.setEditable(false);
//?設置文本框背景顏色為白色
resultText.setBackground(Color.white);
//?初始化計算器上鍵的按鈕,將鍵放在壹個畫板內
JPanel?calckeysPanel?=?new?JPanel();
//?用網格布局器,4行,5列的網格,網格之間的水平方向間隔為3個象素,垂直方向間隔為3個象素
calckeysPanel.setLayout(new?GridLayout(4,?5,?3,?3));
for?(int?i?=?0;?i?<?KEYS.length;?i++)?{
keys[i]?=?new?JButton(KEYS[i]);
calckeysPanel.add(keys[i]);
keys[i].setForeground(Color.blue);
}
//?運算符鍵用紅色標示,其他鍵用藍色表示
keys[3].setForeground(Color.red);
keys[8].setForeground(Color.red);
keys[13].setForeground(Color.red);
keys[18].setForeground(Color.red);
keys[19].setForeground(Color.red);
//?初始化功能鍵,都用紅色標示。將功能鍵放在壹個畫板內
JPanel?commandsPanel?=?new?JPanel();
//?用網格布局器,1行,3列的網格,網格之間的水平方向間隔為3個象素,垂直方向間隔為3個象素
commandsPanel.setLayout(new?GridLayout(1,?3,?3,?3));
for?(int?i?=?0;?i?<?COMMAND.length;?i++)?{
commands[i]?=?new?JButton(COMMAND[i]);
commandsPanel.add(commands[i]);
commands[i].setForeground(Color.red);
}
//?初始化M鍵,用紅色標示,將M鍵放在壹個畫板內
JPanel?calmsPanel?=?new?JPanel();
//?用網格布局管理器,5行,1列的網格,網格之間的水平方向間隔為3個象素,垂直方向間隔為3個象素
calmsPanel.setLayout(new?GridLayout(5,?1,?3,?3));
for?(int?i?=?0;?i?<?M.length;?i++)?{
m[i]?=?new?JButton(M[i]);
calmsPanel.add(m[i]);
m[i].setForeground(Color.red);
}
//?下面進行計算器的整體布局,將calckeys和command畫板放在計算器的中部,
//?將文本框放在北部,將calms畫板放在計算器的西部。
//?新建壹個大的畫板,將上面建立的command和calckeys畫板放在該畫板內
JPanel?panel1?=?new?JPanel();
//?畫板采用邊界布局管理器,畫板裏組件之間的水平和垂直方向上間隔都為3象素
panel1.setLayout(new?BorderLayout(3,?3));
panel1.add("North",?commandsPanel);
panel1.add("West",?calckeysPanel);
//?建立壹個畫板放文本框
JPanel?top?=?new?JPanel();
top.setLayout(new?BorderLayout());
top.add("Center",?resultText);
//?整體布局
getContentPane().setLayout(new?BorderLayout(3,?5));
getContentPane().add("North",?top);
getContentPane().add("Center",?panel1);
getContentPane().add("West",?calmsPanel);
//?為各按鈕添加事件偵聽器
//?都使用同壹個事件偵聽器,即本對象。本類的聲明中有implements?ActionListener
for?(int?i?=?0;?i?<?KEYS.length;?i++)?{
keys[i].addActionListener(this);
}
for?(int?i?=?0;?i?<?COMMAND.length;?i++)?{
commands[i].addActionListener(this);
}
for?(int?i?=?0;?i?<?M.length;?i++)?{
m[i].addActionListener(this);
}
}
/**
?*?處理事件
?*/
public?void?actionPerformed(ActionEvent?e)?{
//?獲取事件源的標簽
String?label?=?e.getActionCommand();
if?(label.equals(COMMAND[0]))?{
//?用戶按了"Backspace"鍵
handleBackspace();
}?else?if?(label.equals(COMMAND[1]))?{
//?用戶按了"CE"鍵
resultText.setText("0");
}?else?if?(label.equals(COMMAND[2]))?{
//?用戶按了"C"鍵
handleC();
}?else?if?("0123456789.".indexOf(label)?>=?0)?{
//?用戶按了數字鍵或者小數點鍵
handleNumber(label);
//?handlezero(zero);
}?else?{
//?用戶按了運算符鍵
handleOperator(label);
}
}
/**
?*?處理Backspace鍵被按下的事件
?*/
private?void?handleBackspace()?{
String?text?=?resultText.getText();
int?i?=?text.length();
if?(i?>?0)?{
//?退格,將文本最後壹個字符去掉
text?=?text.substring(0,?i?-?1);
if?(text.length()?==?0)?{
//?如果文本沒有了內容,則初始化計算器的各種值
resultText.setText("0");
firstDigit?=?true;
operator?=?"=";
}?else?{
//?顯示新的文本
resultText.setText(text);
}
}
}
/**
?*?處理數字鍵被按下的事件
?*?
?*?@param?key
?*/
private?void?handleNumber(String?key)?{
if?(firstDigit)?{
//?輸入的第壹個數字
resultText.setText(key);
}?else?if?((key.equals("."))?&&?(resultText.getText().indexOf(".")?<?0))?{
//?輸入的是小數點,並且之前沒有小數點,則將小數點附在結果文本框的後面
resultText.setText(resultText.getText()?+?".");
}?else?if?(!key.equals("."))?{
//?如果輸入的不是小數點,則將數字附在結果文本框的後面
resultText.setText(resultText.getText()?+?key);
}
//?以後輸入的肯定不是第壹個數字了
firstDigit?=?false;
}
/**
?*?處理C鍵被按下的事件
?*/
private?void?handleC()?{
//?初始化計算器的各種值
resultText.setText("0");
firstDigit?=?true;
operator?=?"=";
}
/**
?*?處理運算符鍵被按下的事件
?*?
?*?@param?key
?*/
private?void?handleOperator(String?key)?{
if?(operator.equals("/"))?{
//?除法運算
//?如果當前結果文本框中的值等於0
if?(getNumberFromText()?==?0.0)?{
//?操作不合法
operateValidFlag?=?false;
resultText.setText("除數不能為零");
}?else?{
resultNum?/=?getNumberFromText();
}
}?else?if?(operator.equals("1/x"))?{
//?倒數運算
if?(resultNum?==?0.0)?{
//?操作不合法
operateValidFlag?=?false;
resultText.setText("零沒有倒數");
}?else?{
resultNum?=?1?/?resultNum;
}
}?else?if?(operator.equals("+"))?{
//?加法運算
resultNum?+=?getNumberFromText();
}?else?if?(operator.equals("-"))?{
//?減法運算
resultNum?-=?getNumberFromText();
}?else?if?(operator.equals("*"))?{
//?乘法運算
resultNum?*=?getNumberFromText();
}?else?if?(operator.equals("sqrt"))?{
//?平方根運算
resultNum?=?Math.sqrt(resultNum);
}?else?if?(operator.equals("%"))?{
//?百分號運算,除以100
resultNum?=?resultNum?/?100;
}?else?if?(operator.equals("+/-"))?{
//?正數負數運算
resultNum?=?resultNum?*?(-1);
}?else?if?(operator.equals("="))?{
//?賦值運算
resultNum?=?getNumberFromText();
}
if?(operateValidFlag)?{
//?雙精度浮點數的運算
long?t1;
double?t2;
t1?=?(long)?resultNum;
t2?=?resultNum?-?t1;
if?(t2?==?0)?{
resultText.setText(String.valueOf(t1));
}?else?{
resultText.setText(String.valueOf(resultNum));
}
}
//?運算符等於用戶按的按鈕
operator?=?key;
firstDigit?=?true;
operateValidFlag?=?true;
}
/**
?*?從結果文本框中獲取數字
?*?
?*?@return
?*/
private?double?getNumberFromText()?{
double?result?=?0;
try?{
result?=?Double.valueOf(resultText.getText()).doubleValue();
}?catch?(NumberFormatException?e)?{
}
return?result;
}
public?static?void?main(String?args[])?{
JCalculator?JCalculator1?=?new?JCalculator();
JCalculator1.setVisible(true);
JCalculator1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}