Как использовать асинхронную команду в пользовательском интерфейсе, построенном с использованием LWUIT ResourceEditor - PullRequest
2 голосов
/ 05 июля 2011

Я использую LWUIT ResrouceEditor (последняя редакция кода SVN 1513) для генерации конечного автомата пользовательского интерфейса.

Я хочу показать экран ожидания, когда пользователь выполняет длительную команду с помощью кнопки в текущей форме. Я считаю, что могу использовать асинхронную опцию при связывании команды на кнопке. Я настроил форму, в которой у меня есть кнопка, которая должна вызвать асинхронную команду. При выборе команды для этой кнопки я установил действие, чтобы показать форму экрана ожидания, и пометил команду как асинхронную. Однако, когда я использую асинхронную опцию, код показывает экран ожидания, но после этого он генерирует исключение NullPointerException.

Насколько я понимаю, после того, как вы пометите команду как асинхронную, она будет вызывать следующие методы из другого потока, где вы можете обрабатывать ее обработку.

protected void asyncCommandProcess(Command cmd, ActionEvent sourceEvent);

protected void postAsyncCommand(Command cmd, ActionEvent sourceEvent);

Однако этот метод не вызывается, и он генерирует исключение NullPointerException.

Когда я посмотрел на код LWUIT в UIBuilder.java (lineno. 2278), я увидел, что он создает новый поток для асинхронной команды следующим образом:

new Thread(new FormListener(currentAction, currentActionEvent, f)).start();

Но при запуске его через отладчик я вижу, что currentAction и currentActionEvent всегда равны нулю. И, следовательно, когда поток FormListener начинает работать, он никогда не вызывает вышеупомянутые два метода обработки асинхронных команд. Пожалуйста, посмотрите листинг метода run () в UIBuilder.java (строка № 2178)

public void run() {
  if(currentAction != null) {
     if(Display.getInstance().isEdt()) {
        postAsyncCommand(currentAction, currentActionEvent);
     } else {
         asyncCommandProcess(currentAction, currentActionEvent);
     // wait for the destination form to appear before moving back into the LWUIT thread
         waitForForm(destForm);
     }
  } else {
     if(Display.getInstance().isEdt()) {
        if(Display.getInstance().getCurrent() != null) {
            exitForm(Display.getInstance().getCurrent());
        }
        Form f = (Form)createContainer(fetchResourceFile(), nextForm);
        beforeShow(f);
        f.show();
        postShow(f);
     } else {
        if(processBackground(destForm)) {
           waitForForm(destForm);
        }
     }
  }
}

В приведенном выше методе, поскольку currentAction имеет значение null, оно всегда входит в оператор else, а поскольку nextForm также имеет значение null, оно вызывает исключение NullPointerException.

При дальнейшем просмотре кода UIBuilder.java я заметил, что вызывает исключение NullPointer. Кажется, когда создается FormListner, ему передаются currentAction и currentActionEvent, однако в то время они равны нулю. Вместо этого код должен быть изменен следующим образом (начиная со строки 2264):

if(action.startsWith("@")) {
     action = action.substring(1);
     Form currentForm = Display.getInstance().getCurrent();
     if(currentForm != null) {
          exitForm(currentForm);
     }
     Form f = (Form)createContainer(fetchResourceFile(), action);
     beforeShow(f);
     /* Replace following with next lines for fixing asynchronous command
        if(Display.getInstance().getCurrent().getBackCommand() == cmd) {
             f.showBack();
        } else {
             f.show();
        }
        postShow(f);
        new Thread(new FormListener(currentAction, currentActionEvent, f)).start();
      */ 
      new Thread(new FormListener(cmd, evt, f)).start();
      return;
}

Может ли команда разработчиков lwuit взглянуть на приведенный выше код, просмотреть и исправить его. После внесения вышеуказанных изменений были вызваны методы асинхронной обработки команд.

Спасибо.

1 Ответ

0 голосов
/ 06 июля 2011

Спасибо за информацию, вероятно, лучше использовать средство отслеживания проблем для подобных вещей (на http://lwuit.java.net). Я внесу аналогичное изменение, хотя я не понимаю, почему вы закомментировали часть навигации по форме.

Чтобы решить ваш вариант использования экрана ожидания, у нас есть намного более простое решение: Следующая форма. Просто покажите экран ожидания и определите в нем свойство «Следующая форма». Это вызовет фоновый поток, который будет вызываться (обратный вызов processBackground) и только после завершения фонового потока будет показана следующая форма.

...