Java - me sale un error de static context al implementar addActionListener en un boton.

 
Vista:

me sale un error de static context al implementar addActionListener en un boton.

Publicado por pablo medina (2 intervenciones) el 09/11/2018 01:38:08
lo que me sucede es que al ejecutar me sale erros de static context.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
 
public class Calculadora_beta3 {
 
    public static void main(String[] args) {
 
    JFrame frame = new JFrame("CALCULADORA POR TECLADO PABLEINSTEIN");
    frame.setSize(400, 250);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    JPanel panel = new JPanel();
 
    frame.add(panel);
 
    placeComponents(panel);
 
    frame.setVisible(true);
    panel.setLayout(null);
    }
    private static void placeComponents(JPanel panel) {
 
        JLabel Label = new JLabel("primer digito: ");
        Label.setBounds(30,8,80,25);
        panel.add(Label);
 
        JTextField LabelText = new JTextField(20);
        LabelText.setBounds(130,10,165,25);
        panel.add(LabelText);
        LabelText.getText();
 
        JLabel Label2 = new JLabel("segundo digito: ");
        Label2.setBounds(30,32,120,25);
        panel.add(Label2);
 
        JTextField Label2Text = new JTextField(20);
        Label2Text.setBounds(130,35,165,25);
        panel.add(Label2Text);
        Label2Text.getText();
 
        JButton sumaButton = new JButton("SUMA");
        sumaButton.setBounds(30, 65, 140, 25);
        panel.add(sumaButton);
        sumaButton.addActionListener(this);
 
        JButton restaButton = new JButton("RESTA");
        restaButton.setBounds(30, 110, 140, 25);
        panel.add(restaButton);
        restaButton.addActionListener(this);
 
        JButton multiButton = new JButton("MULTIPLICACION");
        multiButton.setBounds(200, 110, 140, 25);
        panel.add(multiButton);
        multiButton.addActionListener(this);
 
        JButton divisionButton = new JButton("DIVISION");
        divisionButton.setBounds(200, 65, 140, 25);
        panel.add(divisionButton);
        divisionButton.addActionListener(this);
 
        JLabel Label3 = new JLabel("resultado: ");
        Label3.setBounds(30,150,80,25);
        panel.add(Label3);
 
 
        JTextField Label3Text = new JTextField(20);
        Label3Text.setBounds(130,148,165,25);
        panel.add(Label3Text);
        Label3Text.getText();
}
}



screen
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

me sale un error de static context al implementar addActionListener en un boton.

Publicado por Kabuto (1378 intervenciones) el 10/11/2018 01:50:16
Hola.
Te explico lo que significa ese error.
Cuando hace esto:
1
estaButton.addActionListener(this);

Le estás diciendo que al boton estaButton, que está definido dentro de un "contexto estatico", ya que está en el método:
1
private static void placeComponents(JPanel panel)

se le ha de asignar como ActionListener a this.
this es en realidad la clase Calculadora_beta3, es decir, tu clase principal, la cuál no es estática:
1
public class Calculadora_beta3

Entonces, no puedes pasarle como valor un clase "no estática" a un método invocado desde un contexto "estático".

De todos modos, este no es el verdadero problema. El verdadero problema es que obviamente tu clase principal no es una clase que pueda servir como ActionListener. Tal vez pudiera si le implementas dicha interfaz (la interfaz ActionListener) pero de todos modos, al no ser estática, nunca te va a servir.

Así que si quieres, de momento, sustituye todos esos this que has puesto como argumento a los ActionListener por el valor null.

Esto te permitirá iniciar el programa y ver en pantalla tu JFrame con sus botones y campos y tal..
Solo que de momento, los botones no van a hacer nada.

Cuando quieras que tus botones hagan "algo", tendrás que crear una nueva clase, estática por supuesto, que implemente la interfaz ActionListener.
En esta clase, obligatoriamente ha de tener el método:
1
public void actionPerformed(ActionEvent arg0)

Dentro de ese método, es donde has de programar qué quieres que ocurra cuando se pulse un determinado botón.

Sin embargo, tal y como está escrito el código, ahora se te van a presentar una serie de problemas.
Por ejemplo, si queremos hacer la sumaporque han apretado el botón SUMA, dentro de ese método tendrías que decirle que coja el texto del campo LabelText y lo convierta un un valor int.
Que haga lo mismo con Label2Text.
Y ahora que tiene dos valores int, que los sume, y pase el resultado al campo Label3Text

El problema, es que estos tres campos de texto: LabelText, Label2Text, Label3Text están declarados dentro del método placeComponents().
Esto significa que solo "existen" dentro de este método, fuera de él, ningún otro método o clase puede acceder a ellos, no pueden verlos.
No se si has visto o te han explicado algo sobre el "alcance" (scope) de variables y objetos.

En fin, que esos JTextField solo existen dentro del método placeComponents().
Cuando le digas a tu clase que implementa el ActionListener que coja el valor de esos JTextField, te va a decir que no tiene ni idea de quien le estás hablando, que el no puede ver a ningún JTextField.

Pero tranquilo, que todo tiene solución en esta vida.
Una solución, es redefinir el código de manera que los objetos más importantes estén declarados como atributos de clase.
Los más importantes son los JTextField, porque el resto de métodos y clases que podamos necesitar, van a querer acceder a ellos para leer y escribir su contenido.

