該程式是為了理解Swing應用而嘗試的一個執行個體。雖然是個簡單計算機程式,卻設計了3個類。
設計過程中滿足了將資料與介面完全分離,而且把介面和使用者事件處理也完全分離。因此於我
個人而言覺得設計得還不錯,如果哪位有更好的設計不妨共用共用,也讓我改進改進。在這
個設計中同樣還有些細節沒有達到我理想的要求,但由於時間倉促也就沒有再進一步思考了。
下面把思路描述一下:
總的設計分為3個類,CalcGui負責顯示介面,CalcEvent負責使用者觸發的事件,CalcLogic負責
處理演算法。 這3個類各司其責,協同完成計算過程。
一.CalcGui類中包含4個面板
,一個根面板和三個容器面板,根面板封裝3個容器面板。下面介紹
容器面板。
1.頂部面板封裝
記憶狀態,顯示屏,以及回退鍵backspace ,錯誤清除鍵CE和清零鍵C
2.左部面板封裝 4個於記憶相關的鍵MC MS
MR M+
3.右部面板封裝
剩下的數字鍵和符號鍵
使用者觸發的事件全部是按鍵事件,所以每個按鍵必然有一個相應的事件處理過程,而這麼多按鍵不可能一個一個的添加事件,因此專門設計了CalcEvent類來處理所以按鍵事件。當CalcGui類中產生一個按鍵時對應的建立一個CalcEvent執行個體來處理相應的事件。而為了達到介面和事件分離,在CalcEvent類中儲存了每個按鍵的控制代碼,因此所有的按鍵事件都在自己的CalcEvent中進行監聽和處理。該部分的核心代碼是
buttons[i]
= new JButton(CalcEvent.actionCommands[i]);
buttons[i].setBorder(BorderFactory.createEmptyBorder(5,
5, 5, 5));
new
CalcEvent(buttons[i], displayText, memoryLabel);
同樣為了動態重新整理螢幕,也要在事件處理中更新螢幕和狀態,所以在CalcEvent中也包含了
螢幕Text和狀態Label的控制代碼。通過產生事件執行個體的時候把Gui中的button ,text,label控制代碼傳進去。new
CalcEvent(buttons[i], displayText, memoryLabel);
二.CalcEvent類把每個按鍵上的數字或者符號都設計成命令,當構造執行個體時,就根據Gui傳進來的命令,把相應的命令關聯到符號上,如
this.button = button;
this.text
= text;
this.label
= label;
setCommand();
由於計算邏輯是爭對整個計算機程式的,所以只要一個CalcLogic執行個體,而且這個執行個體需要是靜態,因為所有事件共用一個CalcLogic執行個體由其進行計算。
所以在CalcEvent類中儲存一個靜態CalcLogic執行個體
private static CalcLogic calculate = new
CalcLogic();
三.CalcLogic類執行所有的計算功能。這部分主要包括了重要的演算法,在此我將不解釋具體的演算法,因為該演算法完全是仁者見仁,智者見智,而且我的演算法也不優秀,如果大家有興趣可以參考罷了。
以下是代碼:
CalcGui 類
package calculator;
import java.awt.*;
import javax.swing.*;
// import java.text.DecimalFormat;
// import java.text.ParseException;
public class CalcGui extends JPanel {
JTextField displayText;
JLabel memoryLabel;
private static final int BUTTON_NUM = 27;
JButton[] buttons = new JButton[BUTTON_NUM];
public CalcGui() {
//displayText = new JFormattedTextField(new DecimalFormat("#0.#"));
displayText = new JTextField("0.", 17);
//displayText.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT);
displayText.setHorizontalAlignment(JTextField.RIGHT);
//displayText.setEditable(false);
/* try {
displayText.setText("0.");
displayText.commitEdit();
} catch(ParseException e) {
e.printStackTrace();
} */
memoryLabel = new JLabel();
memoryLabel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 5));
memoryLabel.setHorizontalAlignment(JLabel.RIGHT);
for (int i = 0; i < BUTTON_NUM; i++) {
buttons[i] = new JButton(CalcEvent.actionCommands[i]);
buttons[i].setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//CalcEvent event = new CalcEvent(buttons[i], displayText);
new CalcEvent(buttons[i], displayText, memoryLabel);
}
// topPanel 封裝結果顯示屏, 記憶屏,
// 以及回退鍵,錯誤清除鍵,清零鍵 分別是 Backspace CE C
JPanel topPanel = new JPanel();
topPanel.setLayout(new GridBagLayout());
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
topPanel.add(memoryLabel, c);
c.gridx = 1;
c.gridwidth = 3;
topPanel.add(displayText, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.weightx = 0.5;
c.weighty = 1.0;
topPanel.add(buttons[20], c);
c.gridx = 2;
c.gridy = 1;
topPanel.add(buttons[21], c);
c.gridx = 3;
c.gridy = 1;
topPanel.add(buttons[22], c);
// leftPanel 封裝記憶功能的四個鍵,分別是 MC MR MS M+
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
leftPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
leftPanel.add(buttons[23]);
leftPanel.add(buttons[24]);
leftPanel.add(buttons[25]);
leftPanel.add(buttons[26]);
// rightPanel 封裝數字鍵和一些計算按鍵
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new GridLayout(4, 5));
rightPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
for (int i = 0; i < BUTTON_NUM - 7; i++) {
rightPanel.add(buttons[i]);
}
// 最後由主面板裝載以上3個從面板
setLayout(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
add(topPanel, BorderLayout.PAGE_START);
add(leftPanel, BorderLayout.LINE_START);
add(rightPanel, BorderLayout.CENTER);
}
private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
// new a CalcGUI instance here
//CalcGui calculator = new CalcGui();
JFrame frame = new JFrame("Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// add my component here
frame.getContentPane().add(new CalcGui());
frame.pack();
frame.setVisible(true);
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
CalcEvent 類
package calculator;
import javax.swing.*;
//import java.awt.*;
import java.awt.event.*;
public class CalcEvent implements ActionListener {
private JButton button;
private JTextField text;
private JLabel label;
private String command;
private static CalcLogic calculate = new CalcLogic();
final static int COMMAND_NUM = 27;
static String[] actionCommands =new String[]
{
new String("7"),
// 0
new String("8"),
// 1
new String("9"),
// 2
new String("/"),
// 3
new String("sqrt"),
// 4
new String("4"),
// 5
new String("5"),
// 6
new String("6"),
// 7
new String("*"),
// 8
new String("%"),
// 9
new String("1"),
// 10
new String("2"),
// 11
new String("3"),
// 12
new String("-"),
// 13
new String("1/x"),
// 14
new String("0"),
// 15
new String("+/-"),
// 16
new String("."),
// 17
new String("+"),
// 18
new String("="),
// 19
new String("Backspace"), // 20
new
String("CE"), // 21
new
String("C"), // 22
new
String("MC"), // 23
new
String("MR"), // 24
new
String("MS"), // 25
new
String("M+"), // 26
};
public CalcEvent(JButton button, JTextField text, JLabel
label) {
this.button = button;
this.text = text;
this.label = label;
setCommand();
}
private void setCommand() {
for (int i = 0; i < COMMAND_NUM; i++)
{
if
(actionCommands[i].equals(button.getText())) {
button.setActionCommand(actionCommands[i]);
button.addActionListener(this);
command = actionCommands[i];
break;
}
}
}
public void actionPerformed(ActionEvent e) {
if
(".".equals(e.getActionCommand()) ||
"0".equals(e.getActionCommand()) ||
"1".equals(e.getActionCommand()) ||
"2".equals(e.getActionCommand()) ||
"3".equals(e.getActionCommand()) ||
"4".equals(e.getActionCommand()) ||
"5".equals(e.getActionCommand()) ||
"6".equals(e.getActionCommand()) ||
"7".equals(e.getActionCommand()) ||
"8".equals(e.getActionCommand()) ||
"9".equals(e.getActionCommand())) {
text.setText(calculate.procNum(command, text.getText()));
} else {
text.setText(calculate.procSym(command));
label.setText(calculate.returnMemory());
}
}
}