jsf 2 обновляет интерфейс пользователя от bean-компонента после задержки + мигает - PullRequest
0 голосов
/ 19 марта 2012

Я не уверен, что то, что я пытаюсь сделать, вообще возможно, поэтому я был бы признателен за любую помощь. В основном я пытаюсь создать онлайн-игру в шашки, где пользователи могут соревноваться друг с другом или с компьютером. логика игры находится внутри 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>

в моем бине получатель '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;
  }

в функции clickImg внутри компонента, я проверяю, был ли уже выбран какой-либо квадрат, иначе я знаю, что квадрат был выбран в качестве источника движения; в противном случае я вызываю функцию перемещения EJB, которая возвращает обновленную карту доски, после чего я вызываю функцию 'getImgSrc', которая обновляет доску, а затем я вызываю функцию перемещения компьютера EJB, которая также возвращает обновленную карту доски, а затем я снова вызываю getImgSrc, который обновляет саму плату.
однако, если я попытаюсь вызвать функцию перемещения компьютера с помощью таймера, например:

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

функция 'getMachineMove' вызывается через секунду, и эта функция вызывает 'getImgSrc', но плата не обновляется. он не обновляется, потому что FacesContext.getCurrentInstance () возвращает ноль. Надеюсь, я был достаточно ясен - и в таком случае я был бы признателен за любую помощь (а также за идеи, как заставить определенные кнопки команд мигать от компонента).

ура, Эрез

1 Ответ

1 голос
/ 19 марта 2012

Есть несколько серьезных концептуальных ошибок.

Во-первых, вы можете отправлять только HTTP-ответ на HTTP-запрос. Вы не можете отправить ответ HTTP, когда нет запроса HTTP. HTTP-запрос инициируется только клиентом. FacesContext хранится в потоке HTTP-запросов. Это объясняет, почему в вашей ветке таймера нет FacesContext.

Вы можете ввести HTTP push с веб-сокетами, но это не совсем тривиально. В библиотеке компонентов PrimeFaces для этого есть a <p:push> компонент . Но проще было бы просто рассчитать следующий шаг напрямую и позволить JSF напечатать строку кода JavaScript, которая выполняет клиентскую работу по обновлению с setTimeout(callback, millis).

Во-вторых, использование Timer / TimerTask - чрезвычайно плохая идея в предположительно пожизненном веб-приложении Java EE. Никогда не думай делать это еще раз позже. Вы должны использовать java.util.concurrent API или серверный планировщик задач. Это не ответ на ваш вопрос (он у вас уже есть; используйте HTTP push или JS), но для получения дополнительной информации проверьте Создание потоков в управляемом компоненте JSF для запланированных задач с использованием таймера

...