2009-08-04 112 views
2

我一直在尝试很多不同的事情,我认为它们可以像预期的那样工作。但是,他们让我感到沮丧。这里是独家新闻:动态生成ice:commandButton组件

我在Java EE web应用程序中使用ICEFaces 1.8组件。我的目标是根据对数据库的查询呈现一堆ice:commandButtons。我希望这些按钮能够切换稍后我将用于参数的选择到数据库的另一个查询(基本上是针对一组用户的查询前端)。我想输出看起来像这样:

Deselected

当我点击一个按钮,我想下面的更新到我的网页:

Selected

当我创建的按钮在我的页面上静态地,因此:

<ice:commandButton id="seasonSEP09" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2009-2010" /> 
<ice:commandButton id="seasonSEP08" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2008-2009" /> 
<ice:commandButton id="seasonSEP07" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2007-2008" /> 
<ice:commandButton id="seasonSEP06" style="background-color: #FFFFFF;" partialSubmit="true" actionListener="#{bean.updateSeasons}" value="2006-2007" /> 

这很好,每个按钮单独工作,因为我窝呃期望。我的支持bean被更新,参数被正确添加到updateSeasons()方法中,并且我的输出在最后产生正确的记录。

但是,我知道这不是我想要的。我不想在系统中输入另一个赛季的时候随时更新这些信息。维护噩梦,对吧?

所以我想要做的是动态生成这些ice:commandButton组件基于我的数据库表充满季节对象。这里是我正在使用的季节类:

public class Season 
{ 
    String StartMonth; 
    String Season; 

    public String getStartMonth() 
    { 
     return StartMonth; 
    } 
    public void setStartMonth(String startMonth) 
    { 
     StartMonth = sweep; 
    }  
    public void setSeason(String season) 
    { 
     Season = season; 
    } 
    public String getSeason() 
    { 
     return Season; 
    } 
} 

非常简单。两个属性,我保证在数据库中是唯一的。

下面是支持bean我使用:

public class Bean 
{ 
    public Bean() 
    { 
     defineSeasonsList(); 
    } 

    public List<HtmlCommandButton> seasonsList; 

    // seasonsList getter & setter omitted 

    public List<String> selectedSeasons; 

    // selectedSeasons getter & setter omitted 

    private void defineSeasonsList() 
    { 
     seasonsList = new ArrayList<HtmlCommandButton>(); 
     selectedSeasons = new ArrayList<String>(); 

     try 
     { 
      hibernate.openTransaction(); 

      for(Season season:defineSeasonsListFromDataSource())) 
      { 
       HtmlCommandButton button = new HtmlCommandButton(); 

       button.setId("season" + season.getStartMonth()); 
       button.setValue(season.getSeason); 
       button.setStyle("background-color: #FFFFFF;"); 
       button.setPartialSubmit(true); 

       seasonsList.add(button); 
      }       
     } 
     catch (Exception e) 
     { 
      System.out.println("Error defining seasons list: " + e.getMessage()); 
     } 
     finally 
     { 
      hibernate.commitTransaction(); 
     }    
    } 

    public void updateSeasons(ActionEvent ae) 
    { 
     HtmlCommandButton selected = (HtmlCommandButton) ae.getComponent(); 

     if(selectedSeasons.contains(selected.getValue().toString())) 
     { 
      selectedSeasons.remove(selected.getValue().toString()); 
      selected.setStyle("background: #FFFFFF;"); 
     } 
     else 
     { 
      selectedSeasons.add(selected.getValue().toString()); 
      selected.setStyle("background: #009DD9; color: #FFFFFF;"); 
     } 
    } 
} 

好了,这才是我的困境(一个或多个)。

首先,我试图使这个标记:

<p> 
    <ice:panelGroup> 
     <ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season"> 
       <ice:commandButton binding="#{season}"/>           
     </ice:panelSeries> 
    </ice:panelGroup> 
</p>  

而且我得到这样的输出:

Bad Buttons

所以,感到沮丧和冒险,我试图使这个标记来实现我的目标是:

