- A função +/- inclui o sinal do negativo à direita do número. Poderia usar a excessão que usei na função getResult para resolver a estética, mas então seria impossível usar o número com as outras funções (pois a conversão de string para double supõe aquela posição do sinal negativo). Então esse detalhe foi ignorado para permitir a funcionalidade da calculadora.
- Quando se aperta o botão ".", o visor mostra os números de forma errada. Ainda é um mistério para mim o porquê da chamada
display.append(".");
colocar o ponto antes dos números. Funcionalmente, no entanto, está tudo perfeito, e o resultado sempre é imprimido de maneira correta. - Contas com inteiros sempre contém casas decimais, por causa da conversão para double. Isso pode ser consertado facilmente, mas não achei necessário para o exercício.
Para que os leitores possam rodar o código com mais facilidade, postarei todo o projeto. As partes modificadas desde sexta-feira são dentro da função actionPerformed, mais todas as funções à partir da clear.
Cuidado apenas na hora de copiar e colar o código em um IDE, pois a formatação pode ter sido modificada pelo código html do blog. Vou incluir uma animação da calculadora funcionando para os menos interessados em programação.
1: package calculator;
2: import java.awt.*;
3: import javax.swing.*;
4: import java.awt.event.*;
5: //@author Gabriel
6: public class Calculator extends JFrame implements ActionListener{
7: //Declarando variáveis
8: JPanel[] row = new JPanel[5];
9: JButton[] button = new JButton[19];
10: //colocando todas as strings em um único vetor
11: String[] buttonString = {"7","8","9","+",
12: "4","5","6","-",
13: "1","2","3","*",
14: ".","/","C","sqrt",
15: "+/-","=","0"};
16: //Definindo tamanho do display e botões
17: Dimension displayDimension = new Dimension(300, 35);
18: Dimension regularDimension = new Dimension(45, 40);
19: Dimension rColumnDimension = new Dimension(60, 40);
20: Dimension zeroButtonDimension = new Dimension(90, 40);
21: boolean[] function = new boolean[4]; //vetor para armazenar a função pedida pelo usuário
22: double[] temporary = {0,0}; //variáveis auxiliares para calcular resultados
23: JTextArea display = new JTextArea(1,20);
24: boolean decimal = false; //para garantir que a função "." não possa ser inserida mais de uma vez
25: public static void main(String[] args)
26: {
27: Calculator c = new Calculator();
28: }
29: Calculator()
30: {
31: //o tutorial não explica a necessidade dessa função super. No entanto, procurando na internet, parece que
32: //ela é responsável por invocar o construtor pai
33: //super("Calculator");
34: setDesign();
35: setSize(380,250);
36: setResizable(false); //se o windows não deixa ajustar o tamanho da calculadora, por que eu iria?
37: setDefaultCloseOperation(EXIT_ON_CLOSE);
38: //Como vou querer 5 linhas e 5 colunas
39: GridLayout grid = new GridLayout(5,5);
40: setLayout(grid);
41: //inicializando o vetor de funções
42: for(int i=0;i<4 br="" i=""> function[i] = false;
43: FlowLayout f1 = new FlowLayout(FlowLayout.CENTER); //utilizamos a função FlowLayout para posicionar as colunas e linhas
44: FlowLayout f2 = new FlowLayout(FlowLayout.CENTER,1,1); //1,1 são os espaçamentos horizontais e verticais em relação a f1
45: for(int i=0; i<5 br="" i=""> row[i] = new JPanel();
46: row[0].setLayout(f1);
47: for(int i = 1; i<5 br="" i=""> row[i].setLayout(f2);
48: //agora as linhas e colunas já podem ser usadas!
49: for(int i = 0; i < 19; i++) //coloca as características dos botões
50: {
51: button[i] = new JButton();
52: button[i].setText(buttonString[i]);
53: button[i].addActionListener((ActionListener) this); //será usado para implementação do funcionamento do botão no futuro
54: }
55: display.setEditable(false); //não seria bom permitir o usuário editar o display
56: display.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); //Por alguma razão desconhecida por mim, calculadoras geralmente tem o display escrevendo da direita para a esquerda
57: //definindo tamanhos!
58: display.setPreferredSize(displayDimension);
59: for(int i = 0; i < 14; i++)
60: button[i].setPreferredSize(regularDimension);
61: for(int i = 14; i < 18; i++)
62: button[i].setPreferredSize(rColumnDimension);
63: button[18].setPreferredSize(zeroButtonDimension);
64: //colocando o display e os botões nas linhas e colunas
65: row[0].add(display);
66: add(row[0]);
67: for(int i = 0; i < 4; i++)
68: row[1].add(button[i]);
69: row[1].add(button[14]);
70: add(row[1]);
71: for(int i = 4; i < 8; i++)
72: row[2].add(button[i]);
73: row[2].add(button[15]);
74: add(row[2]);
75: for(int i = 8; i < 12; i++)
76: row[3].add(button[i]);
77: row[3].add(button[16]);
78: add(row[3]);
79: row[4].add(button[18]);
80: for(int i = 12; i < 14; i++)
81: row[4].add(button[i]);
82: row[4].add(button[17]);
83: add(row[4]);
84: setVisible(true);
85: }
86: //necessário para possibilitar a compilação
87: public final void setDesign() {
88: try {
89: UIManager.setLookAndFeel(
90: "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
91: } catch(Exception e) {
92: }
93: }
94: public void actionPerformed(ActionEvent ae)
95: {
96: if(ae.getSource() == button[0]) //7
97: display.append("7");
98: if(ae.getSource() == button[1]) //8
99: display.append("8");
100: if(ae.getSource() == button[2]) //9
101: display.append("9");
102: if(ae.getSource() == button[3]) //Soma
103: {
104: temporary[0] = Double.parseDouble(display.getText());
105: for(int i = 0; i < 4; i++) //Para evitar conflito quando multiplas teclas de função são apertadas
106: function[i] = false;
107: function[0] = true;
108: decimal = false;
109: display.setText("");
110: }
111: if(ae.getSource() == button[4]) //4
112: display.append("4");
113: if(ae.getSource() == button[5]) //5
114: display.append("5");
115: if(ae.getSource() == button[6]) //6
116: display.append("6");
117: if(ae.getSource() == button[7]) //Subtração
118: {
119: temporary[0] = Double.parseDouble(display.getText());
120: for(int i = 0; i < 4; i++)
121: function[i] = false;
122: function[1] = true;
123: decimal = false;
124: display.setText("");
125: }
126: if(ae.getSource() == button[8]) //1
127: display.append("1");
128: if(ae.getSource() == button[9]) //2
129: display.append("2");
130: if(ae.getSource() == button[10]) //3
131: display.append("3");
132: if(ae.getSource() == button[11]) //Multiplicação
133: {
134: temporary[0] = Double.parseDouble(display.getText());
135: for(int i = 0; i < 4; i++)
136: function[i] = false;
137: function[2] = true;
138: decimal = false;
139: display.setText("");
140: }
141: if(ae.getSource() == button[12]) //Decimal
142: {
143: if(!decimal)
144: {
145: decimal = true;
146: display.append(".");
147: }
148: }
149: if(ae.getSource() == button[13]) //Divisão
150: {
151: temporary[0] = Double.parseDouble(display.getText());
152: for(int i = 0; i < 4; i++)
153: function[i] = false;
154: function[3] = true;
155: decimal = false;
156: display.setText("");
157: }
158: if(ae.getSource() == button[14]) //C
159: clear();
160: if(ae.getSource() == button[15]) //Sqrt
161: getSqrt();
162: if(ae.getSource() == button[16]) //+/-
163: getPosNeg();
164: if(ae.getSource() == button[17]) //=
165: getResult();
166: if(ae.getSource() == button[18]) //0
167: display.append("0");
168: }
169: //Agora, para implementar o funcionamento dos botões, vou criar diversos métodos
170: //Para limpar a tela e resetar a calculadora
171: public void clear() {
172: try
173: {
174: display.setText(""); // Apaga o visor
175: for(int i = 0; i < 4; i++)
176: function[i] = false; // Reseta o estado de todas as funções
177: for(int i = 0; i < 2; i++)
178: temporary[i] = 0; // Apaga as variáveis auxiliares
179: decimal = false;
180: } catch(NullPointerException e) {
181: }
182: }
183: //Para calcular a raiz quadrada
184: public void getSqrt() {
185: try {
186: double value = Math.sqrt(Double.parseDouble(display.getText())); //Cria uma variável (double) e calcula a raiz do display usando a biblioteca math
187: display.setText(Double.toString(value)); //Modifica o valor do display
188: } catch(NumberFormatException e) {
189: }
190: }
191: //Para o botão +/-
192: public void getPosNeg() {
193: try {
194: double value = Double.parseDouble(display.getText()); //Cria a variável (por simplicidade)
195: value = value * (-1);//Não é necessário se preocupar com o zero por (-1)*0 = 0
196: display.setText(Double.toString(value));//Escreve o resultado
197: } catch(NumberFormatException e) {
198: }
199: }
200: public void getResult() {
201: double result = 0;
202: temporary[1] = Double.parseDouble(display.getText());
203: String temp0 = Double.toString(temporary[0]); //Duas variáveis necessárias para a conversão string -> double dos dois números
204: String temp1 = Double.toString(temporary[1]);
205: try {
206: if(temp0.contains("-")) { //Se o número é negativo
207: String[] temp00 = temp0.split("-", 2); //Divide a string em dois
208: temporary[0] = (Double.parseDouble(temp00[1]) * -1); //Transforma em double como negativo
209: }
210: if(temp1.contains("-")) { //Analogamente
211: String[] temp11 = temp1.split("-", 2);
212: temporary[1] = (Double.parseDouble(temp11[1]) * -1);
213: }
214: } catch(ArrayIndexOutOfBoundsException e) {
215: }
216: try {
217: if(function[2]) //Multiplicação
218: result = temporary[0] * temporary[1];
219: else if(function[3]) //Divisão
220: result = temporary[0] / temporary[1];
221: else if(function[0]) //Soma
222: result = temporary[0] + temporary[1];
223: else if(function[1]) //Subtração
224: result = temporary[0] - temporary[1];
225: if(result>=0) //Imprime resultado
226: display.setText(Double.toString(result));
227: else //evita um bug com o sinal negativo aparecendo depois do número
228: {
229: display.setText(Double.toString((-1)*result));
230: display.append("-");
231: }
232: for(int i = 0; i < 4; i++)
233: function[i] = false; //Reseta variáveis de função
234: decimal = false;
235: } catch(NumberFormatException e) {
236: }
237: }
238: }
Cuidado apenas na hora de copiar e colar o código em um IDE, pois a formatação pode ter sido modificada pelo código html do blog. Vou incluir uma animação da calculadora funcionando para os menos interessados em programação.
Obrigado, até o próximo projeto!
A apresentação do blog está ok. Poderia ser mais didático na apresentação do código. Exibir todo o código é dificil de ser entendido. Apresente as partes que mostrem informações interessantes e um esquema geral do programa. O código pode residir em um site externo.
ReplyDelete