最近在使用richfaces-ui-3.3.3.Final的rich:tabPanel的时候,没有给rich:tab设置name属性,然后就会在表单提交的时候报空指针,然后查看源码后,发现UITabPanel类使用name进行比较是否是该tab
官方使用手册文档
http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/rich_tabPanel.html
针对于tabPanel的说明:
There is also the "selectedTab" attribute. The attribute keeps an active tab name; therefore, an active tabPanel could be changed with setting a name of the necessary tab to this attribute.
粗略翻译:有一个selectedTab属性。该属性保持一个活动的tab name;因此,一个活动的tabPanel被改变,就伴随着设定一个name属性给该tab
空指针:
Caused by: java.lang.NullPointerException
at org.richfaces.component.UITabPanel.queueEvent(UITabPanel.java:266)
at javax.faces.event.FacesEvent.queue(FacesEvent.java:130)
at org.richfaces.renderkit.TabPanelRendererBase.doDecode(TabPanelRendererBase.java:106)
at org.ajax4jsf.renderkit.RendererBase.decode(RendererBase.java:75)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:790)
at javax.faces.component.UIInput.decode(UIInput.java:744)
at org.richfaces.component.UISwitchablePanel.processDecodes(UISwitchablePanel.java:167)
at org.richfaces.component.UITabPanel.processDecodes(UITabPanel.java:155)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1042)
at org.ajax4jsf.component.UIAjaxForm.processDecodes(UIAjaxForm.java:65)
at org.ajax4jsf.component.UIAjaxRegion.processDecodes(UIAjaxRegion.java:103)
at org.ajax4jsf.component.AjaxViewRoot$1.invokeContextCallback(AjaxViewRoot.java:400)
at org.ajax4jsf.component.ContextCallbackWrapper.invokeContextCallback(ContextCallbackWrapper.java:44)
at javax.faces.component.UIComponent.invokeOnComponent(UIComponent.java:1253)
... 45 more
页面代码:
<a4j:form id="budgetform">
<rich:tabPanel id="tpBudgetCollection" switchType="client" immediate="true" selectedTab="tbBudget" >
<!-- name 设置成formID:tabId 即budgetform:tbBudget-->
<rich:tab id="tbBudget" label="aa" name="budgetform:tbBudget" immediate="true">
</rich:tab>
<!-- name 设置成formID:tabId 即budgetform:tbCollection -->
<rich:tab id="tbCollection" label="bb" name="budgetform:tbCollection" immediate="true">
</rich:tab>
<a4j:commandButton id="submitForm" value="submit" action="#{testController.save}" ></a4j:commandButton>
</a4j:form>
richfaces-ui-3.3.3.Final源码下载页面:http://www.jboss.org/richfaces/download/stable
查看源码:
private UITab processedTab(UIComponent component, Object object){
if (object != null) {
return getTabWithName(object);
}
return (UITab)component;
}
//TODO use getTabs() iterator
private UITab getTabWithName(Object tabName){
List children = getChildren();
for (Iterator iterator = children.iterator(); iterator.hasNext();) {
UIComponent childComponent = (UIComponent) iterator.next();
//因在这里tabName为"",没有一个匹配上的,所以返回null。
if(childComponent instanceof UITab && ((UITab)childComponent).getName().equals(tabName)){
return (UITab)childComponent;
}
}
return null;
}
public void queueEvent(FacesEvent event) {
if(event instanceof SwitchablePanelSwitchEvent && this.equals(event.getComponent())){
SwitchablePanelSwitchEvent switchEvent = (SwitchablePanelSwitchEvent)event;
UITab tab = processedTab(switchEvent.getEventSource(),switchEvent.getValue());
//Check if target Tab is immediate
//在这里就会报空指针异常
processedTabImmediate = tab.isImmediate();
}
if(event instanceof ActionEvent && event.getComponent()instanceof UITab){
if(isImmediate()){
event.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
}
}
super.queueEvent(event);
}