не удается установить фокус на текстовое поле в приложении GWT

#gwt #textbox

#gwt #текстовое поле

Вопрос:

Это не должно причинять мне столько боли, но это так. Это очень странная проблема. В приложении GWT у меня есть два java-файла, login.java и application.java . В login.java Я создаю страницу входа пользователя, где, если имя пользователя и пароль подтверждены, пользователь входит в приложение и application.java берет отсюда.

Теперь в приложении. java onModuleLoad() вот как я начинаю со страницы входа в систему.

 public void onModuleLoad() {
  Login login = new Login();
  login.textBoxUsername.setFocus(true);
  RootLayoutPanel.get().add(login);}
  

Это отлично работает, за исключением небольшой проблемы, связанной с невозможностью установить фокус на текстовом поле имени пользователя при загрузке страницы. Я перепробовал все, что только смог придумать. Но фокус просто не устанавливается на текстовое поле. Если кто-нибудь может предложить решение, пожалуйста, сделайте это. Мы очень ценим вашу помощь.

Решение: (На случай, если это поможет кому-либо, столкнувшемуся с такой же проблемой)

 final Login login = new Login();
  Scheduler.get().scheduleDeferred(new ScheduledCommand() {
        public void execute () {
            login.textBoxUsername.setFocus(true);
        }
   });

  RootLayoutPanel.get().add(login);
  

Комментарии:

1. Возможно, вам потребуется вызвать setFocus() после добавления виджета входа в RootLayoutPanel — вы пробовали это?

2. да, когда я вызываю SetFocus() после RootLayoutPanel.get().add(login); экран входа в систему не загружается.

3. Получаете ли вы какую-либо ошибку скрипта, если вызываете SetFocus() после RootLayoutPanel.get().add(login); ? Я думаю, что браузеру требуется некоторое время для загрузки вашего виджета входа в систему. Не могли бы вы, пожалуйста, попробовать вызов SetFocus внутри блока таймера gwt с интервалом в 5 секунд? Тогда мы сможем выяснить, в чем именно проблема.

4. @Din Если требуется некоторое время для создания виджета входа в систему или добавления его в RootLayoutPanel, следующий вызов не произойдет, пока это не будет завершено. @sherry Вы работаете в режиме разработки, чтобы видеть любые ошибки GWT?

5. @Din: Вы правы, браузеру требуется время для загрузки виджета входа в систему, хотя эта задержка не видна пользователю. Я не смог выяснить, когда завершалась загрузка виджета входа в систему. Следуя этой концепции, я использовал предложение @ Peter ниже. Использование DeferredCommand работает! Он ожидает, пока загрузится виджет входа в систему, затем вызывает SetFocus (). Хотя DeferredCommand устарел, и мне придется найти то, что можно использовать вместо него. Но, по крайней мере, теперь я куда-то иду.. Спасибо за ваш ответ!

Ответ №1:

Попробуйте использовать Scheduler.scheduleDeferred():

 public void onModuleLoad() {
    Login login = new Login();
    Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand () {
        public void execute () {
            login.textBoxUsername.setFocus(true);
        }
    });
    RootLayoutPanel.get().add(login);       
}
  

Обновление: ответ обновлен для использования Scheduler.get().scheduleDeferred() вместо DeferredCommand , который устарел.

Комментарии:

1. Спасибо, Питер! Ваше решение сработало. Хотя это устарело, поэтому мне нужно будет найти класс, который будет делать это в текущей версии GWT. По крайней мере, вы предложили, с чего начать, спасибо.

2. Действительно, вы должны использовать Scheduler.scheduleDeferred()

3. Разве это не должно быть Scheduler.get().scheduleDeferred() ?

4. Только один вопрос, все заключено в onModuleLoaded функцию, верно? Аналогично jQuery document.ready() . Так не решит ли это проблему с установкой фокуса только после того, как виджет был загружен в первую очередь? Почему нам нужно позаботиться об этом отдельно с помощью этого взлома?

5. @Cupidvogel — Нет, onModuleLoad() может быть вызван до того, как DOM будет готов и body.onload() вызывается: developers.google.com/web-toolkit/doc/latest / …

Ответ №2:

Зачем использовать DefferedCommand , я думаю, что лучше использовать someWidget.getElement().focus() собственный Javascript. Я использую его везде, я не видел никакой проблемы.

Комментарии:

1. Я тоже использовал это во многих местах. Ну, в данном случае это не сработало. Как было объяснено выше, невозможно узнать, когда завершится загрузка виджета входа в систему для использования someWidget.getElement().focus() . поэтому нам нужно использовать DeferedCommand or scheduleDeferred для достижения этой цели. deferredCommand выполняется после возврата цикла событий браузера.

Ответ №3:

Если ваш виджет расширяет Composite, вы можете:

 @Override
protected void onAttach() {
    super.onAttach();
    textBoxUsername.setFocus(true);
}
  

Ответ №4:

Для GWT было бы так просто сохранить ‘wantsFocus’ во внутреннем состоянии и вызвать focus после прикрепления виджета. Однако мы все еще ждем этой функции спустя много лет…

Тем не менее, даже после вызова обработчика прикрепления SetFocus не всегда работает.

Итак, тем временем наша библиотека GwtUtil использовала следующий код. Это комбинация нескольких других решений, и она была заключена в служебную функцию:

 static public void setFocus(final FocusWidget focusWidget) {
    if (focusWidget.isAttached()) {
        Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
            @Override
            public void execute() {
                focusWidget.setFocus(true);
            }
        });
    } else {
        focusWidget.addAttachHandler(new AttachEvent.Handler() {
            @Override
            public void onAttachOrDetach(AttachEvent event) {
                if (event.isAttached()) {
                    Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
                        @Override
                        public void execute() {
                            focusWidget.setFocus(true);
                        }
                    });
                }
            }
        });
    }
}
  

И назовите это так:

 setFocus(myTextBox);
  

Имеет смысл использовать служебную функцию; Если и когда GWT наконец заставит SetFocus работать, вам не придется изменять исходный код в нескольких местах.