<p> 
    <ice:panelGroup> 
     <ice:panelSeries id="seasonsList" value="#{bean.seasonsList}" var="season"> 
       <ice:commandButton id="#{season.id}" partialSubmit="true" style="background-color: #FFFFFF" value="#{season.value}" actionListener="#{bean.updateSeasons}"/>           
     </ice:panelSeries> 
    </ice:panelGroup> 
</p> 

其中产生以下stac的ktrace:

2009年8月4日下午二时28分11秒com.sun.faces.lifecycle.Phase doPhase 重度:JSF1054:(阶段ID:RENDER_RESPONSE 6,查看ID:/phase1.jspx)异常阶段期间抛出执行:javax.faces.event.PhaseEvent [source = [email protected]] 2009年8月4日下午2时28分11秒org.apache.catalina.core.StandardWrapperValve调用 SEVERE:Servlet。 servlet的service()持久Faces Servlet抛出异常 java.lang.IllegalArgumentException:#{season.id} at javax.faces.component.UIComponentBase.validateId(UIComponentBase。的java:549) 在javax.faces.component.UIComponentBase.setId(UIComponentBase.java:351) 在javax.faces.webapp.UIComponentTag.createComponent(UIComponentTag.java:219) 在javax.faces.webapp.UIComponentClassicTagBase。 createChild所(UIComponentClassicTagBase.java:486) 在javax.faces.webapp.UIComponentClassicTagBase.findComponent(UIComponentClassicTagBase.java:670) 在javax.faces.webapp.UIComponentClassicTagBase.doStartTag(UIComponentClassicTagBase.java:1142) 在com.icesoft。 faces.component.CommandButtonTag.doStartTag(CommandButtonTag.java:741) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:204) at com.icesoft.faces.webapp.parser.Parser。 executeJspLifecycle(Parser.java:229) at com.i cesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp。 parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle( Parser.java:229) 在com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) 在com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle(Parser.java:229) at com.icesoft.faces.webapp.parser.Parser.parse(Parser.java:162) at com.icesoft.faces .application.D2DViewHandler.renderResponse(D2DViewHandler.java:464) at com.icesoft.faces.application.D2DViewHandler.renderView(D2DViewHandler.java:153) at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java :110) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100) at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139) at com.icesoft.faces .webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:17) at com.icesoft.faces.context.View $ 2 $ 1.respond(View.java:47) at com.icesoft.fac es.webapp.http.servlet.ServletRequestResponse.respondWith(ServletRequestResponse.java:197) at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet $ ThreadBlockingRequestResponse.respondWith(ThreadBlockingAdaptingServlet.java:36) at com.icesoft。 faces.context.View $ 2.serve(View.java:72) at com.icesoft.faces.context.View.servePage(View.java:133) at com.icesoft.faces.webapp.http.core.SingleViewServer .service(SingleViewServer.java:52) at com.icesoft.faces.webapp.http.common.ServerProxy.service(ServerProxy.java:11)​​ at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet $ 4。服务(MainSessionBoundServlet.java:114) at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24) at com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service(MainSessionBoundServlet.java:160) at com.icesoft.faces.webapp.http.servlet.SessionDispatcher $ 1.service(SessionDispatcher.java:42) at com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service(ThreadBlockingAdaptingServlet.java:19) at com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service(EnvironmentAdaptingServlet.java:63) at com .icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:62) at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23) at com.icesoft .faces.webapp.http.servlet.MainServlet.service(MainServlet.java:153) at javax.servlet.http.HttpServlet.service(HttpServlet。的java:717) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在org.apache。 catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve。的java:128) 在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在org.apache。 catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) 在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) at org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util .net.JIoEndpoint $ Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Thread.java:619)

我想做一些我不应该做的事情吗?

有没有更好的方法来完成这个目标?

如果需要更多信息,我很乐意提供。

在此先感谢,我的朋友们。

UPDATE

所以,我想从列表改变seasonsList集合列表,并呈现一些不同的标记,就像这样:

