2010-10-28 6 views
11

I stworzył tablicę JButtons z anonimowego ActionListeners i pod pewnymi warunkami Chcę usunąć wszystkie ActionListeners, ale metoda .removeActionListeners wymaga ActionListener jako argument. W jaki sposób chciałbym usunąć odsłuchy akcji?Java Swing: Jak usunąć anonimowego ActionListener ze składnika

for (int i=0; i < button.length; i++){ 
    button[i] = new JButton(); 
    button[i].addActionListener(listener.new ButtonListener()); 
} 
+0

(Tylko uwaga, że ​​to prawdopodobnie nie jest skuteczny sposób zaprojektowania tego, co próbujesz zrobić.) Lepiej zostawić słuchaczy tam strzelających, a następnie sprawdź/polimorfizm po tym, aby wyłączyć akcję (prawdopodobnie zmienić stan zamiast disable).) –

Odpowiedz

2

Nie możesz. Nikt nie ma odniesienia do tych obiektów. Aby móc je usunąć, musisz zapisać go jako element/zmienną danych w kodzie, a następnie przekazać tę zmienną do metody removeActionListener(). Jednak można użyć metody getActionListeners(), aby uzyskać tablicę wszystkich obiektów ActionListener związanych z Button. Następnie należy dowiedzieć się, który z nich usunąć, ale jeśli jest tylko jedna, to powinno być łatwe ;-)

17

Można je dostać z: getActionListeners metody:

for(JButton currentButton: button) { 
    for(ActionListener al : currentButton.getActionListeners()) { 
     currentButton.removeActionListener(al); 
    } 
} 

nie jestem pewnie, czy wyrzuci to jednak ConcurrentModificationException.

+0

Prawdopodobnie nie ... Mogę się założyć, że przechowuje on słuchaczy wewnętrznie jako ArrayList, a następnie kopiuje je do tablicy ActionListeners, aby je zwrócić. Ciekawe, czy by tak było ... –

+0

Nikt nie zwróciłby wewnętrznej tablicy, prawda? (Które i tak nie zmienia rozmiaru.) –

+0

dla (ActionListener al: button.getActionListeners()) To się nie skompiluje, ale był to niezły pomysł –

3

Rozumiem twoje pytanie, a jak sugerowali inni, powtarzanie przez wszystkie działania słuchaczy z klasy klienta może rozwiązać twój natychmiastowy problem.

  1. H/W w tym przypadku, co się naprawdę staramy się robić to rozszerzyć funkcjonalność JButton, a to jest jeden sposób, aby rozwiązać ten problem - rozszerzenie JButton i dodać metodę zwaną removeAllActionListeners() (co robi nie przyjmować żadnych parametrów).

    • Wewnątrz tej metodzie można iteracyjne przez wszystkich słuchaczy działania i je usunąć. Myślę, że jest lepiej projektowania, jeśli robisz to tutaj niż w klasy klienta.
  2. Jeśli nie chcesz tego robić, to myślę, że sugestia Toma Hawtina, aby użyć stanu w swoim ButtonListener jest dobrym pomysłem.

  3. W przypadku braku opcji zawsze można powrócić na bardzo "hacky", czyli przechowywać kolekcję detektorów działań w klasie klienta.

    • Map<JButton, ButtonListener> (jeśli istnieje zawsze tylko będzie jeden słuchacz na przycisku), lub
    • Map<JButton, List<ButtonListener>> (jeśli nie może być wielu słuchaczy na przycisku) jest to, co mógłbym użyć.

myślę metody i są korzystne i sposób oznacza niską konstrukcję (ale jest o wiele łatwiejsze do włamania razem).

zauważyć, że jeśli rzeczywiście używać metoda , lub coś podobnego, sprawdź, że metody i atrybuty uzyskiwania dostępu są bezpieczne (jak wspomniano przez OscarRyz) nici, a jeśli nie, użyj synchronized celu zapewnienia bezpieczeństwa wątku .