Construindo uma calculadora básica em Java, com Swing – passo a passo

A melhor maneira de aprender a programar é programando na prática. Costumo dizer que dois tipos de programas são essenciais para se acostumar com uma linguagem de programação gráfica: calculadora e editor de texto. Com o primeiro, você aprende a utilizar estruturas de controle, operadores aritméticos e de comparação, além de estudar a implementação de ações em certos componentes. Com o segundo, a aprendizagem é estendida a manipulação de arquivos.

O Java possui uma API gráfica chamada Swing. Ela é independente do sistema operacional, de modo que os programas, executados em diferentes sistemas, possuem praticamente o mesmo visual. É com ela que construiremos nossa calculadora, passo a passo. Vamos começar!

Calculadora básica em Java, no Ubuntu 10.04

Calculadora básica em Java, no Ubuntu 10.04



O primeiro passo é dar um nome ao pacote onde ficarão os arquivos da calculadora. Usualmente, esses pacotes têm nomes como “br.com.algumacoisa”, mas você pode escolher qualquer nome, como “calculadora”. Depois, vamos importar os pacotes do AWT (para os eventos) e do Swing (para a interface).

package calculadora;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Calculadora básica, feita com Swing e ActionListener
 * @version 0.3 2010-03-14
 * @author Paulo Seikishi Higa
 */

Agora, vamos começar programando nossa classe “Calculadora”. Ela herdará a classe JFrame, do Swing, responsável pela janela principal, e implementará o ActionListener, para as ações dos cliques nos botões da calculadora.

A calculadora será montada com dois JPanel: o do visor (contendo o JTextField que mostrará o resultado) e o dos botões (contendo os números e as operações). Colocaremos um JTextField, que mostrará o resultado, e vários JButton, com os números, as operações, o botão de igual e o botão de zerar (C).

Para armazenar a operação que está sendo feita atualmente (adição, subtração, multiplicação ou divisão), basta utilizar uma variável (operacaoAritmetica) do tipo inteira (número, sem ponto flutuante). Você pode usar uma variável do tipo String (texto) e armazenar valores como “adição” nelas, mas isso pode complicar futuramente, caso você não conheça o Java muito bem.

public class Calculadora extends JFrame implements ActionListener {

    /**
     * Elementos Swing e AWT
     */
    private JPanel panVisor, panBotoes;
    private JTextField textVisor;
    private JButton btn1, btn2, btn3, btn4, btn5, btn6, btn7, btn8, btn9, btn0, btnAdicao, btnSubtracao, btnMultiplicacao, btnDivisao, btnIgual, btnC;
    /**
     * Variáveis de cálculo
     */
    double resultadoConta, valorAnterior, valorAtual = 0;
    int operacaoAritmetica = 0; // 1 para adição, 2 para subtração, 3 para multiplicação e 4 para divisão

Feito isso, vamos começar com o método construtor. Como o próprio nome diz, ele “construirá” a sua calculadora. O setBounds define a posição e o tamanho da nossa janela. O setTitle é o responsável pelo título dessa janela.

Para os botões, utilizaremos o GridLayout, que facilita a distribuição dos botões em linhas e colunas, assim, não teremos que definir coordenadas para posicionar os botões, por exemplo. Criar os botões é fácil, basta utilizar a sintaxe: nomeDoBotao = new JButton(“Texto do botão”).

Podemos, também, customizar nossa calculadora, alterando as fontes e as cores de fundo dos elementos, como no código mostrado abaixo.

