2009-08-28 89 views
5

Básicamente lo que quiero hacer es obtener un botón de inicio para iniciar un método ejecutándose en otra clase y actuando sobre otro objeto.Java: Usar un actionlistener para llamar a una función en otra clase en un objeto de esa clase

Mi código para el oyente:

button1a.addActionListener(new ActionListener() { 
    public void actionPerformed (ActionEvent event) { 
     // Figure out how to make this work 
     //sim.runCastleCrash(); 
    } 
}); 

Mi código para la otra clase:

public static void main(String[] args) { 
    CastleCrash sim; 
    sim = new CastleCrash(); 
} 

y

public void runCastleCrash() { 
    System.out.println("Castle Crash is beginning..."); 
    //Other method parts here to be added 
} 

tengo la sensación de que esto no puede ser demasiado duro , pero me falta una pieza.

+0

¿Qué errores está obteniendo? ¿Está la variable 'sim' incluso en el alcance cuando intenta agregar actionListener al botón? Un error típico es que las variables deben ser definitivas para poder acceder a ellas desde una clase interna anónima, como su ActionListener. –

+0

me sale el error: Excepción en el hilo "principal" java.lang.Error: no resuelto problema de compilación: \t SIM no se puede resolver Creo que tienes razón en que es un problema sim no estar en el ámbito de aplicación, pero no puedo entender cómo hacerlo definitivo ... – Myles

+0

Ver la respuesta de McDowell, eso es lo que respondería. –

Respuesta

3

Una forma de hacer referencia a las cosas de una clase anónima está utilizando el final palabra clave:

public static void main(String[] args) { 
    final Object thingIWantToUse = "Hello"; 

    JButton button = new JButton("Click"); 
    button.addActionListener(new ActionListener() { 
     @Override public void actionPerformed(ActionEvent e) { 
     System.out.println(thingIWantToUse); 
     } 
    }); 

    JFrame frame = new JFrame(); 
    frame.setLayout(new FlowLayout()); 
    frame.add(button); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setVisible(true); 
    } 

Alternativamente, puede acceder a los miembros (variables o métodos) de un tipo envolvente:

public class ActionListenerDemo2 { 
    private final JFrame frame = new JFrame(); 
    private Object thingIWantToUse = "Hello"; 

    public ActionListenerDemo2() { 
    JButton button = new JButton("Click"); 
    button.addActionListener(new ActionListener() { 
     @Override public void actionPerformed(ActionEvent e) { 
     thingIWantToUse = "Goodbye"; 
     System.out.println(thingIWantToUse); 
     } 
    }); 
    frame.setLayout(new FlowLayout()); 
    frame.add(button); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
    new ActionListenerDemo2().frame.setVisible(true); 
    } 
} 
+0

No entiendo muy bien la segunda opción que describes. ¿Cómo es posible acceder a los métodos de un tipo adjunto? – Myles

+0

Si agregó un método 'doFoo()' a 'AnctionListenerDemo2', entonces podría llamarlo desde adentro' actionPerformed'. 'actionPerformed' pertenece a la implementación de la clase interna anónima de la interfaz' ActionListener'. Introducción a las clases anidadas aquí: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html – McDowell

0

De alguna manera necesita una referencia a su objeto CastleCrash disponible para llamar desde su actionListener.

Probablemente quiera subclasificar JFrame, o lo que sea que contenga su JButton de manera que tenga tanto su método principal como una propiedad CastleCrash que luego pueda ser referenciada desde su clase interna anónima Actionlistener.

PERO - tenga cuidado, parece que está llamando a lo que será un método de larga ejecución desde el hilo del evento GUI (donde se llamará al oyente de acción). En general, esta es una mala idea, usted hará caso de su GUI para dejar de responder.

Consulte http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html especialmente el bit en la clase SwingWorker para obtener ideas sobre cómo evitar ese problema.

1

McDowell ya responde prácticamente con buenos ejemplos sobre cómo acceder a las variables de los oyentes de eventos (o clases internas anónimas en general). Sin embargo, hay a more general Sun resource on Event Listeners in Swing que es canónico y una buena visión general de todas las advertencias que deben tenerse en cuenta al escribirlas.

2

He tenido el mismo problema que tú y así es como lo resolví.

Puede hacer su objeto final (CastleCrash final = new CastleCrash();), pero no quería hacer eso, o puede hacer algo como un método setter para ejecutar el método en su otra clase :

Mi código para la clase oyente:

button1a.addActionListener(new ActionListener() 
{ 

    public void actionPerformed (ActionEvent event) 
    { 
    //How to make this work ? 
    //Like this: 
    runCC(); 
    } 
}); 

public void runCC() 
{ 
    CastleCrash sim = new CastleCrash(); 
    sim.runCastleCrash(); 
} 

Mi código para la otra clase:

public void runCastleCrash() 
{ 
    System.out.println("Castle Crash is beginning..."); 
    //Other method parts here to be added 
} 

la esperanza que esto sea útil, buena suerte! :)

Cuestiones relacionadas