package cross.pauliuyou.calculator.ui;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.math.BigDecimal;
import java.util.Vector;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import cross.pauliuyou.calculator.base.CalculateException;
import cross.pauliuyou.calculator.base.Calculator;
/**
*
* @author 刘优
* @version 1.1
*
*
*
*/
public class CalculatorJFrame extends JFrame implements ActionListener,KeyListener {
private static final long serialVersionUID = 1L;
private JTextArea screen;
private JTextField screen2;
private JButton[] buttons;
private JDialog dialog;
private Container dialogPane;
private Vector express;
private static char[] ops = { '+', '-', '*', '/', '!', 's', 'p' };
private static String keyPermited = "0.123456789+-*/=sp\n\r";
private boolean calculated;
private BigDecimal result = BigDecimal.ZERO;
private Calculator calculator;
class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
JMenuItem menuItem = (JMenuItem) ae.getSource();
String cmd = menuItem.getActionCommand();
// screen.append(cmd);
if (cmd.equals("打开")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("保存")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("另存为")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("退出")) {
System.exit(0);
} else if (cmd.equals("复制")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("剪切")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("粘贴")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("查看")) {
alarm("菜单 : " + cmd, false);
} else if (cmd.equals("主题")) {
alarm("此计算器可以计算复杂表达式", false);
} else if (cmd.equals("关于")) {
showAbout();
}
}
}
public CalculatorJFrame() {
super("计算器 - 作者:刘优");
screen = new JTextArea(4, 24);
screen2 = new JTextField(26);
String[] buttonStrings = { "乘方", "整数", "回退", "清空", "阶乘", "(", ")",
"开方", "1", "2", "3", "+", "4", "5", "6", "-", "7", "8", "9",
"*", ".", "0", "=", "/" };
String[] actionCommand = { "Pow", "Int", "Back", "CE", "!", "(", ")",
"Sqrt", "1", "2", "3", "+", "4", "5", "6", "-", "7", "8", "9",
"*", ".", "0", "=", "/" };
String[] toolTipString = { "乘方", "把结果转为整数", "删除一个字符", "清空结果重新计算", "阶乘",
"左括号", "右括号", "开平方", "", "", "", "加", "", "", "", "减或负数", "",
"", "", "乘", "", "", "计算", "除" };
buttons = new JButton[buttonStrings.length];
Font buttonFont = new Font("宋体", Font.PLAIN, 12);
for (int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(buttonStrings[i]);
buttons[i].setActionCommand(actionCommand[i]);
buttons[i].setFont(buttonFont);
buttons[i].setToolTipText(toolTipString[i]);
}
dialog = new JDialog(this, "消息窗口", true);
express = new Vector();
calculated = false;
myInit();
addEventHandle();
showMe();
}
private void myInit() {
this.setJMenuBar(getMenu());
screen.setFont(new Font("", Font.BOLD, 15));
screen.setEditable(false);
screen.setToolTipText("主屏幕");
screen.setAutoscrolls(true);
screen2.setEditable(false);
JPanel northPane = new JPanel();
JPanel centerPane = new JPanel(new GridLayout(6, 4, 6, 8));
JScrollPane scroll = new JScrollPane(screen);
northPane.add(scroll);
for (int i = 0; i < buttons.length; i++) {
centerPane.add(buttons[i]);
}
add(northPane, "North");
add(centerPane);
add(new JPanel(), "West");
add(new JPanel(), "East");
JPanel result2Panel = new JPanel();
result2Panel.add(screen2);
add(result2Panel, "South");
}
private void addEventHandle() {
screen.addKeyListener(this);
for (int i = 0; i < buttons.length; i++) {
buttons[i].addActionListener(this);
}
}
private JMenuBar getMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menuFile = new JMenu("文件 ");
JMenu menuEdit = new JMenu("编辑 ");
JMenu menuView = new JMenu("查看 ");
JMenu menuHelp = new JMenu("帮助 ");
menuBar.add(menuFile);
menuBar.add(menuEdit);
menuBar.add(menuView);
menuBar.add(menuHelp);
JMenuItem menuItemFileOpen = new JMenuItem("打开");
JMenuItem menuItemFileSave = new JMenuItem("保存");
JMenuItem menuItemFileSaveAs = new JMenuItem("另存为");
JMenuItem menuItemFileExit = new JMenuItem("退出");
JMenuItem menuItemEditCopy = new JMenuItem("复制");
JMenuItem menuItemEditCut = new JMenuItem("剪切");
JMenuItem menuItemEditPaste = new JMenuItem("粘贴");
JMenuItem menuItemViewView = new JMenuItem("查看");
JMenuItem menuItemHelpTopic = new JMenuItem("主题");
JMenuItem menuItemHelpAbout = new JMenuItem("关于");
menuFile.add(menuItemFileOpen);
menuFile.add(menuItemFileSave);
menuFile.add(menuItemFileSaveAs);
menuFile.addSeparator();
menuFile.add(menuItemFileExit);
menuEdit.add(menuItemEditCopy);
menuEdit.add(menuItemEditCut);
menuEdit.addSeparator();
menuEdit.add(menuItemEditPaste);
menuView.add(menuItemViewView);
menuHelp.add(menuItemHelpTopic);
menuHelp.addSeparator();
menuHelp.add(menuItemHelpAbout);
MenuActionListener menuListener = new MenuActionListener();
menuItemFileOpen.addActionListener(menuListener);
menuItemFileSave.addActionListener(menuListener);
menuItemFileSaveAs.addActionListener(menuListener);
menuItemFileExit.addActionListener(menuListener);
menuItemEditCopy.addActionListener(menuListener);
menuItemEditCut.addActionListener(menuListener);
menuItemEditPaste.addActionListener(menuListener);
menuItemViewView.addActionListener(menuListener);
menuItemHelpTopic.addActionListener(menuListener);
menuItemHelpAbout.addActionListener(menuListener);
return menuBar;
}
private void showMe() {
int width = 310;
int height = 370;
setSize(width, height);
setLocation(350, 150);
this.setResizable(false);
setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dialog.setSize(270, 110);
dialog.setLocation(this.getX() + 100, this.getY() + 100);
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
dialog.setResizable(false);
dialogPane = dialog.getContentPane();
}
private void showAbout() {
dialog.setTitle("关于本软件");
dialogPane.removeAll();
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 1));
JTextField f1 = new JTextField("名称 \t: 计算器");
f1.setEditable(false);
panel.add(f1);
f1 = new JTextField("作者 \t: 刘优");
f1.setEditable(false);
panel.add(f1);
f1 = new JTextField("日期 \t: 2007-08");
f1.setEditable(false);
panel.add(f1);
dialogPane.add(panel);
dialog.setLocation(this.getX() + 100, this.getY() + 100);
dialog.setVisible(true);
}
private void backSpace() {
String str = screen.getText();
if (str.length() > 0)
screen.setText(str.substring(0, str.length() - 1));
}
public void actionPerformed(ActionEvent e) {
screen.requestFocus();
String cmd = e.getActionCommand();
char c = cmd.charAt(0);
if (c == 'C') {
clear();
} else if (c == 'B') {
backSpace();
} else if (c == 'P') {
doOperator('p');
} else if (c == 'I') {
/*
String bigint = result.toString();
int dot = bigint.indexOf(".");
if (dot != -1) {
String afterdot = "0" + bigint.substring(dot);
double d = Double.parseDouble(afterdot);
if (d > 0.54) {
bigint = result.intValue() + 1 + "";
} else {
bigint = bigint.substring(0, dot);
}
}
String str = screen.getText();
int equalPos = str.indexOf("=");
if (equalPos != -1) {
screen.setText(str.substring(0, equalPos + 2) + bigint);
result = new BigDecimal(bigint);
}
*/
String intValue = result.intValue() + "";
screen.setText(intValue);
result = new BigDecimal(intValue);
} else if (c == 'S') {
doOperator('s');
} else if (c == '=') {
enter();
} else if (c == '(' || c == ')') {
screen.append(cmd);
} else if (isOperator(c)) {
doOperator(c);
} else if (isNumber(c)) {
doNumber(c);
} else if (cmd.equals("."))
{
screen.append(".");
}
}
private void clear() {
screen.setText("");
toZero();
calculated = false;
}
private void doNumber(char c) {
if (calculated) {
screen.setText(c + "");
calculated = false;
} else {
screen.append(c + "");
}
}
private void doOperator(char c) {
if (calculated) {
screen.setText(result.toString() + c);
calculated = false;
} else {
screen.append(c + "");
}
}
private void enter() {
if (!calculated) {
if (calculator == null) {
calculator = new Calculator();
}
try {
String theText = result.toString().trim();
if (screen2.getText().trim().length () + theText.length() + 4 > screen2.getColumns())
{
screen2.setText(theText);
}
else
{
screen2.setText(screen2.getText() + " " + theText);
}
result = calculator.calculate(screen.getText());
screen.append("\n=" + result.toString());
} catch (CalculateException e) {
alarm(e.getMessage());
}
} else {
screen.setText(result.toString());
}
calculated = true;
toZero();
}
private void alarm(String infor) {
alarm(infor, true);
}
private void alarm(String infor, boolean serious) {
dialogPane.removeAll();
JLabel label = new JLabel("信息", JLabel.CENTER);
dialog.setTitle("信息");
if (serious) {
dialog.setTitle("错误!!");
label = new JLabel("发生错误 : ", JLabel.CENTER);
}
JLabel label2 = new JLabel(infor, JLabel.CENTER);
label2.setFont(new Font("宋体", Font.BOLD, 16));
label2.setForeground(Color.red);
dialogPane.add(label, "North");
dialogPane.add(label2);
dialog.setLocation(this.getX() + 100, this.getY() + 100);
dialog.setVisible(true);
}
private void toZero() {
express.clear();
}
private boolean isKeyPermited(char c) {
for (int i = 0; i < keyPermited.length(); i++) {
if (c == keyPermited.charAt(i)) {
return true;
}
}
return false;
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == 27) {
clear();
}
boolean shift = e.isShiftDown();
if (shift && code == 57) {
screen.append("(");
return;
} else if (shift && code == 48) {
screen.append(")");
return;
}
char c = e.getKeyChar();
if (isKeyPermited(c)) {
if (c == '=' || c == '\n' || c == 'r') {
enter();
} else {
if (isOperator(c)) {
doOperator(c);
}
if (isNumber(c)) {
doNumber(c);
}
}
}
if (code == 8) {
backSpace();
}
}
private boolean isNumber(char c) {
if (c >= '0' && c <= '9') {
return true;
}
return false;
}
private boolean isOperator(char c) {
for (int x = 0; x < ops.length; x++) {
if (c == ops[x]) {
return true;
}
}
return false;
}
public void keyReleased(KeyEvent e) {
}
}