Я пробовал много разных вещей, которые, я думаю, работали бы так, как ожидалось. Тем не менее, они вызывают у меня некоторое разочарование. Вот совок:
Я использую компоненты ICEFaces 1.8 в веб-приложении Java EE. Моя цель состоит в том, чтобы отобразить на странице кучу льда: commandButtons на основе запроса к моей базе данных. Я хочу, чтобы эти кнопки могли переключать выборки, которые я позже буду использовать для параметров, для другого запроса к базе данных (в основном, это внешний вид запроса для набора пользователей). Я бы хотел, чтобы результат выглядел так:
Когда я нажимаю на кнопку, я бы хотел, чтобы на моей странице было следующее обновление:
Когда я создавал кнопки на своей странице статически, вот так:
<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" />
это прекрасно работает, и каждая кнопка работает индивидуально, как я и ожидал. Мой вспомогательный компонент обновлен, параметры правильно добавлены в методе updateSeasons (), а мои выходные данные в конце дают правильные записи.
Однако я знаю, что это не то, чего я хочу. Я не хочу обновлять их каждый раз, когда в систему вводится другой сезон. Ведение кошмара, верно?
Итак, я хочу динамически генерировать эти компоненты ice: commandButton на основе моей таблицы базы данных, полной объектов Season. Вот класс Season, который я использую:
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;
}
}
Очень просто. Два свойства, которые я гарантированно буду уникальными в базе данных.
Вот бэк, который я использую:
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>
И я получаю этот вывод:
Итак, будучи разочарованным и предприимчивым, я попытался сделать эту разметку для достижения своей цели:
<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>
Который дал следующую трассировку стека:
4 августа 2009 14:28:11 com.sun.faces.lifecycle.Phase doPhase
SEVERE: JSF1054: (идентификатор фазы: RENDER_RESPONSE 6, идентификатор представления: /phase1.jspx) Исключение, генерируемое во время выполнения фазы: javax.faces.event.PhaseEvent [source=com.sun.faces.lifecycle.LifecycleImpl@1a477b7]
4 августа 2009 14:28:11 вызов org.apache.catalina.core.StandardWrapperValve
SEVERE: Servlet.service () для сервлета Persistent Faces Servlet выбросил исключение
java.lang.IllegalArgumentException: # {season.id}
в 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)
на com.icesoft.faces.webapp.parser.Parser.executeJspLifecycle (Parser.java:204)
на 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)
на 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)
на 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)
на 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.parse (Parser.java:162)
на com.icesoft.faces.application.D2DViewHandler.renderResponse (D2DViewHandler.java:464)
в com.icesoft.faces.application.D2DViewHandler.renderView (D2DViewHandler.java:153)
на com.sun.faces.lifecycle.RenderResponsePhase.execute (RenderResponsePhase.java:110)
на com.sun.faces.lifecycle.Phase.doPhase (Phase.java:100)
на com.sun.faces.lifecycle.LifecycleImpl.render (LifecycleImpl.java:139)
в com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply (JsfLifecycleExecutor.java:17)
на com.icesoft.faces.context.View $ 2 $ 1.respond (View.java:47)
на com.icesoft.faces.webapp.http.servlet.ServletRequestResponse.respondWith (ServletRequestResponse.java:197)
в com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet $ ThreadBlockingRequestResponse.respondWith (ThreadBlockingAdaptingServlet.java:36)
на com.icesoft.faces.context.View $ 2.serve (View.java:72)
на com.icesoft.faces.context.View.servePage (View.java:133)
на com.icesoft.faces.webapp.http.core.SingleViewServer.service (SingleViewServer.java:52)
на com.icesoft.faces.webapp.http.common.ServerProxy.service (ServerProxy.java:11)
на com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet $ 4.service (MainSessionBoundServlet.java:114)
на com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service (PathDispatcherServer.java:24)
на com.icesoft.faces.webapp.http.servlet.MainSessionBoundServlet.service (MainSessionBoundServlet.java:160)
на com.icesoft.faces.webapp.http.servlet.SessionDispatcher $ 1.service (SessionDispatcher.java:42)
на com.icesoft.faces.webapp.http.servlet.ThreadBlockingAdaptingServlet.service (ThreadBlockingAdaptingServlet.java:19)
на com.icesoft.faces.webapp.http.servlet.EnvironmentAdaptingServlet.service (EnvironmentAdaptingServlet.java:63)
на com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service (SessionDispatcher.java:62)
на com.icesoft.faces.webapp.http.servlet.PathDispatcher.service (PathDispatcher.java:23)
на com.icesoft.faces.webapp.http.servlet.MainServlet.service (MainServlet.java:153)
на 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)
в org.apache.catalina.core.StandardContextValve.invoke (StandardContextValve.java:191)
в 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)
в org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process (Http11Protocol.java:583)
в org.apache.tomcat.util.net.JIoEndpoint $ Worker.run (JIoEndpoint.java:447)
at java.lang.Thread.run (Thread.java:619)
Я пытаюсь сделать что-то, чего не должен делать?
Есть ли лучший способ достичь этой цели?
Если потребуется дополнительная информация, я с радостью ее предоставлю.
Заранее спасибо, друзья.
UPDATE
Итак, я попытался изменить коллекцию seasonsList с List на List и отобразить какую-то другую разметку, например:
<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();
}
}
Это фактически отображает все кнопки, которые я хотел бы видеть, и правильно добавляет их в selectedSeasonsList в моем компоненте поддержки, когда я нажимаю на них, и удаляет их из него при повторном нажатии.
Однако в пользовательском интерфейсе каждая кнопка переключается, когда я нажимаю только одну кнопку. Например, когда я нажимаю на 2009-2010, это то, что я вижу: