Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF: <f:event> with custom events

I can't figure out if it is possible to use custom events using f:event. The book by Ed Burns suggests to ad the @NamedEvent annotation to the Event class and to use:

<f:event type="com.foo.bar.myEvent" listener="#{listener} />

but the event seems never to be instantiated.

From my point of view this makes sense, since the component does not know anything about the event, e.g. when to publish, so this might be useful for custom component authors only.

On the other hand, standard components should be able to publish the the event if derived from e.g. PostAddToViewEvent. Anyway, custom events seem to be never published by standard components.

Am I missing something? Is there a convenient way to use custom events with standard components?

Here is what I wanted to do:

<h:inputText id="input">
    <f:event type="foo.bar.MyCustomEvent" /> 
</h:inputText>
public class MyCustomEvent extends javax.faces.event.PostAddToViewEvent {
}
like image 651
Darkspirit Avatar asked Nov 04 '22 14:11

Darkspirit


1 Answers

yes you can for this you have to override some method in jsf render or component class

public class MyComponent extends HtmlInputText       or   public class MyRenderer extends TextRenderer

@Override
public void decode(FacesContext context, UIComponent component) {
    super.decode(context, component);

    String sourceName = context.getExternalContext().getRequestParameterMap().get("javax.faces.source");
    if(sourceName != null && sourceName.equals(component.getClientId())){
        component.queueEvent(new MyEvent(component));
    }
}

but in MyEvent class you have to override some methods

@Override
public PhaseId getPhaseId() {
    return PhaseId.INVOKE_APPLICATION;
}

which will define in which face this event will process (by default it is ANY_PHASE and event trigger in same phase in which it registered)

@Override
public boolean isAppropriateListener(FacesListener listener) {
    return false;
}

if you have appropiate listener it must return true if you have appropiate listener for MyEvent then JSF will call that listener's processAction(ActionEvent event) method when it will trigger event, otherwise it will call broadcast method in component class which has to be override by developer

@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
    super.broadcast(event);

    if(event instanceof MyEvent){
        try {
            processMyEvent(event);
        } catch (Exception e) {
            // TODO: handle exception
        }
    }
}

Even you can register any event by your own by using component queueEvent(FacesEvent event) method, it will regiester event and it get the phase in which it will trigger by getPhaseId() method in MyEvent class if getPhaseId() method is not overrided by devloper then it will trigger in same phase in which it registered

like image 91
Lokesh Gupta Avatar answered Nov 15 '22 13:11

Lokesh Gupta