Удаление анонимного и лямбда слушателя
Есть меню, в которой при нажатии на кнопку создается/удаляется три слушателя: обычный, анонимный и лямбда. Инициализация их выглядит так:
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 шт):
Если нужно удалять группу слушателей, признаком которой является конкретная реализация 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();
}
}