[Resolvido] JSF + Primefaces: Tab com conteúdo dinâmico

Vou fazer como você falou…

Só que a tab não é criada.
Quando eu entro na página pela primeira vez aparece a msg:

Construtor…
label: null, url: nulltabId: 0

Quando eu clico no link/botão aparece:

Setando label: Aplicação 2
addTab…
label: Aplicação 2, url: teste.xhtmltabId: 1

Mas nada acontece, nenhuma tab é criada.
Aí quando eu clico em outro ou no mesmo link, nada acontece…
Quando eu dou um refresh (CTRL F5) na página, aparece:

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/sitic] threw exception [1] with root cause
java.lang.IllegalArgumentException: 1
	at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)
	at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)
bla bla bla...

Olha como ficou meu TabViewController:

package br.com.sitic.sitic.sistema.controller;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="tabViewController")
@SessionScoped
public class TabViewController {
	private String label;
	private String url;
	private int tabId;
	private List<TabItem> tabList;
	private int activeIndex = 0;

	public TabViewController(){
		tabList = new ArrayList<TabItem>();
		System.out.println("Construtor...");
		System.out.println("label: "+label+", url: "+url+"tabId: "+tabId);
	}
	
	public void addTab(){
		System.out.println("addTab...");
		System.out.println("label: "+label+", url: "+url+"tabId: "+tabId);
		this.tabList.add(new TabItem(this.label, this.url, this.tabId));
	}
	
	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		System.out.println("Setando label: "+label);
		this.label = label;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public int getTabId() {
		return tabId;
	}

	public void setTabId(int tabId) {
		this.tabId = tabId;
		addTab();
	}

	public List<TabItem> getTabList() {
		return tabList;
	}

	public void setTabList(List<TabItem> tabList) {
		this.tabList = tabList;
	}

	public int getActiveIndex() {
		return activeIndex;
	}

	public void setActiveIndex(int activeIndex) {
		this.activeIndex = activeIndex;
	}

	public class TabItem {
		private String name;
		private String url;
		private int tabIndex;

		public TabItem(String name, String url, int tabIndex)
		{
			this.setName(name);
			this.setUrl(url);
			this.setTabIndex(tabIndex);
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public int getTabIndex() {
			return tabIndex;
		}

		public void setTabIndex(int tabIndex) {
			this.tabIndex = tabIndex;
		}

	}
}

E o index.xhtml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
      
    <f:view contentType="text/html">
        <h:head>
            <f:facet name="first">
                <meta http-equiv="X-UA-Compatible" content="EmulateIE8" />
                <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
                <title>PrimeFaces - ShowCase</title>
            </f:facet>

            <link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/css/default.css" />
            <link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/css/syntaxhighlighter/syntaxhighlighter.css" />

            <style type="text/css">
                .ui-layout-north {
                    z-index:20 !important;
                    overflow:visible !important;;
                }

                .ui-layout-north .ui-layout-unit-content {
                    overflow:visible !important;
                }
            </style>
        </h:head>


        <h:body>

            <p:layout fullPage="true" >

                <p:layoutUnit id="top" position="north" size="50">
                </p:layoutUnit>

                <p:layoutUnit id="bottom" position="south" size="60">
                </p:layoutUnit>

                <p:layoutUnit id="left" position="west" size="300" resizable="true" closable="true" collapsible="true" header="Options" minSize="200">
					<h:form>
						<p:accordionPanel value="#{menuController.menus}" var="menu">
							<p:tab title="#{menu.group}">
								<ul>
									<ui:repeat value="#{menu.subMenu}" var="subMenu">
										<p:commandLink ajax="true" oncomplete="updateTabView()">
											<f:setPropertyActionListener target="#{tabViewController.label}"
												value="#{subMenu.label}" />
											<f:setPropertyActionListener target="#{tabViewController.url}"
												value="#{subMenu.url}" />
											<f:setPropertyActionListener target="#{tabViewController.tabId}"
												value="#{subMenu.tabId}" />
											
											<h:outputText value="#{subMenu.label}" />
											<h:outputText value="#{subMenu.url}" />
											<h:outputText value="#{subMenu.tabId}" />
											
										</p:commandLink>
										<br />
									</ui:repeat>
								</ul>
								
								<p:remoteCommand name="updateTabView" update=":tabView"></p:remoteCommand>
							</p:tab>
						</p:accordionPanel>
					</h:form>
                </p:layoutUnit>

                <p:layoutUnit id="right" position="east" size="250" header="Gallery" resizable="true" closable="true" collapsible="true" style="text-align:center">
                <h:form>
					 <p:themeSwitcher value="#{themeSwitcherBean.theme}" style="width:150px" effect="fade">
						<f:selectItem itemLabel="Choose Theme" itemValue="" />
						<f:selectItems value="#{themeSwitcherBean.themes}" />
						<p:ajax listener="#{themeSwitcherBean.saveTheme}" />
					 </p:themeSwitcher>
                </h:form>
                </p:layoutUnit>

                <p:layoutUnit id="center" position="center">