    public Calculadora() {

        /**
         * Configurações da janela
         */
        setBounds(200, 200, 300, 300); // posição X, posição Y, largura e altura
        setTitle("Calculadora");

        /**
         * Definir os elementos no construtor
         */
        GridLayout gridBotoes = new GridLayout(4, 4, 2, 2); // linhas, colunas, espaçamento direita, espaçamento inferior
        panBotoes = new JPanel();
        panVisor = new JPanel();
        textVisor = new JTextField(16);
        btn1 = new JButton("1");
        btn2 = new JButton("2");
        btn3 = new JButton("3");
        btn4 = new JButton("4");
        btn5 = new JButton("5");
        btn6 = new JButton("6");
        btn7 = new JButton("7");
        btn8 = new JButton("8");
        btn9 = new JButton("9");
        btn0 = new JButton("0");
        btnAdicao = new JButton("+");
        btnSubtracao = new JButton("-");
        btnMultiplicacao = new JButton("*");
        btnDivisao = new JButton("/");
        btnIgual = new JButton("=");
        btnC = new JButton("C");

        /**
         * Setar configurações dos elementos
         */
        panVisor.setBackground(Color.DARK_GRAY);
        panBotoes.setBackground(Color.GRAY);
        panBotoes.setLayout(gridBotoes);
        textVisor.setFont(new Font("Arial", Font.BOLD, 18));
        textVisor.setHorizontalAlignment(JTextField.RIGHT);
        textVisor.setEditable(false);
        btn1.setFont(new Font("Arial", Font.BOLD, 28));
        btn2.setFont(new Font("Arial", Font.BOLD, 28));
        btn3.setFont(new Font("Arial", Font.BOLD, 28));
        btn4.setFont(new Font("Arial", Font.BOLD, 28));
        btn5.setFont(new Font("Arial", Font.BOLD, 28));
        btn6.setFont(new Font("Arial", Font.BOLD, 28));
        btn7.setFont(new Font("Arial", Font.BOLD, 28));
        btn8.setFont(new Font("Arial", Font.BOLD, 28));
        btn9.setFont(new Font("Arial", Font.BOLD, 28));
        btn0.setFont(new Font("Arial", Font.BOLD, 28));
        btnAdicao.setFont(new Font("Arial", Font.BOLD, 28));
        btnSubtracao.setFont(new Font("Arial", Font.BOLD, 28));
        btnMultiplicacao.setFont(new Font("Arial", Font.BOLD, 28));
        btnDivisao.setFont(new Font("Arial", Font.BOLD, 28));
        btnIgual.setFont(new Font("Arial", Font.BOLD, 28));
        btnC.setFont(new Font("Arial", Font.BOLD, 28));

Com os elementos já configurados, vamos adicioná-los a nossa janela! Primeiramente, adicionaremos os dois painéis: o do visor e o dos botões. Esses painéis, do BorderLayout, podem ser posicionados com o Center (fica no “centro” da tela) e com os pontos cardeais: North, South, West e East. No nosso caso, utilizaremos o North no visor e o Center nos botões.

Demonstração do BorderLayout

Demonstração do BorderLayout

Depois, é só adicionar os botões nos painéis, assim: nomeDoPainel.add(nomeDoElemento). É importante lembrar que, como estamos utilizando um painel GridLayout dentro de outro, os botões serão exibidos da esquerda para a direita, de cima para baixo. Sendo assim, tome cuidado para adicionar os botões na ordem correta.

    /**
         * Adicionar os elementos nos JPanel()
         */
        add(panVisor, "North");
        add(panBotoes, "Center");
        panVisor.add(textVisor);
        panBotoes.add(btn7);
        panBotoes.add(btn8);
        panBotoes.add(btn9);
        panBotoes.add(btnAdicao);
        panBotoes.add(btn4);
        panBotoes.add(btn5);
        panBotoes.add(btn6);
        panBotoes.add(btnSubtracao);
        panBotoes.add(btn1);
        panBotoes.add(btn2);
        panBotoes.add(btn3);
        panBotoes.add(btnMultiplicacao);
        panBotoes.add(btn0);
        panBotoes.add(btnIgual);
        panBotoes.add(btnC);
        panBotoes.add(btnDivisao);

Agora, começaremos a trabalhar com os eventos dos botões, via ActionListener. No caso dos botões numéricos, o número será jogado no visor da calculadora quando o usuário clicar nele. Para isso, teremos que pegar o texto que já está no visor (com o método getText) e concatenar com esse número (caso contrário, nunca conseguiremos inserir números de dois ou mais dígitos na calculadora).

        /**
         * Setar eventos nos botões de números
         */
        btn1.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "1");
            }
        });
        btn2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "2");
            }
        });
        btn3.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "3");
            }
        });
        btn4.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "4");
            }
        });
        btn5.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "5");
            }
        });
        btn6.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "6");
            }
        });
        btn7.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "7");
            }
        });
        btn8.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "8");
            }
        });
        btn9.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "9");
            }
        });
        btn0.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                textVisor.setText(textVisor.getText() + "0");
            }
        });

