Эмм ...
Это интересный вопрос ...
Глядя на MenuBar исходный код ... особенно метод openPopup
private void openPopup(final MenuItem item) {
// Only the last popup to be opened should preview all event
if (parentMenu != null && parentMenu.popup != null) {
parentMenu.popup.setPreviewingAllNativeEvents(false);
}
// Create a new popup for this item, and position it next to
// the item (below if this is a horizontal menu bar, to the
// right if it's a vertical bar).
popup = new DecoratedPopupPanel(true, false, "menuPopup") {
{
setWidget(item.getSubMenu());
setPreviewingAllNativeEvents(true);
item.getSubMenu().onShow();
}
@Override
protected void onPreviewNativeEvent(NativePreviewEvent event) {
// Hook the popup panel's event preview. We use this to keep it from
// auto-hiding when the parent menu is clicked.
if (!event.isCanceled()) {
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
// If the event target is part of the parent menu, suppress the
// event altogether.
EventTarget target = event.getNativeEvent().getEventTarget();
Element parentMenuElement = item.getParentMenu().getElement();
if (parentMenuElement.isOrHasChild(Element.as(target))) {
event.cancel();
return;
}
super.onPreviewNativeEvent(event);
if (event.isCanceled()) {
selectItem(null);
}
return;
}
}
super.onPreviewNativeEvent(event);
}
};
popup.setAnimationType(AnimationType.ONE_WAY_CORNER);
popup.setAnimationEnabled(isAnimationEnabled);
popup.setStyleName(STYLENAME_DEFAULT + "Popup");
String primaryStyleName = getStylePrimaryName();
if (!STYLENAME_DEFAULT.equals(primaryStyleName)) {
popup.addStyleName(primaryStyleName + "Popup");
}
popup.addPopupListener(this);
shownChildMenu = item.getSubMenu();
item.getSubMenu().parentMenu = this;
// Show the popup, ensuring that the menubar's event preview remains on top
// of the popup's.
popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
public void setPosition(int offsetWidth, int offsetHeight) {
// depending on the bidi direction position a menu on the left or right
// of its base item
if (LocaleInfo.getCurrentLocale().isRTL()) {
if (vertical) {
popup.setPopupPosition(MenuBar.this.getAbsoluteLeft() - offsetWidth
+ 1, item.getAbsoluteTop());
} else {
popup.setPopupPosition(item.getAbsoluteLeft()
+ item.getOffsetWidth() - offsetWidth,
MenuBar.this.getAbsoluteTop() + MenuBar.this.getOffsetHeight()
- 1);
}
} else {
if (vertical) {
popup.setPopupPosition(MenuBar.this.getAbsoluteLeft()
+ MenuBar.this.getOffsetWidth() - 1, item.getAbsoluteTop());
} else {
popup.setPopupPosition(item.getAbsoluteLeft(),
MenuBar.this.getAbsoluteTop() + MenuBar.this.getOffsetHeight()
- 1);
}
}
}
});
}
Интересно указать фрагмент как
...
popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
public void setPosition(int offsetWidth, int offsetHeight) {
// depending on the bidi direction position a menu on the left or right
// of its base item
if (LocaleInfo.getCurrentLocale().isRTL()) {
if (vertical) {
popup.setPopupPosition(MenuBar.this.getAbsoluteLeft() - offsetWidth
+ 1, item.getAbsoluteTop());
} else {
popup.setPopupPosition(item.getAbsoluteLeft()
+ item.getOffsetWidth() - offsetWidth,
MenuBar.this.getAbsoluteTop() + MenuBar.this.getOffsetHeight()
- 1);
}
} else {
if (vertical) {
popup.setPopupPosition(MenuBar.this.getAbsoluteLeft()
+ MenuBar.this.getOffsetWidth() - 1, item.getAbsoluteTop());
} else {
popup.setPopupPosition(item.getAbsoluteLeft(),
MenuBar.this.getAbsoluteTop() + MenuBar.this.getOffsetHeight()
- 1);
}
}
}
});
...
... поэтому я могу предположить, что есть смысл поиграть с объектом MenuItem, особенно с его наследуемыми методами UIObject, такими какgetAbsoluteLeft () и getAbsoluteTop (), конечно ...
Я бы порекомендовал расширить MenuItem таким образом
//not tested
public class MyMenuItem extends MenuItem
{
private MenuBar aSubMenuBar;//ItemMenu's submenu
//...
@Override
public int getAbsoluteTop() {
// TODO Auto-generated method stub
return super.getAbsoluteTop()+movePopupTo();
}
private int movePopupTo()
{
int moveTo=0;
int bottom=RootPanel.getBodyElement().getAbsoluteBottom();
int rest=bottom -(super.getAbsoluteTop()+this.getaSubMenuBar().getOffsetHeight());
if(rest<0)
{
moveTo=rest;
}
return moveTo;
}
public MenuBar getaSubMenuBar() {
return aSubMenuBar;
}
public void setaSubMenuBar(MenuBar aSubMenuBar) {
this.aSubMenuBar = aSubMenuBar;
}
//...
}
Это не окончательное решение, а базовая концепция.
Сообщите, помогло ли это
Удачи