几乎每个初学 Java 的人都做过一个写计算器的练习。现在搞 Java 搞了这么多年,重新写一遍,风格已经完全不同了。
public class MyCalculator implements ActionListener {
private JFrame frame = new JFrame();
private JTextField text = new JTextField("0");
private Processor processor = new Processor();
private void show() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// nothing happens
}
initControls();
frame.setVisible(true);
}
private void initControls() {
initFrame();
initTextField();
initTopPanel();
initButtonsPanel();
}
private void initFrame() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("计算器");
frame.setLayout(new BorderLayout());
frame.setSize(300, 250);
frame.setResizable(false);
}
private void initButtonsPanel() {
JPanel buttons_panel = new JPanel(new GridLayout(4, 4, 3, 3));
buttons_panel.setBorder(new EmptyBorder(0, 10, 10, 10));
String[] button_texts = {"7", "8", "9", "+", "4", "5", "6",
"-", "1", "2", "3", "*", "0", ".", "=", "/"};
for (String button_text : button_texts) {
buttons_panel.add(createButton(button_text));
}
frame.add(buttons_panel);
}
private void initTopPanel() {
JPanel top_panel = new JPanel(new BorderLayout());
top_panel.setBorder(new EmptyBorder(10, 10, 5, 10));
top_panel.add(text, BorderLayout.CENTER);
frame.add(top_panel, BorderLayout.NORTH);
}
private void initTextField() {
text.setEditable(false);
text.setHorizontalAlignment(JTextField.RIGHT);
text.setBackground(Color.white);
}
private JButton createButton(String button_text) {
JButton button = new JButton(button_text);
button.addActionListener(this);
return button;
}
/**
* 处理按钮事件
*
* @param e 按钮事件
*/
public void actionPerformed(ActionEvent e) {
if (!(e.getSource() instanceof JButton)) {
return;
}
JButton btn = (JButton) e.getSource();
String btn_text = btn.getText();
if ("0123456789".indexOf(btn_text) != -1) {
processor.numButtonClicked(btn_text);
} else if (".".indexOf(btn_text) != -1) {
processor.dotButtonClicked();
} else if ("+-*/".indexOf(btn_text) != -1) {
processor.operateButtonClicked(btn_text);
} else if ("=".indexOf(btn_text) != -1) {
processor.equalsButtonClicked();
}
text.setText(processor.getResult());
}
/**
* 程序入口
*
* @param args 命令行参数
*/
public static void main(String[] args) {
new MyCalculator().show();
}
}
/**
* 运算部分
*/
class Processor {
private String result = "0";
private boolean start_new = false;
private double last_value = 0;
private String operation = "";
public String getResult() {
return result;
}
public void numButtonClicked(String text) {
if (!start_new) {
result += text;
} else {
result = text;
}
// 去掉开头的 0
while (result.startsWith("0") && !result.startsWith("0.") && result.length() > 1) {
result = result.substring(1);
}
start_new = false;
}
public void dotButtonClicked() {
if (result.indexOf(".") == -1) {
result += ".";
}
}
public void operateButtonClicked(String text) {
operation = text;
if (result.length() > 0) {
last_value = Double.parseDouble(result);
}
start_new = true;
}
public void equalsButtonClicked() {
double value = Double.parseDouble(result);
// 执行计算
if (operation.equals("+")) {
result = String.valueOf(value + last_value);
} else if (operation.equals("-")) {
result = String.valueOf(last_value - value);
} else if (operation.equals("*")) {
result = String.valueOf(last_value * value);
} else if (operation.equals("/")) {
if (value == 0) {
result = "ERROR";
} else {
result = String.valueOf(last_value / value);
}
}
// 去掉结尾的“.0000...”
if (result.matches(".+\\.0+")) {
result = result.substring(0, result.lastIndexOf("."));
}
// 设置状态
start_new = true;
operation = "";
}
}