Calculadora con GUI y sin GUI

Ruso

Newbie Lvl 1
Hola a todos, como no quería oxidarme con el tema de java aunque mis conocimientos son basicos, me puse a programar un poco y cree dos clases. Una ejecuta una calculadora simple sin GUI(osea, sin interfaz de usuario), solo se ejecuta desde la consola de comandos y otra calculadora con una GUI.
Osea quiero que me corrigan algunos errores logicos, si se puede optimizar codigo, etc.
Aclaro que es una calculadora basica, lo hice para compararlo con los conocimientos de gente mas avanzada en java.

Calculadora sin GUI:
Java:
package Clases;

import java.util.Scanner;

public class CalculadoraSinGUI {

    private static CalculadoraSinGUI c = new CalculadoraSinGUI();
    private Scanner entrada = new Scanner(System.in);

    private static final char SUMA = '+';
    private static final char RESTA = '-';
    private static final char DIVISION = '/';
    private static final char PRODUCTO = '*';

    private double n1 = 0;
    private double n2 = 0;
    private double tot = 0;

    public static void main(String[] args) {
        // primero se ingresan los valores
        c.ingresarValores();
        // despues se calcula el total
        c.calcularTotal();
    }

    private void ingresarValores() {
        System.out.print("Ingrese el primer numero: ");
        n1 = entrada.nextInt();
        System.out.print("Ingrese el segundo numero: ");
        n2 = entrada.nextInt();
    }

    private void calcularTotal() {
        char signo;
        do {
            System.out.print("\nSuma + | Resta - | Division / | Producto * | Salir 0\nIngrese un signo: ");
            signo = entrada.next().charAt(0);
            switch (signo) {
                case SUMA:
                    tot = n1 + n2;
                    break;
                case RESTA:
                    tot = n1 - n2;
                    break;
                case DIVISION:
                    tot = n1 / n2;
                    break;
                case PRODUCTO:
                    tot = n1 * n2;
                    break;
                default:
                    if (signo == '0') {
                        System.out.println("Salio.");
                    } else
                        System.out.println("Signo incorrecto.");

            }
        } while ((signo != SUMA && signo != RESTA && signo != DIVISION && signo != PRODUCTO && signo != '0'));

        System.out.println("Total: " + tot);
    }

}

Mis dudas son:
1. Nose que diferencia hay entre static y final, osea a las constantes siempre las tengo que definir como "private static final", "private final" o "private static"?, osea nose que diferencia hay.
2. A la variables de clase siempre las declaro como private ?, en este caso no se protegen de nada ya que solo tengo un paquete y una clase.
3. Es necesario crear un objeto de la clase CalculadoraSinGUI como static?


Calculadora con GUI:
Java:
package Clases;

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.JPanel;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;

public class CalculadoraConGUI extends JFrame {
    private static final long serialVersionUID = 1L;
    // tomo el aspecto visual(Look and Feel) del OS en el que se esta ejecutando la aplicacion
    private static String LAF = UIManager.getSystemLookAndFeelClassName(); // si declaro el LAF despues de crear un objeto de esta clase me da error, no se por que

    private static CalculadoraConGUI c = new CalculadoraConGUI();

    // ancho(width) y alto(high)
    private static final int WIDTH = 167;
    private static final int HIGH = 183;

    DecimalFormat decimales = new DecimalFormat("0.00");

    private JPanel panel;
    private JLabel lblN1;
    private JLabel lblN2;
    private JTextField txtN1;
    private JTextField txtN2;
    private JButton btnSuma;
    private JButton btnResta;
    private JButton btnDivision;
    private JButton btnProducto;
    private JLabel lblTot;