<p> 
    <ice:panelGroup> 
     <ice:panelSeries value="#{bean.seasonsList}" var="season"> 
       <ice:commandButton partialSubmit="true" style="background-color: #FFFFFF" value="#{season}" actionListener="#{Phase1EventBean.updateSeasons}"/>           
     </ice:panelSeries> 
    </ice:panelGroup> 
</p> 

和更改defineSeasonsList()方法:

public void defineNationalSeasonsList() 
{ 
    try 
    { 
     seasonsList = new ArrayList<String>(); 
     selectedSeasonsList = new ArrayList<String>(); 

     hibernate.openTransaction(); 

     for(UedaNationalDates season:hibernate.getList(new UedaNationalDates(), QueryFactory.getUedaNationalSeasons(hibernate.getHibSession()))) 
     { 
      nationalSeasonsList.add(season.getSeason()); 
     }  
    } 
    catch (Exception e) 
    { 
     System.out.println("Error defining nationalMeasurementPeriods: " + e.getMessage()); 
    } 
    finally 
    { 
     hibernate.commitTransaction(); 
    }    
} 

这实际上呈现我想看到的所有按钮,并将它们正确地添加到选择tedSeasonsList在我的支持bean中,当我点击它们时,当我再次点击时将它从它移除。

但是,在UI上,每个按钮似乎都会在单击一个按钮时切换。例如,当我点击2009- 2010年,这是我所看到的:

All Selected

回答

2
<ice:commandButton binding="#{season}"/> 

绑定属性必须绑定到UIComponent类型的bean属性。它用于你希望框架给你一个支持bean中的组件的引用或者从支持bean提供一个实例)。有关更多详细信息,请参见JSF 1.2 spec的第3.1.5节。


<ice:commandButton id="#{season.id}" 
    partialSubmit="true" 
    style="background-color: #FFFFFF" 
    value="#{season.value}" 
    actionListener="#{Phase1EventBean.updateSeasons}"/> 

id属性不能是动态的 - JSF将确保使用clientIdread this for more detail)在客户端上其独特的照顾。


编辑:

然而,在UI上,每一个按钮出现,当我点击只是一个按钮进行切换。

我猜ice:panelSeries并不像每个重复控件所做的那样存储每一行​​的组件状态(例如dataTable)。请记住,即使每个“行”编码/解码一次,也只有一个按钮实例。

我从来没有使用ICEfaces的,但我建议结合豆类与此类似:

public class Bean { 

    private final List<SelectionBean> seasonsList = Arrays.asList(
     new SelectionBean("Spring"), new SelectionBean("Summer"), 
     new SelectionBean("Autumn"), new SelectionBean("Winter")); 

    public List<SelectionBean> getSeasonsList() { return seasonsList; } 

    public static class SelectionBean { 

    private String season; 
    private boolean selected; 

    public SelectionBean() {} 
    public SelectionBean(String season) { this.season = season; } 

    public String getSeason() { return season; } 
    public void setSeason(String season) { this.season = season; } 

    public String toggle() { 
     System.out.println("toggle " + season); 
     selected = !selected; 
     return null; 
    } 

    public String getStyle() { 
     return selected ? "background-color: yellow" : "background-color: blue"; 
    } 
    } 
} 

我回吐逻辑降到最低限度,但希望你如何修改逻辑把休眠支持回那么你的组件将成为这样的事情:

<ice:panelSeries value="#{bean.seasonsList}" var="item"> 
    <ice:commandButton partialSubmit="true" 
    style="#{item.style}" 
    value="#{item.season}" 
    action="#{item.toggle}"/>           
</ice:panelSeries> 

所以,在列表中的每个项目,所有的结合可以追溯到一件状态(一SelectionBean实例)和你不要尝试在组件i上存储任何非声明状态自行宣布。

我试着在actionListener以上使用action当我可以 - 它使JSF的东西保持在POJO之外。

+0

HtmlCommandButton扩展了UIComponent,虽然,或者所以我认为... – karlgrz 2009-08-04 21:42:04