creación dinámica de botones

angel_itwt
22 de Noviembre del 2005
Hola a todos, tengo un problemilla a la hora de crear dinámicamente botones con Java: tengo que crear una aplicación de interfaz gráfica que contenga un botón (Jbutton normal y corriente) de manera que, cuando el usuario pulse en ese botón, se añadirá un nuevo botón a la ventana. Este nuevo botón contendrá tendrá un icono y su nombre será el color del icono que contiene. Los colores los decide la aplicación de manera aleatoria, es decir que si pulsamos 7 veces tendremos algo parecido a:

[crea un botón][amarillo][verde][naranja][azul][verde][verde]

Cualquiera de los botones generados debe ser capaz a su vez de generar un nuevo botón, con su mismo color.


Es algo bastante sencillo pero es que al compilar me sale un error que no entiendo y soy incapaz de solucionar por muchas vueltas que le dé. Os voy a dejar el fragmento de código para ver si alguno podeis ayudarme.


//método del botón inicial, creado en el initComponents()
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
javax.swing.JButton jButtonAux;
numero_aleatorio = Math.random();
if (numero_aleatorio < 0.25){
jButtonAux = new javax.swing.JButton(\"amarillo\",amarillo);
}
else if(numero_aleatorio < 0.5){
jButtonAux = new javax.swing.JButton(\"verde\",verde);
}
else if(numero_aleatorio < 0.75){
jButtonAux = new javax.swing.JButton(\"naranja\",naranja);
}
else{
jButtonAux = new javax.swing.JButton(\"azul\",azul);
}

jButtonAux.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButtonAuxActionPerformed(evt, numero_aleatorio);
}
});

getContentPane().add(jButtonAux);
pack();
}

//ESTE ES EL MÉTODO QUE ME FALLA
private void jButtonAuxActionPerformed(java.awt.event.ActionEve nt evt, double numero_aleatorio_otro) {
javax.swing.JButton jButtonOtro = new javax.swing.JButton();
if (numero_aleatorio_otro < 0.25){
jButtonOtro = new javax.swing.JButton(\"amarillo\",amarillo);
}
else if(numero_aleatorio_otro < 0.5){
jButtonOtro = new javax.swing.JButton(\"verde\",verde);
}
else if(numero_aleatorio_otro < 0.75){
jButtonOtro = new javax.swing.JButton(\"naranja\",naranja);
}
else{
jButtonOtro = new javax.swing.JButton(\"azul\",azul);
}

jButtonOtro.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
JButtonAuxActionPerformed(evt, numero_aleatorio_otro)
//AQUÍ ES DONDE ME FALLA, EXACTAMENTE ME DICE:
//local variable numero_aleatorio_otro is accessed from within inner class; needs to be declared final

}
});


getContentPane().add(jButtonOtro);
pack();


}

Disculpad las molestias y muchas gracias por vuestra atención.

también indicaros q las variables numero_aleatorio como numero_aleatorio_otro son globales, y que obviamente si las declaro final ya no puedo cambiarlas en tiempo de ejecución que es lo que quiero

si encontrais una solución alternativa a la q yo he planteado también me sirve

muchísimas gracias de nuevo




chuidiang
22 de Noviembre del 2005
Hola:

El problema es el siguiente. La varaible numero_aleatorio_otro es un parámetro del método. Sólo existe mientras estás dentro del método. En el método creas el botón, añades el ActionListener y sales del método, por lo que desaparece la variable.
Si luego pulsas el botón, se ejecutará el ActionListener que hace referencia a una variable numero_aleatorio_otro que ya no existe.
El compilador es listo y te avisa de esta circunstancia. La forma que te aconseja para que esta variable no desapareczca, es declararla final.
Como dentro del método no cambias el valor de ese parámetro, puedes ponerlo final en el método. Otra opción es declarrar una variable auxiliar local que sea final

private void jButtonAuxActionPerformed(java.awt.event.ActionEve nt evt, double numero_aleatorio_otro) {
final double aux = numero_aleatorio_otro;

y usar aux en el ActionListener.

Finalmente, una opción más es hacer una clase que herede de ActionListener, que admita en el constructor el valor de numero_aleatorio_otro y cualquier otra cosa que necesite y que en su actionPerformed haga lo que tenga que hacer.

Se bueno

angel_itwt
22 de Noviembre del 2005
muchas gracias por tu ayuda