					<p:tabView id="tabView"	activeIndex="#{tabViewController.activeIndex}"	style="heigth:100%;">
						<p:ajax event="tabClose" listener="#{tabViewController.onTabClose}" />  
						<p:ajax event="tabChange" listener="#{tabViewController.onTabChange}" />

						<c:forEach items="#{tabViewController.tabList}" var="tabItem">   
							<p:tab title="#{tabItem.name}" id="#{tabItem.tabIndex}">   
								<ui:include src="http://#{request.serverName}:#{request.serverPort}#{request.contextPath}/#{tabItem.url}" />   
							</p:tab>   
						</c:forEach>
					</p:tabView>

                </p:layoutUnit>

            </p:layout>

            <p:dialog header="Basic Dialog" widgetVar="dlg1" modal="true"> 
                <h:outputText value="Resistance to PrimeFaces is futile!" />
            </p:dialog>

			<h:form>
			<p:remoteCommand name="rcAdicionarTabItem" actionListener="#{tabTeste.adicionarTabItem}" update=":tabView"></p:remoteCommand>
			</h:form>
        </h:body>

    </f:view>
</html>

Abraços e obrigado.

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/sitic] threw exception [1] with root cause
java.lang.IllegalArgumentException: 1
	at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)
	at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)

Vou fazer como você falou…

Só que a tab não é criada.
Quando eu entro na página pela primeira vez aparece a msg:

Construtor…
label: null, url: nulltabId: 0

Quando eu clico no link/botão aparece:

Setando label: Aplicação 2
addTab…
label: Aplicação 2, url: teste.xhtmltabId: 1

Mas nada acontece, nenhuma tab é criada.
Aí quando eu clico em outro ou no mesmo link, nada acontece…
Quando eu dou um refresh (CTRL F5) na página, aparece:

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/sitic] threw exception [1] with root cause
java.lang.IllegalArgumentException: 1
	at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)
	at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)
bla bla bla...

Olha como ficou meu TabViewController:

package br.com.sitic.sitic.sistema.controller;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="tabViewController")
@SessionScoped
public class TabViewController {
	private String label;
	private String url;
	private int tabId;
	private List<TabItem> tabList;
	private int activeIndex = 0;

	public TabViewController(){
		tabList = new ArrayList<TabItem>();
		System.out.println("Construtor...");
		System.out.println("label: "+label+", url: "+url+"tabId: "+tabId);
	}
	
	public void addTab(){
		System.out.println("addTab...");
		System.out.println("label: "+label+", url: "+url+"tabId: "+tabId);
		this.tabList.add(new TabItem(this.label, this.url, this.tabId));
	}
	
	public String getLabel() {
		return label;
	}

