Executing the ActionListener of a (Primefaces) menu item leads to an IllegalStateException

a 夏天 提交于 2019-11-29 10:39:31
BalusC

EL (read: reflection) cannot access/construct anonymous classes. Refactor them into fullworthy classes.

So, replace

    item.addActionListener(new ActionListener() {
        @Override
        public void processAction(ActionEvent event)
                throws AbortProcessingException {
            System.out.println(event.toString());
        }
    });

by

    item.addActionListener(new FooActionListener());

and

public class FooActionListener implements ActionListener {

    @Override
    public void processAction(ActionEvent event)
            throws AbortProcessingException {
        System.out.println(event.toString());
    }

}

See also:

It looks like an additional restriction is that the ActionListener class have no contructor arguments, which kind of adds insult to injury here. As far as I can see the addActionListener probably just stores the class name of the object passed to it.

In fact if the intent was to make this listener unusable by preventing any data being passed to the listener from your backing bean they could hardly have done more.

You get another IllegalStateException if you try subclassing MenuItem.

You can't pass an object containing data to MenuItem as a value, it requires a String.

It doesn't seem to allow the listener as an inner class.

But I think I may have cracked it, by putting the needed data in the attributes map of the menu item.

Here's what I wound up with:

public class MenuSelectListener implements ActionListener {
public static final String MENU_ACTION_KEY = "menu.action.delegate";

private final static Log log = LogFactory.getLog(MenuSelectListener.class);

@Override
public void processAction(ActionEvent ae) throws AbortProcessingException {
    System.out.println("listener invoked");
    if (ae.getComponent() instanceof MenuItem) {
        Runnable delegate = (Runnable) ae.getComponent().getAttributes().get(MENU_ACTION_KEY);
        if(delegate != null)
            delegate.run();
        else
            log.error("Menu action has no runnable");
    } else {
        log.error("Listener, wrong component class: " + ae.getComponent().getClass().getName());
    }
}

}

To set up an item:-

        item.setValue("Cancel");
        sm.getChildren().add(item);
        item.addActionListener(new MenuSelectListener());
        item.getAttributes().put(MenuSelectListener.MENU_ACTION_KEY, new MiscActionDelegate(MiscActions.close));

With:

private class MiscActionDelegate implements Runnable, Serializable {

(works as an inner class, but cannot be anonymous).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!