Nesse tutorial vou mostrar uma solução que encontrei para criar um menu dinâmico infinito multinível.
Primeiramente vamos criar a classe Menu:
public class Menu {
private Long id;
private String nome; //Rótulo do menu.
private String navegacao; //Nome da navegação cadastrada no faces-config.xml
private Menu menuSuperior; //Elemento pai do menu caso haja.
private TipoMenu tipoMenu;
public Menu getMenuSuperior() {
return menuSuperior;
}
public TipoMenu getTipoMenu() {
if (tipoMenu == null){
tipoMenu = TipoMenu.ITEM;
}
return tipoMenu;
}
public String getNome() {
return nome;
}
public String getNavegacao() {
return navegacao;
}
public void setNome(String nome) {
this.nome = nome;
}
public void setNavegacao(String navegacao) {
this.navegacao = navegacao;
}
public void setMenuSuperior(Menu menuSuperior) {
this.menuSuperior = menuSuperior;
}
public void setTipoMenu(TipoMenu tipoMenu) {
this.tipoMenu = tipoMenu;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}A classe TipoMenu é um enumerador:
public enum TipoMenu {
DROP_DOWN,
GROUP,
ITEM;
}Realizando o controle:
public class MenuControle {
private HtmlToolBar htmlToolBar;
private int countId = 1;
@SuppressWarnings("unchecked")
public HtmlToolBar getHtmlToolBar(){
if (htmlToolBar == null){
try{
ArrayList<Menu> itens = (ArrayList<Menu>) getMenuDAO().listar(Menu.class); //UTILIZAR SEU MÉTODO DE LISTAGEM.
FacesContext context = FacesContext.getCurrentInstance();
htmlToolBar = (HtmlToolBar) context.getApplication().createComponent(HtmlToolBar.COMPONENT_TYPE);
htmlToolBar.setId("myToolBar" + countId++);
//BOTÃO SAIR
HtmlToolBarGroup htmlToolBarGroup = (HtmlToolBarGroup) context.getApplication().createComponent(HtmlToolBarGroup.COMPONENT_TYPE);
htmlToolBarGroup.setLocation("right");
htmlToolBarGroup.setId("myToolBarGroup" + countId++);
HtmlMenuItem menu = (HtmlMenuItem) context.getApplication().createComponent(HtmlMenuItem.COMPONENT_TYPE);
menu.setValue("Sair");
menu.setSubmitMode("ajax");
MethodExpression action = context.getApplication().getExpressionFactory().createMethodExpression(context.getELContext(), "#{menuControle.logout}", String.class, new Class[]{});
menu.setActionExpression(action);
htmlToolBarGroup.getChildren().add(menu);
htmlToolBar.getChildren().add(htmlToolBarGroup);
if (itens == null || itens.isEmpty()){
return htmlToolBar;
}
Map<Long, Map<Long, Menu>> menuTotal = new HashMap<Long, Map<Long, Menu>>();
for (Menu item : itens) {
Long idPai = item.getMenuSuperior() == null ? 0L : item.getMenuSuperior().getId();
if (!menuTotal.containsKey(idPai)){
menuTotal.put(idPai, new HashMap<Long, Menu>());
}
menuTotal.get(idPai).put(item.getId(), item);
}
montaMenu(context, htmlToolBar, menuTotal, 0L);
}catch (Exception e) {
e.printStackTrace();
}
}
return htmlToolBar;
}
public static void montaMenu(FacesContext context, UIComponent pai, Map<Long, Map<Long, Menu>> menuTotal, Long idPai){
Iterator<Long> it = menuTotal.get(idPai).keySet().iterator();
while (it.hasNext()) {
Long key = it.next();
Menu item = menuTotal.get(idPai).get(key);
UIComponent novoPai = null;
switch (item.getTipoMenu()) {
case DROP_DOWN:
HtmlDropDownMenu menuAdm = (HtmlDropDownMenu) context.getApplication().createComponent(HtmlDropDownMenu.COMPONENT_TYPE);
menuAdm.setValue(item.getNome());
pai.getChildren().add(menuAdm);
novoPai = menuAdm;
break;
case GROUP:
HtmlMenuGroup group = (HtmlMenuGroup) context.getApplication().createComponent(HtmlMenuGroup.COMPONENT_TYPE);
group.setValue(item.getNome());
pai.getChildren().add(group);
novoPai = group;
break;
case ITEM:
HtmlMenuItem menu = (HtmlMenuItem) context.getApplication().createComponent(HtmlMenuItem.COMPONENT_TYPE);
menu.setValue(item.getNome());
menu.setSubmitMode("ajax");
MethodExpression action = context.getApplication().getExpressionFactory().createMethodExpression(context.getELContext(), item.getNavegacao(), null, new Class<?>[0]);
menu.setActionExpression(action);
pai.getChildren().add(menu);
break;
}
if (menuTotal.containsKey(key)){
montaMenu(context, novoPai, menuTotal, key);
}
}
}
public String logout(){
//TODO SEU MÉTODO DE SAÍDA.
return "login";
}
public void setHtmlToolBar(HtmlToolBar htmlToolBar) {
this.htmlToolBar = htmlToolBar;
}
}Agora basta inserir o menu no jsp:
<rich:toolBar binding="#{menuControle.htmlToolBar}"></rich:toolBar>
Não se esqueça de cadastrar a navegação no faces-config.xml.
Valew, galera!
Abraços!!!
Anderson, excelente dica. :P
ResponderExcluirEu quebrei muito a cabeça tentando deixar essa montagem do menu totalmente dinâmica e com essa sua dica ficou show de bola.
Parabéns!
Boa noite Anderson,
ResponderExcluirGostei muito da estrutura que vc montou para o menu dinamico mas estou com um problema e será que pode me ajudar?
Fiz conforme o post e para fazer um teste adicionei um list de menu manualmente:
Menu menu1 = new Menu();
menu1.setId(1L);
menu1.setNome("TESTE");
menu1.setTipoMenu(TipoMenu.DROP_DOWN);
o erro apresentado é:
04/08/2010 00:37:35 com.sun.facelets.FaceletViewHandler handleRenderException
SEVERE: Error Rendering View[/index.xhtml]
javax.faces.FacesException: Parent menu for menu group (id=j_id5:j_id11) has not been found.
Obrigado
Opa...
ResponderExcluirTudo bem, Dudu!?
Acabei de atualizar o código. Realmente havia um erro, os id's têm que ser definidos previamente.
Qualquer coisa, estamos a disposição.
Abraços!!!
boa tarde anderson vc nao teria nenhum tutorial ensinando a criar menu dinamico com panelmenu + panelmenugroup
ResponderExcluircara ja to a mais de 15 dias tentando criar um menu destes so que, nao consigo fazer a parte de navegacao.
meu email duzackzack@hotmail.com
Eduardo,
ExcluirAinda não utilizei o rich:panelMenu, mas acredito que substituindo o HtmlMenu nesse tutorial, deve funcionar. O difícil do menu dinâmico é a lógica de sua criação. Tente substituir, se der resultado positivo nos informe.
Abraços!
Este comentário foi removido pelo autor.
ResponderExcluirNessa linha de código está dando erro:
ResponderExcluir(Logo após o hello world)
binding="#{menuControle.htmlToolBar}"
Erro-> #{...} Not allowed in a template text body.
Isso acontece com todos os menus que eu já tentei utilizar :(
Tentei entrar em contato contigo, Anderson, mas não achei nenhum e-mail aqui no site de contato...
Valeu