Как я могу получить доступ к всплывающей панели / подменю строки меню GWT?

Я пытаюсь добавить слушателей мыши в подменю / каскадные меню GWT MenuBar. К сожалению, я не могу напрямую получить доступ к подменю popuppanel - метод для этого (getPopup ()) является частным. И вы не можете получить к нему доступ через отражение из-за способа компиляции GWT.

Добавление слушателя мыши к строке главного меню (для определения, когда мышь находится внутри границ строки меню) было приятным и простым. Но я не могу придумать никакого способа добавить слушателя мыши, чтобы определять, когда мышь находится внутри одного из каскадных подменю.

Я делаю вот что:

com.google.gwt.user.client.ui.MenuBar myMainBar = new MenuBar();
myMainBar.addDomHandler(menuHoverOutHandler, MouseOutEvent.getType());
myMainBar.addDomHandler(menuHoverOverHandler, MouseOverEvent.getType());

Это отлично работает с реальной панелью меню GWT. Когда я нахожу указатель мыши, срабатывает событие mouseOverEvent. Когда я нахожу указатель мыши, срабатывает MouseOutEvent.

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

Когда я говорю подменю, я имею в виду что-то вроде тех, что мы видели здесь:

http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/MenuBar.html

Итак, пока я нахожусь на «главной» панели со списком Style, Fruit и Term, события мыши распознают это.

Но если я выпаду в подменю с надписью «Полужирный», «Курсив», «Еще», события мыши будут считать, что я полностью покинул строку меню. Мне нужен способ определить, находится ли мышь внутри одного из этих подменю. (Или что подменю этой панели главного меню где-то открыто)

Вы не можете просто сделать

myMainBar.getPopup()

и добавьте слушателей в полученный PopupPanel, поскольку getPopup является закрытым. Ищу другой способ попасть в MenuBar.popup

Кажется, нет никакого способа узнать, открыто ли одно из подменю, что меня немного озадачивает. Кажется, разочаровывает отсутствие возможности взаимодействовать с этими подменю, и мне интересно, не упускаю ли я чего-то.


person user2197116    schedule 19.06.2014    source источник
comment
как я могу получить доступ к вашему коду? :) Не могли бы вы поделиться фрагментом кода, который рассказывает о том, что вы делаете?   -  person Braj    schedule 20.06.2014
comment
Я добавил код, показывающий, что я делаю, и некоторые дополнительные пояснения. Спасибо, что заглянули!   -  person user2197116    schedule 21.06.2014
comment
Удалось ли вам это решить? Я сейчас столкнулся именно с этой проблемой ...   -  person Sleeper9    schedule 05.09.2014
comment
Почему бы вам просто не добавить DomHandlers в свои подменю? Если вы посмотрите на пример раздела MenuBar javadocs, вы можете увидеть, что MenuBar создается каскадом MenuBars. Что мешает вам добавить DomHandlers к этим дочерним MenuBars?   -  person mucaho    schedule 15.10.2014
comment
Давным-давно у меня была аналогичная проблема, и, если я помню, мне нужно переопределить событие onBrowser и отменить события на виджетах, которые не должны запускать событие. Возможно, я смогу привести пример на этих выходных.   -  person Pintouch    schedule 17.10.2014
comment
Разве вы не можете просто игнорировать (отменить) MouseOutEvent в своем обработчике, если мышь в данный момент находится в подменю?   -  person Steve K    schedule 21.10.2014
comment
@SteveK: Я думаю, проблема в том, что OP не знает, как это игнорировать   -  person Engineer2021    schedule 21.10.2014


Ответы (2)


Если вы добавите MouseOverHandler и MouseOutHandler в каждое из ваших подменю, а не в строку главного меню, оно должно делать то, что вы хотите.

Например:

MenuBar subMenu = new MenuBar(true);
subMenu.addItem("Item1", new Command() {
    @Override
    public void execute() {
        Window.alert("Item1 clicked");
    }
});

subMenu.addDomHandler(new MouseOverHandler() {
    @Override
    public void onMouseOver(MouseOverEvent arg0) {
        Window.alert("SubMenu over!");
    }
}, MouseOverEvent.getType());

subMenu.addDomHandler(new MouseOutHandler() {
    @Override
    public void onMouseOut(MouseOutEvent arg0) {
        Window.alert("SubMenu out!");
    }
}, MouseOutEvent.getType());

MenuBar mainMenu = new MenuBar();
mainMenu.addItem("SubMenu", subMenu);

RootPanel.get().add(mainMenu);
person megadan    schedule 16.10.2014
comment
OP может использовать это для установки флага и игнорирования MouseOutEvent в главной строке меню, если ваше подменю «выскочило». - person Engineer2021; 21.10.2014

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

Для этого вы могли бы добавить код, который слушает как наведение, так и наведение курсора, и компилировать доступную информацию, чтобы понять, что происходит.

Вы можете быть уверены, что выполните код после всех прошедших событий, используя планировщик

 Scheduler.get().scheduleDeferred(new Command() {
    public void execute () {
      //check all what happened in a static shared variable, there was a mouse out, was there a mouse over after it? if yes then stay calm; If there wasn't, then trigger a MouseOutOfAllMenus event
    }
  });

этот фрагмент кода следует поместить в onMouseOut(), а другой код, который только обновляет состояние экземпляра статического класса, следует поместить в onMouseOver(). Вы можете быть уверены, что код в Scheduler.execute() будет выполняться после выполнения onMouseOver() благодаря механизму отложенного планирования. Итак, когда вы придете проверять состояние, это будет после того, как мышь вошла в другое меню (или не открыла); поэтому вы можете узнать, действительно ли пользователь покинул пункты меню или вошел в подменю.

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

Надеюсь, вы поняли все, что я пытался объяснить, если нет, не стесняйтесь комментировать, я постараюсь ответить вам

Наилучшие пожелания,

p.s: когда я говорю о статическом состоянии экземпляра, это просто для простоты понимания. Естественно, рекомендуется избегать статического использования, чтобы иметь возможность иметь более одного меню в одном приложении. Под статикой я подразумеваю: экземпляр, доступный для всех компонентов.

person Zied Hamdi    schedule 19.10.2014