Lembra quando definimos a variável inteira operacoesAritmeticas no início do programa? Ela será usada agora, nos botões dos operadores aritméticos. Ao clicar no botão de adição, o valor da operacaoAritmetica será definido como 1, por exemplo. Para quê? Para nossa calculadora saber, posteriormente, o que fazer quando o usuário clicar no botão de igual. Esses botões também armazenarão o número que estava na tela em uma variável, que será utilizada depois e limpará o visor da calculadora, deixando o usuário entrar com o próximo número.

No botão “C”, de zerar, as variáveis são retornadas para 0 e o texto do visor ficará nulo. Isso deixará a calculadora “como nova”.

        /**
         * Setar eventos nos botões de operações aritméticas
         */
        btnAdicao.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAnterior = Double.parseDouble(textVisor.getText());
                textVisor.setText(null);
                operacaoAritmetica = 1;
            }
        });
        btnSubtracao.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAnterior = Double.parseDouble(textVisor.getText());
                textVisor.setText(null);
                operacaoAritmetica = 2;
            }
        });
        btnMultiplicacao.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAnterior = Double.parseDouble(textVisor.getText());
                textVisor.setText(null);
                operacaoAritmetica = 3;
            }
        });
        btnDivisao.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAnterior = Double.parseDouble(textVisor.getText());
                textVisor.setText(null);
                operacaoAritmetica = 4;
            }
        });
        btnC.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAnterior = 0;
                valorAtual = 0;
                operacaoAritmetica = 0;
                textVisor.setText(null);
            }
        });

Agora vem o “cérebro” da calculadora: o evento no botão de igual. Ele armazenará o número que está no visor em uma variável, para facilitar o cálculo e nós usaremos o switch para programar as operações aritméticas.

No caso da divisão, lembre-se de que não existe divisão por zero. Assim, se o último valor do visor (valorAtual) for zero, podemos exibir uma mensagem na tela do usuário, informando sobre o problema. Caso contrário, o programa calcula e armazena o resultado na variável resultadoConta.

Divisão por zero

Divisão por zero

Caso o programa tenha dado “tilt” por algum problema desconhecido, o switch irá para o default, que mostrará a mensagem “Erro: operador inválido ou elementos insuficientes“.

Por fim, jogaremos o valor da variável resultadoConta no nosso textVisor, o visor da calculadora.

        /**
         * Setar eventos no cálculo do resultado (botão =)
         */
        btnIgual.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                valorAtual = Double.parseDouble(textVisor.getText());
                switch (operacaoAritmetica) {
                    case 1:
                        resultadoConta = valorAnterior + valorAtual;
                        break;
                    case 2:
                        resultadoConta = valorAnterior - valorAtual;
                        break;
                    case 3:
                        resultadoConta = valorAnterior * valorAtual;
                        break;
                    case 4:
                        if (valorAtual == 0) {
                            JOptionPane.showMessageDialog(null, "Erro: impossível dividir por zero");
                        } else {
                            resultadoConta = valorAnterior / valorAtual;
                        }
                        break;
                    default:
                        JOptionPane.showMessageDialog(null, "Erro: operador inválido ou elementos insuficientes");
                        break;
                }
                textVisor.setText(String.valueOf(resultadoConta));
            }
        });

