Calculadora em JAVA

13 respostas
eve_bsi

[i]Oi pessoal!
Entao estou desenvolvendo uma calculadora em JAVA, e estou precisando de uma ajudinha.
Na verdade minha calculadora ja esta funcionando, só q assim ela nao faz calculos diretos. Ex.: 2+4-5*6=6
ela esta calculando assim 2 + 4 =6 - 5 =1 * 6 =6
se fizer como estou qrendo ela esta a resposta dela 30 pq ela calcula somente os 2 ultimos valores informados!

bom sera q alguem pode m ajuda?

obrigada
:idea: :idea: :idea:

13 Respostas

M

Kra, tu vai ter q fazer um troço muito xato separando Strings para descobrir os ultimos numeros e operações. Recomendo que uses a classe StringTokenizer (http://www.guj.com.br/posts/list/33581.java) para separar a String em tokens.

T

Como está o seu código?
Se você rodar essa expressão no java, por Default ele seguirá a sequência matemática, respeitando a ordem: * / + -.

eve_bsi

Meu código esta ae!

eve_bsi
package janelas;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Componentes extends JFrame implements ActionListener {
	public JButton btn0;
	public JButton btn1;
	public JButton btn2;
	public JButton btn3;
	public JButton btn4;
	public JButton btn5;
	public JButton btn6;
	public JButton btn7;
	public JButton btn8;
	public JButton btn9;
	public JButton btnsep;
	public JButton btnresult;
	public JButton btnsoma;
	public JButton btnsubt;
	public JButton btnmult;
	public JButton btndiv;
	public JButton btnlimpa;
	String operacao = "";
	double armazena = 0;
	double calculo = 0;
	JTextField edicao;

	public static void main(String[] args) {
		JFrame janela = new Componentes();
		janela.setVisible(true); // pra não ter q redimensionar a janela pra
		// aparece alguma coisa

		// tem que ter isso para reconhecer o comando de "clicar no botão"
		WindowListener x = new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		};
		janela.addWindowListener(x);
	}

	public Componentes() {
		setTitle("Calculadora");
		setSize(600, 600);
		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension d = tk.getScreenSize(); // ­obtém dimensão da tela
		setVisible(true);
		setResizable(false); // não permite redimensionar o formulario
		setLocation(d.width / 3, d.height / 3); // -define localização tela
		getContentPane().setLayout(new BorderLayout());

		// Cria o formulario onde serão inseridos os componentes
		JPanel formulario = new JPanel(null);
		setSize(300, 250);
		formulario.setBackground(Color.WHITE);

		//--------- Cria um label na tela --------- 
		JLabel label = new JLabel("CALCULADORA PADRÃO");
		label.setForeground(Color.BLUE);
		label.setBounds(70, 10, 150, 20);
		formulario.add(label);

		//--------- Cria uma caixa de edição --------- 
		edicao = new JTextField();
		edicao.setForeground(Color.RED);
		edicao.setBounds(40, 40, 170, 20);
		this.getContentPane().add(edicao);
		edicao.setEditable(false);
		formulario.add(edicao);
		edicao.setBackground(Color.WHITE);

		//--------- cria botão 1 --------- 
		btn1 = new JButton("1");
		btn1.setBackground(Color.WHITE);
		btn1.setBounds(30, 70, 50, 25);
		this.getContentPane().add(btn1);
		btn1.setEnabled(true);
		btn1.addActionListener(this);
		formulario.add(btn1);

		// --------- cria botão 2 --------- 
		btn2 = new JButton("2");
		btn2.setBackground(Color.WHITE);
		btn2.setBounds(90, 70, 50, 25);
		this.getContentPane().add(btn2);
		btn2.setEnabled(true);
		btn2.addActionListener(this);
		formulario.add(btn2);

		// --------- cria botão 3 --------- 
		btn3 = new JButton("3");
		btn3.setBackground(Color.WHITE);
		btn3.setBounds(150, 70, 50, 25);
		this.getContentPane().add(btn3);
		btn3.setEnabled(true);
		btn3.addActionListener(this);
		formulario.add(btn3);

		// --------- cria botão 4 --------- 
		btn4 = new JButton("4");
		btn4.setBackground(Color.WHITE);
		btn4.setBounds(30, 100, 50, 25);
		this.getContentPane().add(btn4);
		btn4.setEnabled(true);
		btn4.addActionListener(this);
		formulario.add(btn4);

		// --------- cria botão 5 --------- 
		btn5 = new JButton("5");
		btn5.setBackground(Color.WHITE);
		btn5.setBounds(90, 100, 50, 25);
		this.getContentPane().add(btn5);
		btn5.setEnabled(true);
		btn5.addActionListener(this);
		formulario.add(btn5);

		// --------- cria botão 6 --------- 
		btn6 = new JButton("6");
		btn6.setBackground(Color.WHITE);
		btn6.setBounds(150, 100, 50, 25);
		this.getContentPane().add(btn6);
		btn6.setEnabled(true);
		btn6.addActionListener(this);
		formulario.add(btn6);

		//--------- cria botão 7 --------- 
		btn7 = new JButton("7");
		btn7.setBackground(Color.WHITE);
		btn7.setBounds(30, 130, 50, 25);
		this.getContentPane().add(btn7);
		btn7.setEnabled(true);
		btn7.addActionListener(this);
		formulario.add(btn7);

		// --------- cria botão 8 --------- 
		btn8 = new JButton("8");
		btn8.setBackground(Color.WHITE);
		btn8.setBounds(90, 130, 50, 25);
		this.getContentPane().add(btn8);
		btn8.setEnabled(true);
		btn8.addActionListener(this);
		formulario.add(btn8);

		// --------- cria botão 9 --------- 
		btn9 = new JButton("9");
		btn9.setBackground(Color.WHITE);
		btn9.setBounds(150, 130, 50, 25);
		this.getContentPane().add(btn9);
		btn9.setEnabled(true);
		btn9.addActionListener(this);
		formulario.add(btn9);

		//--------- cria botão 0 --------- 
		btn0 = new JButton("0");
		btn0.setBackground(Color.WHITE);
		btn0.setBounds(90, 160, 50, 25);
		this.getContentPane().add(btn0);
		btn0.setEnabled(true);
		btn0.addActionListener(this);
		formulario.add(btn0);

		//--------- cria botão virgula(,) --------- 
		btnsep = new JButton(",");
		btnsep.setBackground(Color.WHITE);
		btnsep.setBounds(30, 160, 50, 25);
		this.getContentPane().add(btnsep);
		btnsep.setEnabled(true);
		btnsep.addActionListener(this);
		formulario.add(btnsep);

		// --------- cria botão resultado (=) --------- 
		btnresult = new JButton("=");
		btnresult.setBackground(Color.WHITE);
		btnresult.setBounds(150, 160, 50, 25);
		this.getContentPane().add(btnresult);
		btnresult.setEnabled(true);
		btnresult.addActionListener(this);
		formulario.add(btnresult);

		//--------- cria botão soma (+) --------- 
		btnsoma = new JButton("+");
		btnsoma.setBackground(Color.WHITE);
		btnsoma.setBounds(220, 70, 50, 25);
		this.getContentPane().add(btnsoma);
		btnsoma.setEnabled(true);
		btnsoma.addActionListener(this);
		formulario.add(btnsoma);

		//--------- cria botão subtração (-)--------- 
		btnsubt = new JButton("-");
		btnsubt.setBackground(Color.WHITE);
		btnsubt.setBounds(220, 100, 50, 25);
		this.getContentPane().add(btnsubt);
		btnsubt.setEnabled(true);
		btnsubt.addActionListener(this);
		formulario.add(btnsubt);

		//--------- cria botão multiplicação (*) --------- 
		btnmult = new JButton("*");
		btnmult.setBackground(Color.WHITE);
		btnmult.setBounds(220, 130, 50, 25);
		this.getContentPane().add(btnmult);
		btnmult.setEnabled(true);
		btnmult.addActionListener(this);
		formulario.add(btnmult);

		//--------- cria botão divisão (/)--------- 
		btndiv = new JButton("/");
		btndiv.setBackground(Color.WHITE);
		btndiv.setBounds(220, 160, 50, 25);
		this.getContentPane().add(btndiv);
		btndiv.setEnabled(true);
		btndiv.addActionListener(this);
		formulario.add(btndiv);

		//--------- cria botão limpa (C)--------- 
		btnlimpa = new JButton("C");
		btnlimpa.setBackground(Color.WHITE);
		btnlimpa.setBounds(213, 40, 50, 19);
		this.getContentPane().add(btnlimpa);
		btnlimpa.setEnabled(true);
		btnlimpa.addActionListener(this);
		formulario.add(btnlimpa);

		this.getContentPane().add(formulario, BorderLayout.CENTER);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	public void actionPerformed(ActionEvent e) {
		double aux;

		Object obj = e.getSource();

		if (edicao.getText().equals("")) { // equals =&gt comparação de objetos
			aux = 0;
		} else {
			aux = Double.valueOf(edicao.getText());
		}

		/*---------- BOTAO DA VIRGULA ----------
		if (obj == btnsep) { 
			if (aux == 0){
				edicao.setText("0."); 

			}else{
				if (((edicao.getText()).indexOf(".")) ==-1){
					edicao.setText(edicao.getText()+".");

				}

			}

		} 	
		
		//--------- OPERAÇÕES ----------
		if (obj == btnsoma) {
			edicao.setText("");
			armazena = aux;
			operacao = "+";
		}
		if (obj == btnsubt) {
			edicao.setText("");
			armazena = aux;
			operacao = "-";
		}
		if (obj == btnmult) {
			edicao.setText("");
			armazena = aux;
			operacao = "*";
		}
		if (obj == btndiv) {
			edicao.setText("");
			armazena = aux;
			operacao = "/";
		}
		//---------- RESULTADO ---------
		if (obj == btnresult) {
			if (operacao == "+") {
				calculo = armazena + aux;
				edicao.setText("" + calculo);
			}
			if (operacao == "-") {
				calculo = armazena - aux;
				edicao.setText("" + calculo);
			}
			if (operacao == "*") {
				calculo = armazena * aux;
				edicao.setText("" + calculo);
			}
			if (operacao == "/") {
				calculo = armazena / aux;
				edicao.setText("" + calculo);
			}
			armazena = calculo;
		}
		//---------- NÚMEROS ----------
		if (obj == btn1) {			
			edicao.setText(edicao.getText() + "1");
		}
		if (obj == btn2) {
			edicao.setText(edicao.getText() + "2");
		}
		if (obj == btn3) {
			edicao.setText(edicao.getText() + "3");
		}
		if (obj == btn4) {
			edicao.setText(edicao.getText() + "4");
		}
		if (obj == btn5) {
			edicao.setText(edicao.getText() + "5");
		}
		if (obj == btn6) {
			edicao.setText(edicao.getText() + "6");
		}
		if (obj == btn7) {
			edicao.setText(edicao.getText() + "7");
		}
		if (obj == btn8) {
			edicao.setText(edicao.getText() + "8");
		}
		if (obj == btn9) {
			edicao.setText(edicao.getText() + "9");
		}
		if (obj == btn0) {
			edicao.setText(edicao.getText() + "0");
		}
		// -------- LIMPAR CONTEÚDO ---------
		if (obj == btnlimpa) {
			edicao.setText("");
		}
	}
}
H

Se eu entendi direito, sua calculadora é na verdade um avaliador de expressões aritméticas, certo? O indivíduo vai digitando 1+3*5/6… e o resultado só vai ser mostrado no final (quando pressionar o botão resultado)?

Se for assim, e se o seu problema é fazer as operações seguindo a precedência dos operadores, você teria que transformar a expressão digitada na forma infixa para a forma pós-fixa.

Exemplo:
Infixa: 2+46-5
Pós fixa: 2 4 6
+5-

E o resultado seria extraído da expressão pós fixa.

//---- CONVERTER PARA PÓS-FIXA
//topo_da_pilha(): método que  o operador que está no topo da pilha
//e: estrutura que contém a expressão digitada pelo usuário, seja List, Vector, array...
//e[i]: falta de criativiade minha; é prá indicar cada token da estrutura

/*prec: método que você criaria (ou se preferir colocar direto...) para retornar um 
  valor comparável para a precedência dos operadores. Esse algoritmo considera 
  prec(*) == 2, prec(/) == 2, prec (+) == 1, prec(-) == 1;
*/

//ehVazia(): verificação de que ainda existem elementos na pilha
//armazena: metodo que armazena os tokens, na forma pós-fixa, para ser avaliada depois.


enquanto (e){
  se e[i] é número{
   armazena (e[i]);
   continua;
  }

  se token é operador {
    se (prec(e[i]) <= prec(topo_da_pilha())){
      enquanto (prec(e[i]) <= prec(topo_da_pilha()) && !ehVazia(pilha)){
        armazena (topo_da_pilha());
        desempilha();

      }
    } senao 
      empilha (e[i]);
  }
}

enquanto (! ehVazia (pilha)){
  aux = topo_da_pilha();
  armazena(aux);
  desempilha();
}
//-------AVALIAR A EXPRESSAO E OBTER O RESULTADO
//exp_pos_fixa: expressao na forma pós-fixa, resultado do processamento anterior
/*faz_op: falta de criatividade de novo; é um método que recebe os dois números 
  e a operação (provavelmente um caracter), faz a operação e retorna o resultado
  para aux
*/



enquanto (exp_pos_fixa){
  se e[i] é número {
    empilha;
    continua;
  }

  se e[i] é operador {
    y = topo_da_pilha();
    desempilha();
    x = topo da pilha();
    desempilha();

    aux = faz_op (x, y, e[i]);
    empilha (aux);
  }
}

resultado = topo_da_pilha();
desempilha();
return resultado;

continua…

H

No caso da expressão: 2+4*6-5

CONVERSÃO:

expressão   exp_pós_fixa   pilha(topo->base)
2+4*6-5     VAZIA          VAZIA
+4*6-5      2              VAZIA
4*6-5       2              +
*6-5        2 4            +
6-5         2 4            * +
-5          2 4 6          * +
5           2 4 6 * +      -
VAZIA       2 4 6 * + 5    -
VAZIA       2 4 6 * + 5 -  VAZIA

exp_pós_fixa = 2 4 6 * + 5 -
AVALIAÇÃO

exp_pós_fixa         pilha(topo->base)
2 4 6 * + 5 -        VAZIA
4 6 * + 5 -          2
6 * + 5 -            4 2
* + 5 -              6 4 2
+ 5 -                24 2 (x = 4, y = 6, x * y = 24, empilha 24)
5 -                  26 (x = 2, y = 24, x + y = 26, empilha 26
-                    5 26
VAZIA                21 (x = 26, y = 5, x - y = 21, empilha 21)

resultado = topo_da_pilha() = 21

Espero ter ajudado…

Marky.Vasconcelos

Ps: Poste o código entre as tags [code] e [/ code] e não [quote]

rodrigo_gomes

Olá,

Não é mais facil vc simplesmente ir concatenando o que o usuario digitar e no final vc usar algo como
http://www.beanshell.org/ ou http://groovy.codehaus.org/ para resolver a expressão pra vc?

[]´s

H

Bom, provavelmente é mais fácil mesmo…

A questão é o que você quer fazer… Se você quer entender o funcionamento da avaliação de expressões e ver na prática o resultado (o que eu acho que é o caso, porque dificilmente alguém vai implementar uma calculadora em Java com outra finalidade), então a maneira que eu conheço é usando a expressão pós-fixa.

Agora, se você quer apenas criar a interface, sem ter que se preocupar com o como o resultado é gerado, adotando a visão de caixa preta sopbre o componente, aí com certeza é mais fácil mesmo.


http://www.beanshell.org/ ou http://groovy.codehaus.org/ para resolver a expressão pra vc?

Não conheço nenhuma das ferramentas citadas, mas, pelo post, imagino que seja esse o caso.

eve_bsi

hadilson:
Se eu entendi direito, sua calculadora é na verdade um avaliador de expressões aritméticas, certo? O indivíduo vai digitando 1+3*5/6… e o resultado só vai ser mostrado no final (quando pressionar o botão resultado)?

Não não… assim na verdade eu qro q ela calcule assim. se eu quiser resolver a expressao ‘2-1+54’ eu tenho q resolver da seguinte maneira: digito nº ‘2’ digito a operação ‘-’ o outro nº ‘1’ e clico no botão ‘=’ me da a resultado ‘1’ entao clico na operação ‘+’ e no nº ‘5’ e entao tenho q clicar novamente no botao ‘=’ para m retornar o resultado ‘6’ e assim consecutivamente, nao consigo fazer a operação inteira “diretamente” -> '2-1+54’ se eu fizer isso ela m retorna o valor ‘20’ q éo resultado de ‘5*4’ e o resultado da expressao inteira é ‘24’, no caso a minha calculadora está pegando somente os 2 ultimos valores.
ele nao armazena a expressao inteira pra m dar o resultado de tudo.
sera q esse caso q vc colocou tbm adiantaria para o q eu estou precisando?

obrigada :wink:

H

eve_bsi,
Ok, seu problema então é como armazenar a expressão inteira, e fazer com que a calculadora calcule a expressão inteira, sem ter que fazer pedaço por pedaço? É isso?

Prá armazenar, uma idéia…

...
    double armazena = 0;   
    double calculo = 0;   
    JTextField edicao; 
    
    Vector<String> expr = new Vector<String>();

...
        String temp = (edicao.getText().equals("")) ? "0" : edicao.getText();
        if (obj == btnsoma) {  
 
            //coloca uma String com o número digitado
            expr.addElement(temp);
            edicao.setText("");

            //coloca uma String com a operação escolhida
            expr.addElement("+");
        }   
        if (obj == btnsubt) {   
            expr.addElement(temp);
            edicao.setText("");   
            expr.addElement("-");
        }   
        if (obj == btnmult) {   
            expr.addElement(temp);
            edicao.setText("");   
            expr.addElement("*");
        }   
        if (obj == btndiv) {   
            expr.addElement(temp);
            edicao.setText("");   
            expr.addElement("/");
        }
...
    if (obj == btnresult) {
      //a última coisa digitada antes do resultado deve ser um número
      expr.addElement(temp);

/*aqui agora, você tem na variável expr um Vector de Strings, contendo os números
  e as operações que o indivíduo digitou. Tipo: "2" "-" "1" "+" ...
  Agora é  implementar a sua estratégia de avaliação/cálculo.
  Se você for usar uma das ferramentas citadas pelo rodrigo_gomes,
  eu não conheço, mas pelo que ele falou, você precisa concatenar
  prá uma String. Nesse caso,
*/
  String expr_pra_avaliar = "";
  for (int i = 0; i < expr.size(); i++)
    expr_pra_avaliar += expr.elementAt(i);

//aqui, expr_pra_avaliar tem a expressão na forma de String (tipo "2-1+5*4"), daí é  você ver como usar as ferramentas
...

O que eu coloquei serve para avaliar a expressão, considerando que você já tenha a expressão inteira. É uma outra opção…

É preciso ainda observar que, tanto com a forma pós-fixa, quanto com as ferramentas (eu imagino), a calculadora vai respeitar a precedência de operadores. E nesse caso, a expressão 2-1+5*4 será igual a 21.

Mas se eu tiver entendido errado de novo, avisa aí… (ando meio lesado)

eve_bsi

hadilson:
eve_bsi,
Ok, seu problema então é como armazenar a expressão inteira, e fazer com que a calculadora calcule a expressão inteira, sem ter que fazer pedaço por pedaço? É isso?

Isso meu problema é esse mesmo, mas acontece q o eu nao digito (a calculadora naum pega dados do teclado, pra isso tem q fazer mais um tanto de verificação, pq o usuario pode digita letras, e como ainda estou começando a mecher em java, nao vou fazer isso por enquanto) no caso ele tem na tela a calculadora (tipo uma calculadora padrao do windows) só q ao invés de eu digitar (teclado) eu aperto os botoes um por um… mas a expressao naum fica na tela até eu aperta o sinal de ‘=’ (q seria o caso do q vc passou do pós-fixa) a cada número ou operação q eu aperte a tela limpa… e vai armazenando, mas acontece q no caso se for fazer uma expressao com mais de 2 numeros, eu tenho q aperta o ‘=’ a cada operação na expressao…
deu pra entender mais ou menor…
ontem estava mechendo na calculadora, e eu acho q o mais facil seria eu criar mais uma variavel para armazenar, e nessa variavel, fazer a verificação se ja existe calculos sendo realizados, mas acontece q estou tendo dificuldades de saber ond fazer essa verificação no meu código…
bom o meu código esta um pouco acima… para dar uma noçao do q estou fazendo…
okey
brigada

H

Pois é, nesse último trecho de código que eu passei, que foi uma alteração do seu código, o usuário vai pressionando os botões na tela, tipo 12 + 2 - 6 e só quando ele apertar o igual é que o resultado vai ser apresentado. Mas enquanto o usuários vai informando a expressão no teclado da calculadora, seja com dois ou com dez números, a expressão TODA vai sendo armazenada na variável expr.

Da forma que eu coloquei, o usuário não vai precisar colocar apertar igual a cada operação da expressão, só no final…

Criado 23 de agosto de 2007
Ultima resposta 30 de ago. de 2007
Respostas 13
Participantes 6