【问题标题】:jsf 2 update UI from bean after delay + blinking延迟+闪烁后jsf 2从bean更新UI
【发布时间】:2012-03-18 21:42:27
【问题描述】:

我不确定我尝试完成的工作是否可行,因此我将不胜感激。 我基本上想做的是创建一个在线跳棋游戏,用户可以在其中相互竞争或与计算机竞争。游戏的逻辑在 EJB 内部,目前运行良好。到目前为止,我已经完成了玩家-电脑游戏,并且运行良好 - 玩家选择移动的起点和目的地(而逻辑决定它们是否有效),然后计算机让它移动,然后更新棋盘. 但是,目前我要解决两个问题: 1)我希望计算机的移动发生在播放器完成后大约一秒钟。它可以工作 - 但是董事会没有更新(我稍后会解释原因) 2)电脑让它移动后,我想让它影响的方块闪烁几次。

在我的板上,每个方块都是一个命令按钮,如下所示:

<h:commandButton id="B1" image="#{CodeBean.imgSrc}"  actionListener="#{CodeBean.clickImg()}" action="#{CodeBean.update}"  onmouseover="this.src='#{CodeBean.overImgSrc}'" onmouseout="this.src='/CheckersClientSide#{CodeBean.imgSrc}'">
    <f:ajax render="@form"   />
</h:commandButton>

在我的 bean 中,'imgSrc' getter 看起来像这样:

public String getImgSrc()
{
    FacesContext fc = FacesContext.getCurrentInstance();
    UIComponent c = UIComponent.getCurrentComponent(fc);
    String cID = c.getId();
    String output = "/resources/EMPTY_BOX.jpg";
    String currOption = gameBoard.get(cID);
    if (currOption != null)
    {
        output = "/resources/" + currOption + ".jpg";
    }
    return output;
  }

在 bean 内的“clickImg”函数中,我检查是否已经选择了任何正方形,否则我知道该正方形被选择为移动的原点;否则,我调用 EJB 的 move 函数,它返回一个更新的板图,然后我调用 'getImgSrc' 函数,它更新板,然后我调用 EJB 的计算机 move 函数,它也返回更新的板图,然后我再次调用“getImgSrc”,它会更新电路板本身。
但是,如果我尝试使用计时器调用计算机的移动功能,就像这样 -

Timer timer = new Timer();
timer.schedule(new TimerTask()
{
   @Override
   public void run()
   {
      getMachineMove();
   }
} , 1000);

“getMachineMove”函数在一秒钟后被调用,该函数调用“getImgSrc”,但板子没有更新。它没有得到更新,因为 'FacesContext.getCurrentInstance()' 返回 null。 我希望我已经足够清楚了——如果我是的话,我会很感激任何帮助(以及如何让某些命令按钮从 bean 中闪烁的想法)。

干杯, 埃雷兹

【问题讨论】:

    标签: java jsf-2 facelets


    【解决方案1】:

    有几个严重的概念错误。

    首先,您只能向 HTTP 请求发送 HTTP 响应。没有 HTTP 请求时,您无法发送 HTTP 响应。 HTTP 请求仅由客户端发起。 FacesContext 存储在 HTTP 请求线程中。这就解释了为什么你的计时器线程中没有FacesContext

    您可以使用 websockets 引入 HTTP 推送,但这并不是微不足道的。 PrimeFaces 组件库为此提供了a &lt;p:push&gt; component。但更简单的方法是直接计算下一步并让 JSF 打印一行 JavaScript 代码,该代码使用 setTimeout(callback, millis) 执行更新作业客户端。

    其次,使用Timer/TimerTask 在本应终身运行的 Java EE Web 应用程序中是一个非常糟糕的主意。永远不要考虑以后再做一次。您应该使用java.util.concurrent API 或服务器提供的任务调度程序。这不是您问题的答案(您已经有了它;使用 HTTP 推送或 JS),但要了解更多信息,请查看Spawning threads in a JSF managed bean for scheduled tasks using a timer

    【讨论】:

    • 一如既往-感谢您的详细回答。我已经很容易地管理了“ScheduledExecutorService”,但是当我尝试实现 PrimeFace 的推送时它不起作用(尽管他们的例子看起来很简单)。我想答案就在这里 - blog.primefaces.org/?p=1440,因为我使用的是 GlassFish 3.0。因此我会尝试在 JS 中实现超时
    猜你喜欢
    • 2014-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多