Удаление анонимного и лямбда слушателя

Есть меню, в которой при нажатии на кнопку создается/удаляется три слушателя: обычный, анонимный и лямбда. Инициализация их выглядит так:

private ProductStore ps = new ProductStore();
IProductListener pLis = new IProductListener() {
            @Override
            public void onProductEvent(ProductEvent e) {
                System.out.println(e);
            }
        };
        menuAddListener = new JMenuItem("Add Listener");
        menuAddListener.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                ps.addProductListener(pLis);

                ps.addProductListener(new IProductListener(){
                    public void onProductEvent(ProductEvent e) {
                        System.err.println(e+ "1");
                    }
                });
                ps.addProductListener((e1)->{System.err.println(e1.getProduct());} );
                writeString("You've added Listener, Anonymous Listener and Lambda Listener \n");
            }   
        });
        menuEvent.add(menuAddListener);

С удалением обычного слушателя проблем нет, но вот анонимный и лямбда даются очень туго. Есть вариант достать слушателей через GetListeners / GetActionLisnteners, но идей как это реализовать нет.

Код удаления пока выглядит так:

menuRemoweL = new JMenuItem("Remove listener");
menuRemoweL.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        ps.removeProductListener(pLis);


        ps.removeProductListener(ps.getActionListeners());//не знаю, как реализовать гетАкшн

        writeString("You've deleted Listener, Anonymous Listener and Lambda Listener \n");
    }
});
menuEvent.add(menuRemoweL);
menuBar.add(menuItemInfo);

Класс, для которого создаются слушатели:

public class ProductStore extends AbstractStore {

List<IProductListener> productListeners = new CopyOnWriteArrayList<>();

public void addProductListener(IProductListener listener) {
    productListeners.add(listener);
}

public void removeProductListener(IProductListener listener) {
    productListeners.remove(listener);
}

protected void fireProductEvent(ProductEvent obj) {
    productListeners.forEach((lsn)->lsn.onProductEvent(obj));
}
private WoodDirectory wd = new WoodDirectory();

{
    try {
        arr[0]=new Timber(wd.get(0), 12.3f, 1f, 1.5f);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        JOptionPane.showMessageDialog(null, e.getMessage(), "Entering product", JOptionPane.ERROR_MESSAGE);
    }
    try {
        arr[1]=new Timber(wd.get(1), 14.6f, 0.5f, 1.6f);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        JOptionPane.showMessageDialog(null, e.getMessage(), "Entering product", JOptionPane.ERROR_MESSAGE);
    }
    try {
        arr[2]=new Timber(wd.get(2), 11.0f, 0.6f, 2f);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        JOptionPane.showMessageDialog(null, e.getMessage(), "Entering product", JOptionPane.ERROR_MESSAGE);
    }
    count = 3;
}
public void add(IWeight newProduct) {
    super.add(newProduct);
    fireProductEvent(new ProductEvent(this, newProduct));
}
public String toString() {
    StringBuilder sb = new StringBuilder("Storage: \n");
    sb.append(super.toString());
    return sb.toString();       
}
public float calcTotalWeight() {
    return super.calcTotalWeight() ;
}

}


Ответы (1 шт):

Автор решения: Nowhere Man

Если нужно удалять группу слушателей, признаком которой является конкретная реализация pLis: [pLis, anonLis, lambdaLis], то следует изменить реализацию метода ProductStore::removeProductListener, чтобы удалить три (или менее) элемента подряд, начиная с индекса:

public void removeProductListener(IProductListener listener) {
    int index = productListeners.indexOf(listener);
    if (index > -1) {
        for (int i = 0; i < 3 && !productListeners.isEmpty(); i++) {
            productListeners.remove(index);
        }
    }
}

Также вместо цикла с жёстко закодированным количеством элементов подгруппы можно "очистить" подсписок между двумя индексами: начало - индекс первого вхождения, конец - индекс следующего вхождения или конец списка:

public void removeProductListener(IProductListener listener) {
    int index = productListeners.indexOf(listener);
    if (index > -1) {
        int nextIndex = productListeners.indexOf(listener, index);
        if (nextIndex == -1) nextIndex = productListeners.size();
        List<IProductListener> group = productListeners(index, nextIndex);
        group.clear();
    }
}
→ Ссылка