Rendering Problem with Richfaces 4
haukegulich Oct 31, 2011 8:24 AMHello everyone,
I have a strange problem with richfaces 4 I used to have with primefaces as well. Before I blamed primefaces but now the same thing happens with richfaces, so I think it might be my problem :-)
What I want:
I want a left-side panel with some images like a menu navigation (Main-Page, Help-Page, Settings-Page etc) The right panel should have the content. The loading should be realized with ajax because I have a MP3 player on the left side panel which would be start over again if the request isn't ajax.
What is the problem:
After deploying the application everything looks good if I go to the index.xhtml page (see below). If I click any of those buttons the content on the right panel changes but isn't rendered correctly at all. If I hit F5 (Refresh) it looks good.
Also the rich:dataScroller works only in one direction. If I am one page one, I can switch to two and three, but if I go back to page two, it won't be rendered. It stays at page three. If I hit F5 it will be rendered correctly with page two.
The thrid thing is that some components should be rendered only if some backing bean value isn't null. So I do something like this:
{code:xml}
<rich:panel id="lightTimerDetails" rendered="#{control.lightTimer!=null?'true':'false'}"> |
{code}
But this will be only noticed after hitting F5 again.
What I am using:
Richfaces 4
JBoss 7
Maven build the EAR file with one JAR (Server-Applicatoin) and the WAR (Web-Application)
What I programmed so far:
index.xhtml
{code:xml}
<!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:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich">
<f:view>
<h:head>
<title>Whatever</title>
<link href="style/mainstyle.css" rel="stylesheet" type="text/css" />
<link href="style/control.css" rel="stylesheet" type="text/css" />
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2" columnClasses="navigation, content">
<h:panelGroup>
<rich:panel styleClass="logoPanel">
<h:graphicImage url="graphics/#{systemBean.logo}"></h:graphicImage>
</rich:panel>
<rich:panel styleClass="navigationPanel" header="Navigation">
<a4j:commandButton value=" " id="menu_startseite" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_home.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_steuerung" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_control.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_timer" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_timer.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_statistik" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_statistik.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_musik" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_music.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_webcam" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_webcam.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_alert" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_alert.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_help" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_help.png')"></a4j:commandButton><br />
<a4j:commandButton value=" " id="menu_einstellung" actionListener="#{navigationBean.changePage}" render="content" style="border: none; width: 55px; height: 55px; background-color: white; background-image: url('graphics/menu_setting.png')"></a4j:commandButton><br />
</rich:panel>
</h:panelGroup>
<rich:panel styleClass="contentPanel" id="content">
<ui:include src="#{navigationBean.contentPage}"></ui:include>
</rich:panel>
</h:panelGrid>
</h:form>
</h:body>
</f:view>
</html>
{code}
The commandButtons call the actionListener which set the variable contentPage. This is actual a string representing the xhtml page which should be rendered on the content part.
NavigationBean.java
{code}
package de.hauke.client.system;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;
@ManagedBean (name="navigationBean")
@SessionScoped
public class NavigationBean implements Serializable{
private static final long serialVersionUID = 1L;
private static final Logger logger = Logger.getLogger(NavigationBean.class);
/**
* Welche Seite soll im Content für diese Session gerendert werden
*/
private String contentPage = "startseite.xhtml";
/**
* Diese Methode wird aufgerufen, wenn ein Benutzer auf einen Menupunkt klickt
* @param evt
*/
public void changePage(ActionEvent evt) {
logger.debug("Ein Navigationslink wurde angeklickt : " + evt.getComponent().getId());
if(evt.getComponent().getId().equalsIgnoreCase("menu_startseite")) {
contentPage = "startseite.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_steuerung")) {
contentPage = "steuerung.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_timer")) {
contentPage = "timer.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_statistik")) {
contentPage = "statistik.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_musik")) {
contentPage = "musik.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_webcam")) {
contentPage = "webcam.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_alert")) {
contentPage = "alert.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_help")) {
contentPage = "help.xhtml";
} else if(evt.getComponent().getId().equalsIgnoreCase("menu_einstellung")) {
contentPage = "einstellung.xhtml";
}
}
public String getContentPage() {
return contentPage;
}
public void setContentPage(String contentPage) {
this.contentPage = contentPage;
}
}
{code}
And here is the content of the page for the second button
steuerung.xhtml
{code:xml}
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<rich:tabPanel>
<rich:tab name="Beleuchtung">
<rich:panel style="height:600px;overflow:auto;">
<h:form>
<a4j:jsFunction name="selectLight" render="timerListe, createTimerButton" action="#{control.selectLight}">
<a4j:param name="param1" assignTo="#{control.selectedLightID}" />
</a4j:jsFunction>
<a4j:jsFunction name="selectLightTimer" render="timerListe,lightTimerDetails" action="#{control.selectLightTimer}">
<a4j:param name="param1" assignTo="#{control.selectedLightTimerID}" />
</a4j:jsFunction>
<rich:dataTable value="#{control.lightList}" onrowclick="selectLight(#{licht['id'].integerValue})" rowKeyVar="rowKey" var="licht" style="width:100%" id="lichtListe" columns="5" columnClasses="lightTableWidthNarrow,lightTableWidthLarge,lightTableWidthLarge,lightTableWidthNarrow,lightTableWidthLarge">
<a4j:push address="" ></a4j:push>
<rich:column>
<h:graphicImage value="graphics/#{licht['icon'].stringValue}" width="20"></h:graphicImage>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Beschreibung" />
</f:facet>
<h:outputText value="#{licht['beschreibung'].stringValue}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Letztes mal eingeschaltet / läuft seit" />
</f:facet>
<h:outputText value="xxxxxx"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Anzahl der Timer" />
</f:facet>
<h:outputText value="#{licht['anzahlTimer'].integerValue}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Funktion" />
</f:facet>
<a4j:commandButton value="#{licht['buttonText'].stringValue}" disabled="#{licht['buttonDisable'].stringValue}" actionListener="#{control.switchLightState}">
<f:param name="switchButton" id="switchButton" value="#{licht['id'].stringValue}"/>
</a4j:commandButton>
</rich:column>
</rich:dataTable>
</h:form>
</rich:panel>
</rich:tab>
<rich:tab name="Pumpen">
</rich:tab>
</rich:tabPanel>
</html>
{code}
Here are two screens from how it looks BEFORE hitting F5
And here is the image AFTER F5
I believe the problem is
{code:xml}
<rich:panel styleClass="contentPanel" id="content">
<ui:include src="#{navigationBean.contentPage}"></ui:include>
</rich:panel>
{code}
But I couldn't find any other EASY way to relize that.
Thanks a lot,
Hauke