да, вы можете для этого переопределить какой-то метод в jsf render или компонентном классе
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));
}
}
но в классе MyEvent вам нужно переопределить некоторые методы
@Override
public PhaseId getPhaseId() {
return PhaseId.INVOKE_APPLICATION;
}
, который будет определять, на каком лице будет обрабатываться это событие (по умолчанию это ANY_PHASE и триггер события в той же фазе, в которой оно зарегистрировано)
@Override
public boolean isAppropriateListener(FacesListener listener) {
return false;
}
если у вас есть подходящий слушатель, он должен вернуть true
если у вас есть подходящий слушатель для MyEvent, тогда JSF вызовет метод processAction (событие ActionEvent) этого слушателя, когда он вызовет событие, в противном случае он вызовет метод вещания в классе компонентов, который должен быть переопределен разработчиком
@Override
public void broadcast(FacesEvent event) throws AbortProcessingException {
super.broadcast(event);
if(event instanceof MyEvent){
try {
processMyEvent(event);
} catch (Exception e) {
// TODO: handle exception
}
}
}
Даже если вы можете зарегистрировать любое событие самостоятельно, используя компонент queueEvent (событие FacesEvent), оно зарегистрирует событие и получит фазу, на которой оно будет вызываться методом getPhaseId () в классе MyEvent, если метод getPhaseId () не переопределяется devloper, тогда он сработает в той же фазе, в которой он зарегистрировал