简体   繁体   English

延迟+闪烁后jsf 2从bean更新UI

[英]jsf 2 update UI from bean after delay + blinking

i'm not sure if what i try to accomplish is possible at all, so i'd appreciate any help. 我不确定我尝试实现的目标是否完全可能,因此我将不胜感激。 what i'm basically trying to do is create an online checkers game, where users can compete one another or the computer. 我基本上想做的是创建一个在线跳棋游戏,用户可以在其中相互竞争,也可以与计算机竞争。 the game's logic is inside EJB, and so far it works fine. 游戏的逻辑是在EJB内部,到目前为止,它仍然可以正常工作。 so far i've accomplished the player-computer game, and it works fine - the player picks the move's origin and destination (while the logic decides if they're valid), and then the computer makes it move, afterward the board is updated. 到目前为止,我已经完成了玩家计算机游戏,并且工作正常-玩家选择了移动的起点和终点(逻辑确定它们是否有效),然后计算机使其移动,然后更新了棋盘。 however, currently there are 2 issues i want to solve: 1) i want the computer's move to take place about a second after the player is done. 但是,目前我要解决2个问题:1)我希望在播放器完成后大约一秒钟进行计算机移动。 it works - however the board isn't updated (i'll explain later why) 2) after the computer makes it move, i want the squares it affected to blink few times. 它可以正常工作-但是该板未更新(我将在后面解释原因)2)计算机移动后,我希望受影响的方块闪烁几次。

on my board, each square is a command button that looks like this: 在我的板上,每个方框都是一个命令按钮,如下所示:

<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>

in my bean, the 'imgSrc' getter looks like this: 在我的bean中,“ imgSrc”获取器如下所示:

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;
  }

in the 'clickImg' function inside the bean, i check if any square was already picked, for otherwise i know the square was picked as the move's origin; 在bean内的“ clickImg”函数中,我检查是否已经选择了任何正方形,否则我知道该正方形被选为移动的原点; otherwise, i call the EJB's move function, which returns an updated board map, afterwards i call the 'getImgSrc' function, which updates the board, and then i call the EJB's computer move's function, which also return the updated board's map, and then i call the 'getImgSrc' again, which update the board itself. 否则,我调用EJB的move函数,该函数将返回更新的电路板图,此后,我调用'getImgSrc'函数,该函数将更新板子,然后调用EJB的计算机移动的函数,该函数也将返回更新的板子图,然后我再次调用“ getImgSrc”,它会更新板子本身。
however, if i try to call the computer's move function using a timer, like this - 但是,如果我尝试使用计时器调用计算机的移动功能,例如这样-

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

the 'getMachineMove' function is call after a second, and that function call the 'getImgSrc', but the board doesn't get updated. 一秒钟后会调用“ getMachineMove”函数,而该函数会调用“ getImgSrc”,但不会更新开发板。 it doesn't get updated because 'FacesContext.getCurrentInstance()' returns null. 它不会更新,因为'FacesContext.getCurrentInstance()'返回null。 i hope i was clear enough - and in case i was, i'd appreciate any kind of help (and also ideas how can i make certain command-buttons blink from the bean). 我希望我已经足够清楚了,以防万一,如果有的话,我将感谢您提供的任何帮助(以及如何使某些命令按钮从Bean闪烁的想法)。

cheers, eRez 欢呼声,eRez

There are several serious conceptual mistakes. 有几个严重的概念错误。

First, you can only send a HTTP response to a HTTP request. 首先,您只能发送对HTTP请求的HTTP响应。 You cannot send a HTTP response when there's no HTTP request. 没有HTTP请求时,您无法发送HTTP响应。 A HTTP request is only initiated by the client. HTTP请求仅由客户端发起。 The FacesContext is stored in the HTTP request thread. FacesContext存储在HTTP请求线程中。 That explains why there's no FacesContext in your timer thread. 这就解释了为什么计时器线程中没有FacesContext

You could introduce HTTP push with websockets, but this is not exactly trivial. 您可以在websockets中引入HTTP推送,但这并不简单。 The PrimeFaces component library has a <p:push> component for that. PrimeFaces组件库为此提供了一个<p:push>组件 But easier would be to just calculate the next move directly and let JSF print a line of JavaScript code which does the update job client side with setTimeout(callback, millis) . 但是更简单的方法是直接计算下一步,并让JSF打印一行JavaScript代码,该代码使用setTimeout(callback, millis)在客户端进行更新作业。

Second, using Timer / TimerTask is an extremely bad idea in a supposedly life-long running Java EE web application. 其次,在据称终身运行的Java EE Web应用程序中,使用Timer / TimerTask是一个极坏的主意。 Never ever think about doing it once again later. 永远不要考虑以后再做一次。 You should be using the java.util.concurrent API or the server-provided task scheduler. 您应该使用java.util.concurrent API或服务器提供的任务计划程序。 This is not the answer to your quesiton (you already have it; use HTTP push or JS), but to learn more check Spawning threads in a JSF managed bean for scheduled tasks using a timer 这不是您的问题的答案(您已经有了;使用HTTP push或JS),但是要了解更多信息,请使用计时器检查JSF托管Bean中的Spawning线程是否有计划的任务

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM