[英]jsf 2 update UI from bean after delay + blinking
我不確定我嘗試實現的目標是否完全可能,因此我將不勝感激。 我基本上想做的是創建一個在線跳棋游戲,用戶可以在其中相互競爭,也可以與計算機競爭。 游戲的邏輯是在EJB內部,到目前為止,它仍然可以正常工作。 到目前為止,我已經完成了玩家計算機游戲,並且工作正常-玩家選擇了移動的起點和終點(邏輯確定它們是否有效),然后計算機使其移動,然后更新了棋盤。 但是,目前我要解決2個問題: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”獲取器如下所示:
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的計算機移動的函數,該函數也將返回更新的板子圖,然后我再次調用“ getImgSrc”,它會更新板子本身。
但是,如果我嘗試使用計時器調用計算機的移動功能,例如這樣-
Timer timer = new Timer();
timer.schedule(new TimerTask()
{
@Override
public void run()
{
getMachineMove();
}
} , 1000);
一秒鍾后會調用“ getMachineMove”函數,而該函數會調用“ getImgSrc”,但不會更新開發板。 它不會更新,因為'FacesContext.getCurrentInstance()'返回null。 我希望我已經足夠清楚了,以防萬一,如果有的話,我將感謝您提供的任何幫助(以及如何使某些命令按鈕從Bean閃爍的想法)。
歡呼聲,eRez
有幾個嚴重的概念錯誤。
首先,您只能發送對HTTP請求的HTTP響應。 沒有HTTP請求時,您無法發送HTTP響應。 HTTP請求僅由客戶端發起。 FacesContext
存儲在HTTP請求線程中。 這就解釋了為什么計時器線程中沒有FacesContext
。
您可以在websockets中引入HTTP推送,但這並不簡單。 PrimeFaces組件庫為此提供了一個<p:push>
組件 。 但是更簡單的方法是直接計算下一步,並讓JSF打印一行JavaScript代碼,該代碼使用setTimeout(callback, millis)
在客戶端進行更新作業。
其次,在據稱終身運行的Java EE Web應用程序中,使用Timer
/ TimerTask
是一個極壞的主意。 永遠不要考慮以后再做一次。 您應該使用java.util.concurrent
API或服務器提供的任務計划程序。 這不是您的問題的答案(您已經有了;使用HTTP push或JS),但是要了解更多信息,請使用計時器檢查JSF托管Bean中的Spawning線程是否有計划的任務
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.