2009-08-28 20 views
5

Zasadniczo chcę uzyskać przycisk uruchamiania, aby zainicjować metodę działającą w innej klasie i działającą na innym obiekcie.Java: Używanie actionlistener do wywoływania funkcji w innej klasie na obiekcie z tej klasy

Mój kod dla słuchacza:

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

Mój kod do drugiej klasy:

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

i

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

mam wrażenie, to nie może być zbyt trudne , ale brakuje mi kawałka.

+0

Jakie błędy dostałeś? Czy zmienna 'sim' jest jeszcze w zasięgu podczas próby dodania actionListener do przycisku? Typową pułapką jest to, że zmienne muszą być ostateczne, aby były dostępne z anonimowej klasy wewnętrznej, takiej jak ActionListener. –

+0

pojawia się błąd: Wyjątek w wątku „main” java.lang.Error: nierozwiązanym problemem kompilacja: \t sim nie może być rozwiązany Chyba masz rację, że jej problem z karta SIM nie jest w zakresie, ale nie mogę wymyślić, jak zrobić to końcowym ... – Myles

+0

Zobacz odpowiedź McDowell, to, co bym odpowiedział. –

Odpowiedz

3

Jednym ze sposobów, aby odwoływać rzeczy w anonimowej klasy używa final kluczowe:

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); 
    } 

Alternatywnie, można uzyskać dostęp Członkowie (zmienne lub metod) o typ otaczającej:

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

Nie do końca rozumiem drugą opcję, którą opisujesz. W jaki sposób można uzyskać dostęp do metod typu otaczającego? – Myles

+0

Jeśli dodałeś metodę 'doFoo()' do 'AnctionListenerDemo2', możesz wywołać ją z wnętrza' actionPerformed'. 'actionPerformed' należy do anonimowej klasy wewnętrznej implementacji interfejsu' ActionListener'. Wprowadzenie do klas zagnieżdżonych tutaj: http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html – McDowell

0

W pewien sposób potrzebne jest odwołanie do obiektu CastleCrash, który można wywoływać z poziomu actionListener.

Prawdopodobnie chcesz podklasy JFrame, lub cokolwiek zawiera JButton, tak, że ma ona zarówno swoją główną metodę, jak i właściwość CastleCrash, do której można następnie odwołać się z anonimowej klasy Actionlistener klasy wewnętrznej.

BUT - bądź ostrożny, wyglądasz jak wywołujesz metodę, która będzie długotrwała z poziomu wątku zdarzenia GUI (w którym wywoływany jest detektor działań). Zwykle jest to zły pomysł, sprawisz, że twój GUI przestanie reagować.

Zobacz zwłaszcza ten bit w klasie SwingWorker, aby dowiedzieć się, jak uniknąć tego problemu.

1

McDowell już odpowiada praktycznie na dobrych przykładach, jak uzyskać dostęp do zmiennych od detektorów zdarzeń (lub ogólnie anonimowych klas wewnętrznych). Istnieje jednak a more general Sun resource on Event Listeners in Swing, który jest kanoniczny i dobry przegląd wszystkich zastrzeżeń, które należy wziąć pod uwagę przy ich pisaniu.

2

Miałem ten sam problem jak ty i tak go rozwiązałem.

Możesz albo uczynić swój obiekt ostatecznym (ostatni zamek CastleCrash = nowy CastleCrash();), ale nie chciałem tego zrobić, albo możesz zrobić coś w stylu metody ustawiającej metodę w twojej drugiej klasie :

Mój kod dla klasy słuchacza:

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(); 
} 

Mój kod do drugiej klasy:

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

Nadzieja jest to pomocne, powodzenia! :)

Powiązane problemy