调用notifyListeners()时清除了ActionListeners的ArrayList

时间:2018-09-22 00:45:14

标签: java arraylist actionlistener


我正在尝试编写一个类,该类既侦听按钮的动作,又在按下其中一个按钮时通知另一个类。我有一个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 :(得分:0)

根据我的评论:3)您要创建多个MainMenu对象,一个向其添加侦听器,另一个向窗口添加。这似乎是一个严重的错误。

仅创建一个实例,根据需要设置其状态(添加侦听器)并将其添加到gui。

所以改变

window.add(new MainMenu());

收件人

window.add(mainMenu);

再次根据我之前的评论,不要将==用于字符串相等性检查,而应使用.equals方法。