ArrayList из ActionListeners очищается при вызове notifyListeners () - PullRequest
0 голосов
/ 22 сентября 2018


Я пытаюсь написать класс, который одновременно прослушивает действия от кнопок и уведомляет другой класс, когда нажата одна из кнопок.У меня есть ArrayList<ActionListener> и методы addActionListener(ActionListener al), removeActionListener(ActionListener al) и notifyActionListeners(ActionEvent ae).Я печатаю в отдельном окне всякий раз, когда добавляю слушателя, и печатаю также размер actionListeners.Он прекрасно работает и печатает, что у меня есть 1 actionListener, но затем, когда я пытаюсь уведомить слушателей, он говорит, что в actionListeners есть 0 объектов.Я добавил println() в метод removeActionListener(al), чтобы увидеть, вызывается ли он, и никогда не вызывается.Вот класс:

package state;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import driver.GameDriver;
import ui.Button;

public class MainMenu extends Menu {
    private static final long serialVersionUID = -7130241947836998525L;

    private ArrayList<ActionListener> actionListeners;

    private Button play;
    private Button scores;
    private Button settings;
    private Button help;
    private Button exit;

    public MainMenu() {
        super("Main Menu");
        actionListeners = new ArrayList<ActionListener>();

    }

    @Override
    protected void addComponents() {
        //Irrelevant to Stackexchange
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        Object src = arg0.getSource();
        if (src == play) {
        } else if (src == scores) {
        } else if (src == settings) {
        } else if (src == help) {
        } else if (src == exit) {
            ActionEvent ae = new ActionEvent(this, ActionEvent.ACTION_FIRST, "exit");

            notifyActionListeners(ae);
        }

    }
    public void addActionListener(ActionListener al) {
        GameDriver.println("Added Listener:");
        actionListeners.add(al);
        GameDriver.println(actionListeners.size());
    }

    public void removeActionListener(ActionListener al) {
        GameDriver.println("Removed al for some reason");
        actionListeners.remove(al);
    }

    private void notifyActionListeners(ActionEvent ae) {
        GameDriver.println("Sending exit to " + actionListeners.size() + " listeners.");

        for(int i = 0; i < actionListeners.size(); i++) {
            GameDriver.println("Exit sent");
            actionListeners.get(i).actionPerformed(ae);

        }
    }
}

Вот методы, которые на самом деле ссылаются на экземпляр MainMenu: 1. Инициализация

protected GameDriver() {
        mainMenu = new MainMenu();
        mainMenu.addActionListener(this);
        debugger = new Debugger();
        println("Size Loader Test...");
        SizeLoader.loadSizes();
        println(SizeLoader.getCurrentSize());
        println("Complete.");
        println("Window Test...");
        window = new Window("Asteroids");
        windowManager = new WindowManager();
//      window.addWindowFocusListener(windowManager);
//      window.addWindowListener(windowManager);
//      window.addWindowStateListener(windowManager);
        window.buildWindow(SizeLoader.getCurrentWidth(), SizeLoader.getCurrentHeight());
        window.add(new MainMenu());
        println("Complete");
        println("Menu Test...");

}

А вот actionPerformed(ae):

@Override
    public void actionPerformed(ActionEvent e) {
        println("Event happened");
        if (e.getSource() == mainMenu) {
            if (e.getActionCommand() == "exit") {
                println("Exiting FR this time...");
            }
        }
}

1 Ответ

0 голосов
/ 22 сентября 2018

Согласно моему комментарию: 3) Вы создаете более одного объекта MainMenu , один из которых вы добавляете слушателя, а другой - в окно.Это выглядит как серьезная ошибка.

Вместо этого создайте только один экземпляр, установите его состояние по мере необходимости (добавьте слушателей) и добавьте его в графический интерфейс.

Поэтому измените

window.add(new MainMenu());

на

window.add(mainMenu);

И снова, согласно моему предыдущему комментарию, не используйте == для проверки равенства строк, а скорее .equalsметод.

...