Java - Ayuda con alcance de variables, Aprendiendo Java.

   
Vista:

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por Dave (3 intervenciones) el 24/06/2014 18:00:02
Hola, muy buenas, estoy aprendiendo Java, y me surge un problema. Cuando dentro de una clase declaro unos atributos (variables) y declaro sus métodos, es fácil acceder a cada uno de esos atributos simplemente con llamarlos:

1
2
3
4
5
6
7
8
class myclase(){
 
   int atributo1;
 
   public void setAtributo(int val){
      this.atributo1=val;  [COLOR="YellowGreen"]//Accedo directamente al atributo1[/COLOR]
   }
}

Bien. Mi duda surge cuando declaro eventos (u otras funciones) dentro de un método. Por ejemplo, si dentro del método setAtributo declaro lo siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public void setAtributo(int val){
   this.atributo1=val;
 
   public void setAtributo(int val){
      textFielDeclarado.addFocusListener(   [COLOR="YellowGreen"]//imaginamos que textFielDeclarado esta correctamente declaro y funcionaltamente declaro y funcional[/COLOR]
         new FocusListener() {
             //@Override
            public void focusGained(FocusEvent arg0) {
               System.out.println( (atributo1); [COLOR="YellowGreen"]//ERROR: Aqui no me da acceso al atributo[/COLOR]
            }
         }
      );
   }
 
}


Se que al ejemplo se le pueden sacar mucho errores, no era mi intención poner algo real. Sólo comprender como debo acceder a esos atributos/variables.


Dentro del evento "public void focusGained(FocusEvent arg0)" en concreto (o de cualquier otra función dentro del método) no tengo acceso a atributo1.

Gracias
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
1
Responder

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por Arturo (13 intervenciones) el 24/06/2014 20:06:07
Lo mejor es invocar un método de la clase que sea publico y mandas el evento.


//@Override
public void focusGained(FocusEvent arg0) {
hacerAlgo(arg0);
}

.......


public void hacerAlgo(FocusEvent arg0)
{
System.out.println( (atributo1);
}
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

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por Dave (3 intervenciones) el 25/06/2014 15:07:37
Bueno, gracias por responder, eso es lo que hago para acceder a los atributos de la clase, pero con objetos no me funciona. Bueno para explicarme mejor, pongo a continuacion el codigo real, no lo queria poner por su extension, voy a resumirlo un poco y lo pongo tal como es en realidad (la parte que nos interesa):


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
class Main {
 
	private JFormattedTextField[][] textFieldCasilla;
 
	//Vars
	private int casX, casY;
 
 
	private void makeTextfields(){
		// CAJAS DE TEXTO
		this.textFieldCasilla = new JFormattedTextField[9][9];
 
		for (int n=0; n<9; n++) {
			for (int m=0; m<9; m++){
				this.textFieldCasilla[n][m] = new JFormattedTextField();
 
				this.textFieldCasilla[n][m].setHorizontalAlignment(SwingConstants.CENTER);
				this.textFieldCasilla[n][m].setBackground(Color.WHITE);
				this.textFieldCasilla[n][m].setBorder(null);
				this.textFieldCasilla[n][m].setEditable(false);
				this.textFieldCasilla[n][m].setFocusable(true);
				this.textFieldCasilla[n][m].setFont(new java.awt.Font("Arial", java.awt.Font.PLAIN, 35));
				this.textFieldCasilla[n][m].setText(Integer.toString(m+1));
				this.textFieldCasilla[n][m].setBounds((m*40)+3, (n*40)+3, 35, 35);
 
				this.textFieldCasilla[n][m].addFocusListener(
					new FocusListener() {
 
						@Override
						public void focusGained(FocusEvent arg0) {
							setPosCasilla(n, m);                                  //<----ERROR 1:  Variables n y m no declaradas, no me deja acceder a los indices de los bucles for.
							textFieldCasilla[0][0].setBackground(Color.GREEN);    //<----ERROR 2: no me deja acceder a textFieldCasilla[1][3] o cualquier otro objeto (botón, textos) de la clase, no existen dentro de este evento. Se que puedo acceder al textFieldCasilla que genera el evento con arg0.getComponent(), pero yo quiero acceder a otros objetos de la clase.
							casX=2;                                               //<----ERROR 3: Tampoco a los atributos propios de la clase. Se "soluciona" con Main.this.casX=2; pero parece una solución cuestionable. Tampoco me interesa modificar su accesibilidad con "public".
							casY=2;                                               //<----ERROR 4: Tampoco a los atributos propios de la clase. Se "soluciona" con Main.this.casY=2; pero parece una solución cuestionable. Tampoco me interesa modificar su accesibilidad con "public".
							System.out.println( getPosCasillaX() + "," + getPosCasillaY() );
							arg0.getComponent().setBackground(new Color(215, 250, 205));
						}
 
						@Override
						public void focusLost(FocusEvent arg0) {
							arg0.getComponent().setBackground(Color.WHITE);
						}
					}
				);
 
			}
		}
 
	}
 
	public int getPosCasillaX(){
		return (this.casX);
	}
 
	public int getPosCasillaY(){
		return (this.casY);
	}
 
	public void setPosCasilla(final int x, final int y){
		this.casX = x;
		this.casY = y;
	}
 
	public static void main(String[] args) {
 
	}
 
}


Este es el codigo, es funcional, lo podeis probar (aunque no vereis nada, ya que no muestra nada). Podreis modificarlo para ver los errores que  mi me da. Lo he podificado incluyendo esas lineas de error solo para que veais que es lo que quiero aprender. Se que las lineas hacen cosas que no tienen sentido en el programa. Solo es para solucionar el problema.

El ejercicio trata en general de hacer un sudoku, al menos funcional. Bueno, a parte de esto. Si mirais el code, veis que es solo la especificacion de una matriz de JFormatedTextFields llamados textFieldCasilla[][]. Utilizo un doble for para colocar indices y posiciones y otros atributos al textFieldCasilla[][].

Mi duda es cómo realizar esas operaciones de las lineas ERROR sobre eso atributos y objetos. Como veis tengo creados un par (getPosCasillaX/Y() setPosCasilla(int int)) de metodos "puente" para acceder y establecer a casX y casY. Pero la idea es saber si hay forma "directa" de hacerlo. casX y casY son varibles en el tiempo de ejcucion, es decir no pueden ser static/final.

Gracias
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

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por UnoPorAhi (128 intervenciones) el 26/06/2014 20:20:49
Buenas,

Esas limitaciones que comentas se deben a la forma en que trata java las closures a nivel de compilación. Son reglas que tienes que respetar.
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

Como sabes, con Java 8 hay una nueva implementación de closures. De hecho, compilando en java 8 el ERROR 2, ERROR 3 y ERROR 4 no se producen, funciona perfectamente.

En cuanto a las variables locales al método que contiene la innerclass... no hay alternativa, tienen que ser finales SI o SI.
Una forma rápida de solucionarlo es que las envuelvas en una variable final cada vez:

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
for (int n=0; n<9; n++) {
			for (int m=0; m<9; m++){
				this.textFieldCasilla[n][m] = new JFormattedTextField();
 
				this.textFieldCasilla[n][m].setHorizontalAlignment(SwingConstants.CENTER);
				this.textFieldCasilla[n][m].setBackground(Color.WHITE);
				this.textFieldCasilla[n][m].setBorder(null);
				this.textFieldCasilla[n][m].setEditable(false);
				this.textFieldCasilla[n][m].setFocusable(true);
				this.textFieldCasilla[n][m].setFont(new java.awt.Font("Arial", java.awt.Font.PLAIN, 35));
				this.textFieldCasilla[n][m].setText(Integer.toString(m+1));
				this.textFieldCasilla[n][m].setBounds((m*40)+3, (n*40)+3, 35, 35);
 
                                final int finaln = n;
                                final int finalm = m;
				this.textFieldCasilla[n][m].addFocusListener(
					new FocusListener() {
 
						@Override
						public void focusGained(FocusEvent arg0) {
							setPosCasilla(finaln, finalm);                                  //<----ERROR 1:  Variables n y m no declaradas, no me deja acceder a los indices de los bucles for.
							textFieldCasilla[0][0].setBackground(Color.GREEN);    //<----ERROR 2: no me deja acceder a textFieldCasilla[1][3] o cualquier otro objeto (botón, textos) de la clase, no existen dentro de este evento. Se que puedo acceder al textFieldCasilla que genera el evento con arg0.getComponent(), pero yo quiero acceder a otros objetos de la clase.
							casX=2;                                               //<----ERROR 3: Tampoco a los atributos propios de la clase. Se "soluciona" con Main.this.casX=2; pero parece una solución cuestionable. Tampoco me interesa modificar su accesibilidad con "public".
							casY=2;                                               //<----ERROR 4: Tampoco a los atributos propios de la clase. Se "soluciona" con Main.this.casY=2; pero parece una solución cuestionable. Tampoco me interesa modificar su accesibilidad con "public".
							System.out.println( getPosCasillaX() + "," + getPosCasillaY() );
							arg0.getComponent().setBackground(new Color(215, 250, 205));
						}
 
						@Override
						public void focusLost(FocusEvent arg0) {
							arg0.getComponent().setBackground(Color.WHITE);
						}
					}
				);
 
			}
		}


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
0
Comentar

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por Tom (908 intervenciones) el 25/06/2014 11:01:07
En tu ejemplo, atributo1 ha de ser o static o final.
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

Ayuda con alcance de variables, Aprendiendo Java.

Publicado por Dave (3 intervenciones) el 25/06/2014 15:09:27
no me interesa que sea ni final ni static... ya que se modifican en tiempo de ejecucion. Las utilizo a modo de flags de posicion.
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