	public void setLabel(String label) {
		System.out.println("Setando label: "+label);
		this.label = label;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public int getTabId() {
		return tabId;
	}

	public void setTabId(int tabId) {
		this.tabId = tabId;
		addTab();
	}

	public List<TabItem> getTabList() {
		return tabList;
	}

	public void setTabList(List<TabItem> tabList) {
		this.tabList = tabList;
	}

	public int getActiveIndex() {
		return activeIndex;
	}

	public void setActiveIndex(int activeIndex) {
		this.activeIndex = activeIndex;
	}

	public class TabItem {
		private String name;
		private String url;
		private int tabIndex;

		public TabItem(String name, String url, int tabIndex)
		{
			this.setName(name);
			this.setUrl(url);
			this.setTabIndex(tabIndex);
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public int getTabIndex() {
			return tabIndex;
		}

		public void setTabIndex(int tabIndex) {
			this.tabIndex = tabIndex;
		}

	}
}

E o index.xhtml:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.org/ui"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
      
    <f:view contentType="text/html">
        <h:head>
            <f:facet name="first">
                <meta http-equiv="X-UA-Compatible" content="EmulateIE8" />
                <meta content='text/html; charset=UTF-8' http-equiv="Content-Type"/>
                <title>PrimeFaces - ShowCase</title>
            </f:facet>

            <link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/css/default.css" />
            <link type="text/css" rel="stylesheet" href="#{request.contextPath}/resources/css/syntaxhighlighter/syntaxhighlighter.css" />

            <style type="text/css">
                .ui-layout-north {
                    z-index:20 !important;
                    overflow:visible !important;;
                }

                .ui-layout-north .ui-layout-unit-content {
                    overflow:visible !important;
                }
            </style>
        </h:head>


        <h:body>

            <p:layout fullPage="true" >

                <p:layoutUnit id="top" position="north" size="50">
                </p:layoutUnit>

                <p:layoutUnit id="bottom" position="south" size="60">
                </p:layoutUnit>

                <p:layoutUnit id="left" position="west" size="300" resizable="true" closable="true" collapsible="true" header="Options" minSize="200">
					<h:form>
						<p:accordionPanel value="#{menuController.menus}" var="menu">
							<p:tab title="#{menu.group}">
								<ul>
									<ui:repeat value="#{menu.subMenu}" var="subMenu">
										<p:commandLink ajax="true" oncomplete="updateTabView()">
											<f:setPropertyActionListener target="#{tabViewController.label}"
												value="#{subMenu.label}" />
											<f:setPropertyActionListener target="#{tabViewController.url}"
												value="#{subMenu.url}" />
											<f:setPropertyActionListener target="#{tabViewController.tabId}"
												value="#{subMenu.tabId}" />
											
											<h:outputText value="#{subMenu.label}" />
											<h:outputText value="#{subMenu.url}" />
											<h:outputText value="#{subMenu.tabId}" />
											
										</p:commandLink>
										<br />
									</ui:repeat>
								</ul>
								
								<p:remoteCommand name="updateTabView" update=":tabView"></p:remoteCommand>
							</p:tab>
						</p:accordionPanel>
					</h:form>
                </p:layoutUnit>

                <p:layoutUnit id="right" position="east" size="250" header="Gallery" resizable="true" closable="true" collapsible="true" style="text-align:center">
                <h:form>
					 <p:themeSwitcher value="#{themeSwitcherBean.theme}" style="width:150px" effect="fade">
						<f:selectItem itemLabel="Choose Theme" itemValue="" />
						<f:selectItems value="#{themeSwitcherBean.themes}" />
						<p:ajax listener="#{themeSwitcherBean.saveTheme}" />
					 </p:themeSwitcher>
                </h:form>
                </p:layoutUnit>

                <p:layoutUnit id="center" position="center">


					<p:tabView id="tabView"	activeIndex="#{tabViewController.activeIndex}"	style="heigth:100%;">
						<p:ajax event="tabClose" listener="#{tabViewController.onTabClose}" />  
						<p:ajax event="tabChange" listener="#{tabViewController.onTabChange}" />

						<c:forEach items="#{tabViewController.tabList}" var="tabItem">   
							<p:tab title="#{tabItem.name}" id="#{tabItem.tabIndex}">   
								<ui:include src="http://#{request.serverName}:#{request.serverPort}#{request.contextPath}/#{tabItem.url}" />   
							</p:tab>   
						</c:forEach>
					</p:tabView>

                </p:layoutUnit>

            </p:layout>

            <p:dialog header="Basic Dialog" widgetVar="dlg1" modal="true"> 
                <h:outputText value="Resistance to PrimeFaces is futile!" />
            </p:dialog>

			<h:form>
			<p:remoteCommand name="rcAdicionarTabItem" actionListener="#{tabTeste.adicionarTabItem}" update=":tabView"></p:remoteCommand>
			</h:form>
        </h:body>

    </f:view>
</html>

Abraços e obrigado.

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/sitic] threw exception [1] with root cause
java.lang.IllegalArgumentException: 1
	at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)
	at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)

Rapaiz…
O problema tá na hora que eu coloco o id pra tab que será criada, aqui:

					<p:tabView id="tabView"	activeIndex="#{tabViewController.activeIndex}"	style="heigth:100%;">
						<p:ajax event="tabClose" listener="#{tabViewController.onTabClose}" />  
						<p:ajax event="tabChange" listener="#{tabViewController.onTabChange}" />

						<c:forEach items="#{tabViewController.tabList}" var="tabItem">   
							<p:tab title="#{tabItem.name}" [b]id="#{tabItem.tabIndex}"[/b]>   
								<ui:include src="http://#{request.serverName}:#{request.serverPort}#{request.contextPath}/#{tabItem.url}" />   
							</p:tab>   
						</c:forEach>
					</p:tabView>

Na criação do menu eu defini que cada aplicação terá o seu nro de tab fixo, mas acho que isso não dá certo né?
Quem tem que definir a tab como um contador é o TabViewController?
Valeu…
Abraço…

Consegui…
Pelo menos + ou -…
Tô trabalhando no onTabClose…
Pra removê-la quando ela for fechada…

Abração e obrigado pela ajuda.

Que bom que deu certo.
Agora é só lapidar para chegar ao modelo ideal para você.

Valeu

Olá, estou seguindo o exemplo abaixo e tendo esse mesmo problema abaixo também na hora de gerar uma aba nova clicando no addTab:

GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/sitic] threw exception [1] with root cause  
java.lang.IllegalArgumentException: 1  
    at javax.faces.component.UIComponentBase.validateId(UIComponentBase.java:542)  
    at javax.faces.component.UIComponentBase.setId(UIComponentBase.java:363)  

como fizeram para corrigir?

grato

Consegue resolver os problemas de uma forma diferente, com esse foreach ele volta todas as abas ao estado inicial quando abrimos outra aba, assim se temos campos de formulários que alteramos ou um resultado de pesquisa, eles estavam todos voltando ao estado inicial de quando a aba foi aberta.

valeu galera.

Estou querendo desenvolver um produto utilizando JSF 2.2 e Primefaces 4.0 com essa idéia do jlferreira, vocês conseguiram alguma coisa, se sim por favor postem aí a solução encontrada.

Como você resolveu a questão dos ID’s? Poderia postar o código aqui ?