    public CalculadoraConGUI() {
        try {
            UIManager.setLookAndFeel(LAF);
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
        setSize(new Dimension(WIDTH, HIGH));
        setDefaultCloseOperation(3);
        setResizable(false);
        getContentPane().setLayout(null);
        initialize();
        setLocationRelativeTo(null);
    }

    private void initialize() {
        panel = new JPanel();
        panel.setBackground(Color.WHITE);
        panel.setBounds(0, 0, 161, 154);
        panel.setLayout(null);
        getContentPane().add(panel);

        lblN1 = new JLabel("N1:");
        lblN1.setBounds(10, 11, 17, 14);
        panel.add(lblN1);
        txtN1 = new JTextField();
        txtN1.setBounds(33, 8, 44, 20);
        panel.add(txtN1);

        lblN2 = new JLabel("N2:");
        lblN2.setBounds(87, 11, 17, 14);
        panel.add(lblN2);
        txtN2 = new JTextField();
        txtN2.setBounds(111, 8, 44, 20);
        panel.add(txtN2);

        btnSuma = new JButton("+");
        btnSuma.setBounds(10, 36, 67, 23);
        btnSuma.setFocusable(false);
        btnSuma.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent evt) {
                // compruebo si hay datos de entrada
                if (checkInput()) {
                    /* Le paso el total al label, donde primero se calcula la suma de los dos numero,
                     * luego el resultado de la suma se convierte al formato declarado,
                     * despues el valor numerico se pasa a String con el metodo valueOf y
                     * por ultimo se setea la cadena al label. */
                    lblTot.setText(String.valueOf(decimales.format(getN1() + getN2())));
                    // limpio los dos txt y hago focus en el txtN1
                    clean();
                } else { // si no hay datos de entrada entonces muestro un mensaje de error
                    JOptionPane.showMessageDialog(null, "Faltan datos.", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        panel.add(btnSuma);

        btnResta = new JButton("-");
        btnResta.setBounds(88, 36, 67, 23);
        btnResta.setFocusable(false);
        btnResta.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent evt) {
                if (checkInput()) {
                    lblTot.setText(String.valueOf(decimales.format(getN1() - getN2())));
                    clean();
                } else {
                    JOptionPane.showMessageDialog(null, "Faltan datos.", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        panel.add(btnResta);

        btnDivision = new JButton("/");
        btnDivision.setBounds(10, 70, 67, 23);
        btnDivision.setFocusable(false);
        btnDivision.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (checkInput()) {
                    lblTot.setText(String.valueOf(decimales.format(getN1() / getN2())));
                    clean();
                } else {
                    JOptionPane.showMessageDialog(null, "Faltan datos.", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        panel.add(btnDivision);

        btnProducto = new JButton("*");
        btnProducto.setBounds(88, 70, 67, 23);
        btnProducto.setFocusable(false);
        btnProducto.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (checkInput()) {
                    lblTot.setText(String.valueOf(decimales.format(getN1() * getN2())));
                    clean();
                } else {
                    JOptionPane.showMessageDialog(null, "Faltan datos.", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        });
        panel.add(btnProducto);

        lblTot = new JLabel("");
        lblTot.setFont(new Font("Tahoma", Font.BOLD, 14));
        lblTot.setBounds(10, 114, 145, 14);
        panel.add(lblTot);

    }

    private double getN1() {
        return Double.parseDouble(this.txtN1.getText());
    }

    private double getN2() {
        return Double.parseDouble(this.txtN2.getText());
    }

    private void clean() {
        this.txtN1.setText("");
        this.txtN2.setText("");
        this.txtN1.requestFocus();
    }

    private boolean checkInput() {
        return !this.txtN1.getText().isEmpty() && !this.txtN2.getText().isEmpty();
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    c.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Mis dudas son:
1. Que diferencia hay entre el metodo mouseClicked() y actionPerformed(), ya que lo dos producen un evento cuando toco un JButton, cual es mejor?
2. A los metodos los declaro como private o public?
 

Benadiz

[ I ♥ DubStep ]
Holaa!

1.1 Con static se refiere a que la variable que estas declarando siempre va a ocupar la misma cantidad de memoria en la maquina virtual en este caso. Y con final estas diciendo que la variable no va a cambiar una ves ya fue declarada. Como es en el caso de las constantes.

1.2 Las variables siempre todas tienen que ser privadas.

1.3 No se a que te referis con crear un objeto, ya que en la clase estas ejecutando un main. En esa clase estas manejando objetos



2.1 La diferencia que tienen es que mouseClicked() siempre va a ejecutar cuando hagas click en cualquier cosa, el actionPerformed() depende de a que objeto estes haciendo click. Por ejemplo en este caso el JButton es compatible

2.2 Los metodos los declaras como privados cuando son de uso interno de la clase, y los declaras como publicos cuando son de uso externo a la clase únicamente.

Saludos, y espero haberte ayudado!
 

Dr. Lord Fers

Legendario Inmortal Lvl 5
Miembro del equipo
Moderador
Moderador de Tecnología
¿No es eso? ¿Qué es entonces? El primer post es del 26 de octubre, qué picardía no disponer de tus grandes conocimientos para desasnarnos! o tal vez tu ajetreada vida no deja lugar a que pulules por estos lares para desplegar tu luz.
La palabra 'static' significa que el miembro especificado le corresponde a la Clase, y no a una instancia en particular.
Significa que sólo una instancia del miembro 'static' puede existir, y que no se encuentra ligado a una instancia en particular de la Clase.

Algoritmos y Programación I. Pensaba que ustedes cursaban en la UTN, pero se ve que abandonaron.

Saludos.
 

Franeg95

CARP
Ex-Staff
Final y Static los usas para decirle ciertas cosas a la vm sobre el atributo que declaras.

El operador final le indica que luego de la asignación a ese atributo, no se va a cambiar. Por un lado le permite optimizar ciertas operaciones, y por otro lado te seguridad que vas a manejar el mismo objeto todo el tiempo.

El operador static funciona para decirle que el atributo no va a ser del objeto (instancia de una clase) sino de la clase particularmente. El beneficio que logras es que el atributo va a estar creado una sola vez. Esto es ùtil por ejemplo si declaras una constante que no te serviría de nada tenerla creada una vez por cada instancia de la clase, directamente con que exista una sola vez en la clase te sirve.
Este mismo operador te sirve para metodos también en donde vas a poder ejecutar esos metodos sin instanciar la clase, como pasa por ejemplo con muchos metodos de la clase Math. La salvedad acá es que no vas a poder usar atributos de instancia en un metodo static dado que sería imposible de diferenciarlo de las tantas instancias.

En cuanto a GUI ni idea, no trabaje casi nada con swing ni awt como para decirte algo.
 
Arriba