JSF добавляет прослушиватели действий

Я динамически создаю MenuItem и хочу добавить настраиваемый прослушиватель при нажатии MenuItem.

Я пытался добавить addActionListener и setActionListener, но ни один из них не вызывается при нажатии на ссылку.

Похоже, что к MenuItem прикреплен список под названием «слушатели» (я вижу это при отладке настройки MenuItem со статическим слушателем). Любая идея, как правильно добавить слушателя?


person DD.    schedule 16.02.2010    source источник


Ответы (2)


Их необходимо создать и добавить следующим образом (скопировано из один из моих предыдущих ответов):

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression actionListener = context.getApplication().getExpressionFactory()
    .createMethodExpression(context.getELContext(), "#{bean.actionListener}", null, new Class[] {ActionEvent.class});
uiCommandComponent.addActionListener(new MethodExpressionActionListener(actionListener));

... где #{bean.actionListener} фактически существует и объявлен следующим образом в классе вспомогательного компонента, связанного с именем управляемого компонента bean:

public void actionListener(ActionEvent event) {
    // ...
}

Что еще более важно, вам необходимо присвоить любому динамически создаваемому компоненту UICommandUIInput) фиксированный идентификатор, иначе он получит автоматически сгенерированный идентификатор, что может привести к тому, что JSF не сможет найти/сопоставить его во время этап применения значений запроса.

Таким образом, сделайте также:

uiCommandComponent.setId("someFixedId");
person BalusC    schedule 16.02.2010
comment
Тогда вы, по-видимому, все еще используете старый JSF 1.0/1.1 (который был заменен на 1.2 более 4 (!!) лет назад). Щелкните вышеупомянутую ссылку, чтобы увидеть способ JSF 1.1 для создания файла ActionListener. Вам по-прежнему необходимо установить фиксированный идентификатор самостоятельно! - person BalusC; 16.02.2010
comment
Оказывается, в Maven была ссылка на другой проект, который использовал MyFaces, и хотя у меня был JSF 1.2, он не компилировался :-)... Еще раз спасибо за ваш ответ. - person DD.; 16.02.2010
comment
Один уникальный идентификатор для каждого компонента. При необходимости вы можете добавить к нему какой-нибудь счетчик, например. child.setId("someFixedId" + parent.getChildCount()); parent.getChildren().add(child); - person BalusC; 16.02.2010
comment
вау... такой отстой, что мне нужно придумать уникальную стратегию именования только для того, чтобы добавить слушателя! - person DD.; 16.02.2010
comment
Это не так сложно, если вы сделаете это с умом, также см. пример кода в комментарии. В качестве альтернативы вы также можете получить UIViewRoot#createUniqueId(): java.sun.com/javaee/6/docs/api/javax/faces/component/ - person BalusC; 16.02.2010
comment
большое спасибо за вашу помощь .... Я не думаю, что мой компонент расширяет UIViewRoot ... могу ли я все еще использовать это? - person DD.; 17.02.2010
comment
Это доступно только FacesContext#getViewRoot() :) - person BalusC; 17.02.2010
comment
Не совсем уверен, что происходит, но по какой-то причине IceFaces продолжает воссоздавать мои меню... createUniqueID продолжает меняться... и прослушиватели событий не вызываются. Прекрасно работает с методологией счетчика, но ее сложнее протестировать. - person DD.; 17.02.2010

Основная проблема, на которую указал BalusC, заключается в том, что вам нужно установить идентификатор. Затем вы можете добавить прослушиватели событий следующим образом: private MenuItem createItem(String name){ MenuItem item=new MenuItem(); item.addActionListener (новый ActionListener () {

        public void processAction(ActionEvent event)
                throws AbortProcessingException {
            // handle event

        }
    });
    item.setValue(name);
    return item;
}
person DD.    schedule 16.02.2010