package br.ufpr.c3sl.view.calculator;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import br.ufpr.c3sl.model.CalcLogic;
/*
"AC", "A", "←", "x²",
"7", "8", "9", "÷",
"4", "5", "6", "x",
"1", "2", "3", "-",
".", "0", "±", "+",
"", "", "=", "²√x"
*/
@SuppressWarnings("serial")
public class Calculator extends JFrame{
private static final Font BIGGER_FONT = new Font("monspaced", Font.PLAIN, 20);
private JTextField jtfDisplay;
private JPanel jpMain;
private JPanel jpRight;
private JPanel jpCenter;
private JPanel jpBottom;
private CalcLogic calc;
private boolean clearAll;
private boolean clearDisplay = true;
private boolean inputMode;
private String operation;
public Calculator() {
setSize(200, 300);
inicializeVariables();
this.pack();
this.setFocusable(true);
this.setTitle("Calculadora");
this.setResizable(false);
//this.setLocationRelativeTo(JPanelCRI.getInstance());
this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
this.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) { cmdKeyTyped(e); }
public void keyPressed(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
});
}
public void inicializeVariables(){
calc = new CalcLogic();
jpMain = new JPanel();
jpMain.setName("jpMain");
jpMain.setLayout(new BorderLayout(5, 5));
jpMain.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
this.add(jpMain);
jtfDisplay = new JTextField("0", 15);
jtfDisplay.setName("jtfDisplay");
jtfDisplay.setHorizontalAlignment(JTextField.RIGHT);
jtfDisplay.setFont(BIGGER_FONT);
jtfDisplay.setEditable(false);
jtfDisplay.setFocusable(false);
jtfDisplay.setBackground(Color.white);
addButtons();
jpMain.add(jtfDisplay, BorderLayout.NORTH );
jpMain.add(jpCenter, BorderLayout.CENTER);
jpMain.add(jpRight, BorderLayout.EAST);
jpMain.add(jpBottom, BorderLayout.SOUTH);
}
private void addButtons(){
jpCenter = new JPanel();
jpCenter.setName("jpCenter");
jpCenter.setLayout(new GridLayout(5, 3, 7, 7));
JButton jbAC = new JButton("AC");
jbAC.setName("AC");
jbAC.setFont(BIGGER_FONT);
jbAC.setFocusable(false);
jbAC.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdAC();
}
});
JButton jbA = new JButton("C");
jbA.setName("C");
jbA.setFont(BIGGER_FONT);
jbA.setFocusable(false);
jbA.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdC();
}
});
JButton jbBksp = new JButton("←");
jbBksp.setName("←");
jbBksp.setFont(BIGGER_FONT);
jbBksp.setFocusable(false);
jbBksp.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdBksp();
}
});
jpCenter.add(jbAC);
jpCenter.add(jbA);
jpCenter.add(jbBksp);
String numbers = "7894561230";
for (Character number : numbers.toCharArray()) {
JButton b = new JButton(number.toString());
b.setFont(BIGGER_FONT);
b.setFocusable(false);
b.setName(number.toString());
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdNumbers(e.getActionCommand());
}
});
jpCenter.add(b);
}
JButton jbPoint = new JButton(".");
jbPoint.setName(".");
jbPoint.setFont(BIGGER_FONT);
jbPoint.setFocusable(false);
jbPoint.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdPoint();
}
});
JButton jbMoreLess = new JButton("±");
jbMoreLess.setName("±");
jbMoreLess.setFont(BIGGER_FONT);
jbMoreLess.setFocusable(false);
jbMoreLess.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdMoreLess();
}
});
jpCenter.add(jbPoint, 12);
jpCenter.add(jbMoreLess);
jpRight = new JPanel();
jpRight.setName("jpRight");
jpRight.setLayout(new GridLayout(5,1,7,7));
JButton jbPow = new JButton("x²");
jbPow.setName("x²");
jbPow.setFont(BIGGER_FONT);
jbPow.setFocusable(false);
jbPow.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdPow();
}
});
JButton jbDivide = new JButton("÷");
jbDivide.setName("/");
jbDivide.setFont(BIGGER_FONT);
jbDivide.setFocusable(false);
jbDivide.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("/");
}
});
JButton jbMultiply = new JButton("x");
jbMultiply.setName("x");
jbMultiply.setFont(BIGGER_FONT);
jbMultiply.setFocusable(false);
jbMultiply.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("x");
}
});
JButton jbSubtract= new JButton("-");
jbSubtract.setName("-");
jbSubtract.setFont(BIGGER_FONT);
jbSubtract.setFocusable(false);
jbSubtract.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("-");
}
});
JButton jbSum = new JButton("+");
jbSum.setFont(BIGGER_FONT);
jbSum.setName("+");
jbSum.setFocusable(false);
jbSum.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("+");
}
});
JButton jbPowY = new JButton("<html><sub>X</sub><font size='2'>y</font>");
jbPowY.setName("x^y");
jbPowY.setFont(BIGGER_FONT);
jbPowY.setFocusable(false);
jbPowY.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("x^y");
}
});
JButton jbSqrtY = new JButton("<html><font size='2'>y</font><sub>√x</sub>");
jbSqrtY.setName("srqtY");
jbSqrtY.setFont(BIGGER_FONT);
jbSqrtY.setFocusable(false);
jbSqrtY.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdOperation("sqrtY");
}
});
jpRight.add(jbPow);
jpRight.add(jbDivide);
jpRight.add(jbMultiply);
jpRight.add(jbSubtract);
jpRight.add(jbSum);
jpBottom = new JPanel();
jpBottom.setLayout(new GridBagLayout());
jpBottom.setName("jpBottom");
//jpButtom.setBorder(BorderFactory.createEtchedBorder());
GridBagConstraints c = new GridBagConstraints();
JButton jbEqual = new JButton("=");
jbEqual.setName("=");
jbEqual.setFont(BIGGER_FONT);
jbEqual.setFocusable(false);
jbEqual.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdEqual();
}
});
JButton jbRaiz = new JButton("²√x");
jbRaiz.setName("²√x");
jbRaiz.setFont(BIGGER_FONT);
jbRaiz.setFocusable(false);
jbRaiz.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
cmdRaiz();
}
});
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 1;
c.weightx = 2;
c.weighty = 0;
c.insets = new Insets(0, 0, 0, 6);
jpBottom.add(jbEqual, c);
// c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 2;
c.gridy = 1;
c.weightx = 0.5;
c.weighty = 0;
jpBottom.add(jbRaiz, c);
// c.fill = GridBagConstraints.NONE;
c.gridx = 3;
c.gridy = 1;
// c.weightx = 1;
// c.weighty = 1;
jpBottom.add(jbSqrtY, c);
// c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 4;
c.gridy = 1;
// c.weightx = 1;
// c.weighty = 1;
c.insets = new Insets(0, 0, 0, 0);
jpBottom.add(jbPowY, c);
}
private void setDisplay(String s){
/* if (s.equals("0.0") || s.equals("-0.0"))
jtfDisplay.setText("0");
else
*/
jtfDisplay.setText(s);
}
private String getDisplayText(){
return jtfDisplay.getText();
}
public void clear(){
setDisplay("0");
calc.setSetCurrentNumber(false);
inputMode = false;
}
private void displayErro(String msg){
JOptionPane.showMessageDialog(this, msg,"Erro", JOptionPane.ERROR_MESSAGE);
clear();
}
private void cmdNumbers(String s){
if (clearAll){
clearAll = false;
clear();
}
if (clearDisplay || getDisplayText().equals("0")){
setDisplay(s);
clearDisplay = false;
}else
setDisplay(getDisplayText()+s);
inputMode = true;
}
private void cmdOperation(String s){
if (s.charAt(s.length()-1) == '.'){
s.substring(0, (s.length() -1));
}
if (!calc.isSetCurrentNumber()){
calc.setCurrentNumber(getDisplayText());
calc.setSetCurrentNumber(true);
}else
if (inputMode){
processOperator();
}
operation = s;
clearDisplay = true;
clearAll = false;
inputMode = false;
}
private void processOperator() {
if (operation.equals("-"))
setDisplay(calc.subtract(getDisplayText())+"");
else if (operation.equals("+"))
setDisplay(calc.sum(getDisplayText())+"");
else if (operation.equals("x^y"))
setDisplay(calc.powY(getDisplayText())+"");
else if (operation.equals("sqrtY"))
setDisplay(calc.sqrtY(getDisplayText())+"");
else if (operation.equals("/")){
String result = calc.divide(getDisplayText())+"";
if (result.endsWith("Infinity"))
displayErro("Não é possível dividir um número por zero");
else
setDisplay(result);
}
else if (operation.equals("x"))
setDisplay(calc.multiply(getDisplayText())+"");
}
private void cmdEqual(){
if (calc.isSetCurrentNumber())
if (inputMode){
processOperator();
inputMode = false;
clearAll = true;
}
}
private void cmdAC(){clear();}
private void cmdC(){setDisplay("0");}
private void cmdBksp(){
if (getDisplayText().length() == 1)
setDisplay("0");
else
setDisplay(getDisplayText().substring(0,(getDisplayText().length()-1)));
}
private void cmdPoint(){
if (clearDisplay || getDisplayText().equals("0")){
setDisplay("0.");
clearDisplay = false;
}
if (!getDisplayText().contains(".")){
setDisplay(getDisplayText()+".");
}
}
private void cmdPow(){
setDisplay(calc.pow(getDisplayText())+"");
clearAll = true;
inputMode = false;
}
private void cmdMoreLess(){
if (!getDisplayText().equals("0"))
if (getDisplayText().contains("-")){
setDisplay(getDisplayText().replace('-', ' ').trim());
}else
setDisplay("-"+getDisplayText());
}
private void cmdRaiz(){
String result = calc.sqrt(getDisplayText())+"";
if (result.equals("NaN")){
displayErro("Não existe Raiz de um número negativo");
}else
setDisplay(result);
clearAll = true;
inputMode = false;
}
private void cmdKeyTyped(KeyEvent e){
char c = e.getKeyChar();
if ( c >= '0' && c <= '9' ) {
cmdNumbers(String.valueOf(c-48));
}else if ( c == '+' || c == '-' ) {
cmdOperation(c+"");
}else if ( c == '*' ) {
cmdOperation("x");
}else if ( c == 'x') {
cmdOperation("x^y");
}else if ( c == '/') {
cmdOperation("/");
}else if ( c == '^' ) {
cmdPow();
}else if ( c == '.' || c == ',' ) {
cmdPoint();
}else if ( c == 10 ) {
cmdEqual();
}else if ( c == 8 ) {
cmdBksp();
}else if ( c== 27 ) {
cmdAC();
}
}
public static void createAndShowGUI() {
//Create and set up the window.
Calculator frame = new Calculator();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Calculator.createAndShowGUI();
}
});
}
}