As configurações finais ficam por conta do não-redimensionamento da janela (para não distorcer os botões) e o setDefaultCloseOperation(EXIT_ON_CLOSE), que retira o programa da memória após o usuário clicar no botão de fechar.

        /**
         * Configurações finais da janela - tornar visível, evitar redimensionamento
         */
        setVisible(true);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new Calculadora();
    }

    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

No método principal main(), chamaremos nosso método construtor Calculadora() e também adicionaremos uma exceção dos eventos actionPerformed, caso algum erro ocorra nos botões.

Fim! Agora, é só gerar o arquivo executável *.jar na sua IDE ou um bytecode com o compilador javac, por linha de comando. Se preferir, pode baixar o executável e o código-fonte aqui.

20 thoughts on “Construindo uma calculadora básica em Java, com Swing – passo a passo

  1. Parabéns pelo trabalho, excelente mesmo.

    estou aprendendo java, e me ajudou muito.
    Agora estou pensando como implementar a soma de vários números consecutivos,
    exemplo 1 + 1 + 1 = ?(3), nessa implementação, ela não resolve esse caso, pensei em após cada operação, chamar o evento igual, mas como estou aprendendo , não consegui! :p

    se puder me responder, ficarei grato.
    Abraço, e novamente parabéns!

  2. Pingback: Material sobre Desenvolvimento GUI JAVA com Swing | Kaléu Caminha

  3. Nossa, muito interessante, gosto de programação, mas até então só conhecia o xhtml básico, mas depois de ver o poder do Java nas mãos de quem realmente sabe usar, fiquei impressionado, mas não sei nada sobre compilação etc. nem como colocar esse código pra funcionar perfeitamente no windows, será que você não poderia postar algo sobre isso ?

  4. e como faco para implementar usando implements?adicionando esses novos abaixo:
    . (ponto)
    backspace (eliminar o último caracter digitado)
    sqrt (raiz quadrada)
    % (percentagem)

  5. Meu broher,

    Sou muito feliz por você poder me ajudar com este tutorial, estava eu precisando exatamente de um exemplo desse tipo, e me ajudou muito.

    Obrigado e valeu pela pela força. É sempre bom poder dividir os conhecimentos.

  6. Obrigado por publicar tutoriais que podem ser uteis ao aprendizado de outras pessoas ,continua assim
    tudo de bom pra você .Valeu!!!!!!!

  7. Parabéns, neste mundo ainda tem alguém que compartilha seus conhecimentos com os outros. Esta atitude é válida, pois você aprende muito mais!!!!!!!!!!!!!!!

  8. Caso seja realizada a operação 2+3+4 (somar 3 ou mais numeros antes de apertar o = ) ocorrerá um erro. Você não sabe como consertar isso?

  9. Muito boa sua calculadora e código bem escrito….

    Uma sugestão pra operações é no lugar de um inteiro usar um enum, exemplo:

    public enum Operacoes { sum, sub, mult, div, none };

    public Operacoes operacaoAritmetica;

    Obs: É preciso fazer substituições no switch (Ex: case soma: …. break; case div: … break;) e nas atribuições (Ex: operacaoAritmetica = Operacoes.soma ;)

    Fica mais fácil caso precise de mais operações, evita que a pessoa tenha que ficar voltando o código para saber qual número corresponde à qual operação e fica até mais bonitinho =D

    Abraços…

  10. Adorei seu tutorial,muito didático…obrigada por dividir seu conhecimento estava com problemas com o posicionamento do gridlayout não sou muito boa nisso…

  11. Caraaaaaaaaaaaaaaaca!

    Muito obrigada por compartilhar, você nem imagina o quanto ajudou ^^

    Não gosto de java… e ai já criei um bloqueio, rsrs.

    Valeu!

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>