Es decir, declararlos aquí:
1
2
3
4
5
6
7
8
9
10
11
12
public class Calculadora_beta3 {
 
    //Declaramos los campos de texto como atributos de clase, para que tengan el máximo alcance(scope)
	static JTextField LabelText;
	static JTextField Label2Text;
	static JTextField Label3Text;
 
	public static void main(String[] args) {
 
		JFrame frame = new JFrame("CALCULADORA POR TECLADO PABLEINSTEIN");
		frame.setSize(400, 250);
		........

De este modo, tienen alcance total dentro del programa, es decir, cualquier método o clase (estáticos, eso sí) que escribar dentro del programa, va a poder verlos y acceder a ellos.

Esta es la opción ideal, sobre todo si se tratase de un programa más complicado y de mayor envergadura.

Como en este caso, es una programa sencillo, hay una segunda opción para no tener que cambiar la declaración de estos campos.

Basta con añadir un poquito más de código a la clase que va a implementar el ActionListener.
Normalmente esta clase, es suficiente con escribir su método obligatorio, porque seguramente tendrá acceso a los campos y variables importantes que pueda necesitar.

Como en este caso, no va a tener acceso a los 3 JTextField del programa, lo que podemos hacer es añadirle a esta clase 3 JTextField como atributos y un constructor desde el cuál le pasaremos como referencia los 3 JTextField del programa principal.
De este modo, como sus JTextField internos en realidad están referenciando a los JTextField externos, lo que pase en los internos se reflejará en los externos.
No se si me estoy explicando bien, quizás viendo el código se entiende mejor.

Yo ahora voy a publicarte aquí como podría ser la clase que implemente el ACtionListener para que funcione.
Puede que antes de ver como lo he hecho yo, quieras intentar hacerlo tú. Quizás sea lo ideal, pues al tener que pelearte con los problemas que te he comentado, lo entenderás mejor que si yo te lo explico.

En cualquier caso, aquí te dejo la clase que yo he escrito. No está completa, solo he puesto el código para SUMAR y RESTAR. Falta el resto de operaciones que puedes hacerlo tú siguiendo el ejemplo de como lo he hecho yo.

Esta sería la clase, la he llamado AccionCalcular. Puedes declararla justo después del método placeComponents()
Fíjate que es statica, que tiene un constructor y unos atributos. Y que su constructor lo que recibirá son referencias a los JTextField
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
static class AccionCalcular implements ActionListener {
 
    JTextField campo1;
    JTextField campo2;
    JTextField campo3;
 
    public AccionCalcular(JTextField campo1, JTextField campo2, JTextField campo3) {
        this.campo1 = campo1;
        this.campo2 = campo2;
        this.campo3 = campo3;
    }
 
    @Override
    public void actionPerformed(ActionEvent arg0) {
 
        //Recogemos la "fuente", es decir que boton llamó a la accion
        Object fuente = arg0.getSource();
        JButton boton = (JButton)fuente; //De Object, lo "casteamos" a JButton para luego poder acceder a sus propiedades
        //Recogemos los valores de los campos de texto
        int valor1 = Integer.parseInt(campo1.getText());
        int valor2 = Integer.parseInt(campo2.getText());
 
        //Para identificar que boton ha sido, preguntamos por el texto que tiene escrito cada boton
        if (boton.getText().equals("SUMA"))
        {
            int suma = valor1 + valor2;
            campo3.setText(String.valueOf(suma));
        }
        else if (boton.getText().equals("RESTA"))
        {
            int resta = valor1 - valor2;
            campo3.setText(String.valueOf(resta));
        }
    }
 
}

Vale, ya tendríamos la clase definida. Ahora hay que añadirsela a los botones como objetos que realizarán la acción.
Esto lo hacemos dentro del método placeComponents(), ya que aquí si podemos ver los JTextField que tenemos que pasarle a nuestra clase AccionCalcular como argumentos.

Como tenemos que pasarle los tres campos de texto, y para ello los tres campos de texto han de estar ya declarados, a los botones les añadimos la accion al final del método, después de que Label3Text ya haya sido declarado.

1
2
3
4
5
6
7
8
9
...................
    JTextField Label3Text = new JTextField(20);
    Label3Text.setBounds(130,148,165,25);
    panel.add(Label3Text);
    Label3Text.getText();
 
    sumaButton.addActionListener(new AccionCalcular(LabelText, Label2Text, Label3Text));
    restaButton.addActionListener(new AccionCalcular(LabelText, Label2Text, Label3Text));
}

Aquí solo se lo he pasado a los botones sumar y restar, porque mi código solo suma y resta.
Cuando añadas el código para que también multiplique y divida, tendrás que añadirselo tambien a los botones correspondientes.
Fíjate como al instancia la clase AccionCalcular() le pasamos entre paréntesis los tres campos de texto a los que queremos que tenga acceso.


Cualquier duda, pregúntala por aquí.
Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

me sale un error de static context al implementar addActionListener en un boton.

Publicado por pablo medina (2 intervenciones) el 12/11/2018 19:11:56
Muchas gracias, me fue muy util y prendí.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar