Why jzy3/jogl newt window is always on top? - swt

I'm using jzy3d/SWT with mapper and surface and this code to create the chart (container is a composite with gridLayout) :
Settings.getInstance().setHardwareAccelerated(true);
jzy3DChart = SWTChartComponentFactory.chart(container);
((CanvasNewtSWT)jzy3DChart.getCanvas()).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
jzy3DChart.black();
jzy3DChart.getScene().getGraph().add(surface);
ChartLauncher.openChart(jzy3DChart);
I get this rendering at initial creation :
But when another part is selected, the newt window always stay on top (chart3 is 2D chart and should be on top) :
I've tried to toggle newt window visibility using :
newtCanvasSWT.getNEWTChild().setVisible(false/true);
But doing so the newt window becomes independent and no longer embedded in its SWT container and can disappear under other controls when it should not.
What am I doing wrong ?
How to set newt window not to be always on top ?
Edit :
Here is the workaround code I've used :
getSite().getPage().addPartListener(new IPartListener2() {
#Override
public void partHidden(IWorkbenchPartReference partRef) {
// Dispose jsyz3d chart composite when this part is hidden
if(partRef.getPart(false) == XYZChartEditor.this) {
if(chart != null) {
chart.dispose();
chart = null;
}
}
}
#Override
public void partVisible(IWorkbenchPartReference partRef) {
// Refresh or rebuild chart when this part reappears
if(partRef.getPart(false) == XYZChartEditor.this) {
if(chart != null) {
// Force chart parent composite to layout
chartContainer.layout();
return;
}
// Rebuild chart
chart = SWTChartFactory.chart(chartContainer, Quality.Nicest());
chart.getView().setViewPoint(xyzChartData.getViewPoint());
chart.getView().addViewPointChangedListener(XYZChartEditor.this);
chart.black();
ChartLauncher.openChart(chart);
// Force chart parent composite to layout
chartContainer.layout();
boolean wasDirty = XYZChartEditor.this.isDirty();
SelectionChangedEvent event = new SelectionChangedEvent(trialsListViewer, trialsListViewer.getSelection());
XYZChartEditor.this.selectionChanged(event);
if(!wasDirty) XYZChartEditor.this.setDirty(false);
((CanvasNewtSWT)chart.getCanvas()).addMouseListener(XYZChartEditor.this);
canvas = ((CanvasNewtSWT) chart.getCanvas());
newtCanvasSWT = canvas.getCanvas();
newtWindow = ((CanvasNewtSWT) chart.getCanvas()).getCanvas().getNEWTChild();
}
}
});

Related

How can I hide row/column headers in a NatTable?

I want to be able to add options to a right click menu of the NatTable that when clicked will cause either the row or column headers to be hidden but can be brought back as well.
The common practice is to operate on the corresponding DataLayer and modify the row height. Modifying the IDataProvider is typically not a good practice, as the IDataProvider is responsible for providing the data, not how the data should be rendered. So the following is an example of how to toggle the visibility of the column header layer (supposed that hideHeader is the flag to store the current state).
Button hideButton = new Button(buttonPanel, SWT.PUSH);
hideButton.setText("Hide/Show");
hideButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
this.hideHeader = !this.hideHeader;
if (this.hideHeader) {
columnHeaderDataLayer.setDefaultRowHeight(0);
} else {
columnHeaderDataLayer.setDefaultRowHeight(20);
}
natTable.refresh(false);
}
});
I know users who even used that approach to implement some sort of transition by slowly reducing the height to 0.
Alternatively you could use the RowResizeCommand if the column header DataLayer is not known
Button hideButton = new Button(buttonPanel, SWT.PUSH);
hideButton.setText("Hide/Show");
hideButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
this.hideHeader = !this.hideHeader;
if (this.hideHeader) {
natTable.doCommand(new RowResizeCommand(natTable, 0, 0));
} else {
natTable.doCommand(new RowResizeCommand(natTable, 0, 20));
}
}
});
I ended up solving this by changing the logic in the getColumnCount() method in my RowHeaderDataProvider to return 0 when flagged to be hidden, or 1 when flagged to be not hidden. Same applies for the getRowCount() in my ColumnHeaderDataProvider.

How to get Menu or MenuItem width in JavaFX?

I am extending the default Menu and MenuItem class to add some animated effects to it.
The problem is that I need to know the width and height of the Menu and MenuItem I'm working on. This classes doesn't extend Node or Region so there are no public methods to get their size. The size is composed by the text size inside the MenuItem plus the corresponding default padding, I can calculate how much space the text takes, but I can't get how much padding the MenuItem has neither.
There is a method called impl_styleableGetNode() that returns a Node but it always returns null for me.
Is there anyway to get the size? MenuBar also doesn't seems to expose any helpful method for this.
EDIT:
Here is my class, I'm trying to implement this material design button into the Menu class. Basically I render all the button using the setGraphic() method. It's working perfectly but I'm using the Pane width which doesn't take into account the padding of the Menu so the effect is not complete.
public class MaterialDesignMenu extends Menu {
private Pane stackPane = new Pane();
private Label label = new Label();
private Circle circleRipple;
private Rectangle rippleClip = new Rectangle();
private Duration rippleDuration = Duration.millis(250);
private double lastRippleHeight = 0;
private double lastRippleWidth = 0;
private Color rippleColor = new Color(1, 0, 0, 0.3);
public MaterialDesignMenu() {
init("");
}
public MaterialDesignMenu(String text) {
init(text);
}
public MaterialDesignMenu(String text, Node graphic) {
init(text);
}
private void init(String text){
label.setText(text);
createRippleEffect();
stackPane.getChildren().addAll(circleRipple, label);
setGraphic(stackPane);
}
private void createRippleEffect() {
circleRipple = new Circle(0.1, rippleColor);
circleRipple.setOpacity(0.0);
// Optional box blur on ripple - smoother ripple effect
//circleRipple.setEffect(new BoxBlur(3, 3, 2));
// Fade effect bit longer to show edges on the end of animation
final FadeTransition fadeTransition = new FadeTransition(rippleDuration, circleRipple);
fadeTransition.setInterpolator(Interpolator.EASE_OUT);
fadeTransition.setFromValue(1.0);
fadeTransition.setToValue(0.0);
final Timeline scaleRippleTimeline = new Timeline();
final SequentialTransition parallelTransition = new SequentialTransition();
parallelTransition.getChildren().addAll(
scaleRippleTimeline,
fadeTransition
);
// When ripple transition is finished then reset circleRipple to starting point
parallelTransition.setOnFinished(event -> {
circleRipple.setOpacity(0.0);
circleRipple.setRadius(0.1);
});
stackPane.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
parallelTransition.stop();
// Manually fire finish event
parallelTransition.getOnFinished().handle(null);
circleRipple.setCenterX(event.getX());
circleRipple.setCenterY(event.getY());
// Recalculate ripple size if size of button from last time was changed
if (stackPane.getWidth() != lastRippleWidth || stackPane.getHeight() != lastRippleHeight) {
lastRippleWidth = stackPane.getWidth();
lastRippleHeight = stackPane.getHeight();
rippleClip.setWidth(lastRippleWidth);
rippleClip.setHeight(lastRippleHeight);
/*
// try block because of possible null of Background, fills ...
try {
rippleClip.setArcHeight(stackPane.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius());
rippleClip.setArcWidth(stackPane.getBackground().getFills().get(0).getRadii().getTopLeftHorizontalRadius());
circleRipple.setClip(rippleClip);
} catch (Exception e) {
e.printStackTrace();
}*/
circleRipple.setClip(rippleClip);
// Getting 45% of longest button's length, because we want edge of ripple effect always visible
double circleRippleRadius = Math.max(stackPane.getHeight(), stackPane.getWidth()) * 0.45;
final KeyValue keyValue = new KeyValue(circleRipple.radiusProperty(), circleRippleRadius, Interpolator.EASE_OUT);
final KeyFrame keyFrame = new KeyFrame(rippleDuration, keyValue);
scaleRippleTimeline.getKeyFrames().clear();
scaleRippleTimeline.getKeyFrames().add(keyFrame);
}
parallelTransition.playFromStart();
});
}
public void setRippleColor(Color color) {
circleRipple.setFill(color);
}
}
First you have to listen to parentPopupProperty changes of MenuItem. When you get the instance of parent popup than register listener for skinProperty of ContextMenu (parentPopup). When you get the skin then you can get MenuItemContainer which is Node equivalent of MenuItem and you can listen to widthProperty or heightProperty changes of MenuItemContainer.
Note: skinProperty change is fired just before ContextMenu is shown on the screen.
Custom class extending MenuItem class:
public class CstMenuItem extends MenuItem {
public CstMenuItem() {
// Create custom menu item listener.
new CstMenuItemListener(this);
}
/*
* Returns MenuItemContainer node associated with this menu item
* which can contain:
* 1. label node of type Label for displaying menu item text,
* 2. right node of type Label for displaying accelerator text,
* or an arrow if it's a Menu,
* 3. graphic node for displaying menu item icon, and
* 4. left node for displaying either radio button or check box.
*
* This is basically rewritten impl_styleableGetNode() which
* should not be used since it's marked as deprecated.
*/
public ContextMenuContent.MenuItemContainer getAssociatedNode() {
ContextMenu contextMenu = getParentPopup();
ContextMenuSkin skin = (ContextMenuSkin) contextMenu.getSkin();
ContextMenuContent content = (ContextMenuContent) skin.getNode();
// Items container contains MenuItemContainer nodes and Separator nodes.
Parent itemsContainer = content.getItemsContainer();
List<Node> children = itemsContainer.getChildrenUnmodifiable();
for (Node child : children) {
if (child instanceof ContextMenuContent.MenuItemContainer) {
ContextMenuContent.MenuItemContainer menuItemContainer =
(ContextMenuContent.MenuItemContainer) child;
if (menuItemContainer.getItem() == this) {
return menuItemContainer;
}
}
}
return null;
}
}
Custom MenuItem listener class:
public class CstMenuItemListener implements ChangeListener {
private CstMenuItem menuItem;
private ContextMenu parentPopup;
private Region menuItemContainer;
public CstMenuItemListener(CstMenuItem menuItem) {
this.menuItem = menuItem;
menuItem.parentPopupProperty().addListener(this);
}
#Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
if (observable == menuItem.parentPopupProperty()) {
parentPopup = (ContextMenu) newValue;
parentPopup.skinProperty().addListener(this);
} else if (observable == parentPopup.skinProperty()) {
menuItemContainer = menuItem.getAssociatedNode();
menuItemContainer.widthProperty().addListener(this);
menuItemContainer.heightProperty().addListener(this);
} else if (observable == menuItemContainer.widthProperty()) {
System.out.println("width: " + (double) newValue);
} else if (observable == menuItemContainer.heightProperty()) {
System.out.println("height: " + (double) newValue);
}
}
}

In Gwt Drag and Drop, how to drop a widget into a right position of a VerticalPanel that already has many labels on it?

Ok, let say, you got a label, you got a VerticalPanel that has many labels on it. See this code:
// Make the widget draggable.
Label w = new Label("OutSide Label");
w.getElement().setDraggable(Element.DRAGGABLE_TRUE);
// Add a DragStartHandler.
w.addDragStartHandler(new DragStartHandler() {
#Override
public void onDragStart(DragStartEvent event) {
// Required: set data for the event.
event.setData("text", "Hello World");
// Optional: show a copy of the widget under cursor.
event.getDataTransfer().setDragImage(w.getElement(), 10, 10);
}
});
VerticalPanel vp=nw VerticalPanel();
vp.add(new Label("l1");
vp.add(new Label("l2");
vp.add(new Label("l3");
vp.addDomHandler(new DragOverHandler() {
public void onDragOver(DragOverEvent event) {
vp.getElement().getStyle().setBackgroundColor("#ffa");
}
}, com.google.gwt.event.dom.client.DragOverEvent.getType());
vp.addDomHandler(new DropHandler() {
#Override
public void onDrop(com.google.gwt.event.dom.client.DropEvent event) {
// TODO Auto-generated method stub
event.preventDefault();
// Get the data out of the event.
String data = event.getData("text");
//Window.alert(data);
/// WE NEED TO FILL IN THE MISSING CODE HERE
/// WE NEED TO FILL IN THE MISSING CODE HERE
}
}, DropEvent.getType());
how to code so that when user drag the outside label into the area of VerticalPanel, if the outside label was dragged between the existing widgets, it will be inserted into the between of existing labels on VerticalPanel, Ex if the outside label was drag between "l1" & "l2", the vp will show:
l1
OutSide Label
l2
l3
Something like the following should theoretically work, although not tested:
p.addDomHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
// Get the target event.
EventTarget eventTarget = event.getNativeEvent().getEventTarget();
// Safe check for casting to Element.
if (Element.is(eventTarget)) {
Element elementTarget = Element.as(eventTarget);
// Loop through VerticalPanel's children to find our target.
for (int i = 0; i < p.getWidgetCount(); ++i) {
if (p.getWidget(i).getElement().isOrHasChild(elementTarget)) {
// Insert a new Label with the DataTransfer's data,
// and remove the old one.
p.insert(new Label(event.getData("text")), i);
oldLabelContainer.remove(oldLabel);
break;
}
}
}
}
}, DropEvent.getType());
Of course, if you have a lot of labels that loop should be avoided.

Ext GWT (GXT) tooltip over a grid row

I'm developing a custom tooltip using Ext GWT (GXT) for a project of mine, and this tooltip has to appear over Grid rows when they're selected.
I can't use the default GXT tooltip or quicktip because I need be able to add Components (like buttons) to this tooltip.
The problem is that the GXT Grid component doesn't expose a event related to mousing over a row (although there's RowClick and RowMouseDown).
I tried adding a listener to the Grid with the OnMouseOver and OnMouseOut events anyway, but it doesn't work as expected. It fires these events up whenever
you mouse over any of the divs and spans that composes a row.
The only way I see to solve this is to subclass the GridView component and make each row become a Component itself,
but that would be a lot of work and would probably impact performance as well. I can't help but think there's a better way to do this.
Could someone more experienced with GXT give me a light?
try this
QuickTip quickTip = new QuickTip(grid);
grid.addListener(Events.OnMouseOver, new Listener<GridEvent<BeanModel>>(){
#Override
public void handleEvent(GridEvent<BeanModel> ge) {
com.google.gwt.dom.client.Element el= grid.getView().getCell(ge.getRowIndex(),ge.getColIndex());
String html = "<span qtip='" + el.getFirstChildElement().getInnerText() + "'>" + el.getFirstChildElement().getInnerText() + "</span>";
el.getFirstChildElement().setInnerHTML(html);
}
});
onComponentEvent() (defined in com.extjs.gxt.ui.client.widget.Component with an empty body and overridden in com.extjs.gxt.ui.client.widget.grid.Grid) also receives Events with type Event.ONMOUSEOVER and Event.ONMOUSEOUT
The default implementation in the Grid class doesn't handle those events, so you may want to override this function in a subclass.
Additionally, at the end of onComponentEvent(), the Grid calls the function handleComponentEvent() of the GridView.
I found 2 ways to do that:
1.For specific column of the grid describe renderer, e.g.:
{
width: 200,
dataIndex : 'invoice',
renderer:addTooltip
}
And your renderer function:
function addTooltip(value, metadata){
metadata.attr = 'ext:qtip="' + value + '"';
return value;
}
But this method will work only when your mouse pointer will be above that specific column.
2.For 'render' event of the grid apply/use this function:
var myGrid = grid;
myGrid.on('render', function() {
myGrid.tip = new Ext.ToolTip({
view: myGrid.getView(),
target: myGrid.getView().mainBody,
delegate: '.x-grid3-row',
trackMouse: true,
renderTo: document.body,
listeners: {
beforeshow: function updateTipBody(tip) {
tip.body.dom.innerHTML = "Over row " + tip.view.findRowIndex(tip.triggerElement);
}
}
});
});
I hope this will be helpful to you :)
I know this is old but there's no accepted answer and I think I found a better way:
grid.addListener(Events.OnMouseOver, new Listener<GridEvent<Model>>() {
#Override
public void handleEvent(GridEvent<Model> ge) {
if (grid.getToolTip() != null) {
grid.getToolTip().hide();
}
ModelData model = ge.getModel();
if (model != null) {
Object someValue = model.get("someProperty");
String label = someValue.toString();
grid.setToolTip(label);
}
if (grid.getToolTip() != null) {
grid.getToolTip().show();
}
}
});
I am using GWT 2.6 and GXT 3.1.0 and I managed to do this in this way ....
Here the class RowSet is analogous to a Map
GridView<RowSet> view = new GridView<RowSet>() {
private Element cell;
#Override
protected void handleComponentEvent(Event event) {
switch (event.getTypeInt()) {
case Event.ONMOUSEMOVE:
cell = Element.is(event.getEventTarget()) ? findCell((Element) event.getEventTarget().cast())
: null;
break;
}
super.handleComponentEvent(event);
}
#Override
protected void onRowOut(Element row) {
grid.hideToolTip();
grid.setToolTipConfig(null);
super.onRowOut(row);
}
#Override
protected void onRowOver(final Element row) {
super.onRowOver(row);
grid.hideToolTip();
grid.setToolTipConfig(null);
ToolTipConfig config = new ToolTipConfig();
int rowIndex = grid.getView().findRowIndex(row);
// Through "rowIndex" you can get the Row like this :
// grid.getStore().get(rowIndex)
config.setBodyHtml("Your tool tip text here");
config.setTitleHtml("Tool Tip Title");
config.setCloseable(true);
grid.setToolTipConfig(config);
int absoluteRight = (cell != null) ? cell.getAbsoluteRight() : row.getAbsoluteRight();
int absoluteTop = (cell != null) ? cell.getAbsoluteTop() : row.getAbsoluteTop();
Point point = new Point(absoluteRight, absoluteTop);
grid.getToolTip().showAt(point);
}
};
view.setAutoFill(true);
grid.setView(view);

How do I get a GWT menu popup to stay within the browser window?

My GWT app uses a DockLayoutPanel for primary layout and the page itself does not scroll. I have a PopupPanel with a MenuBar and sometimes when a MenuItem is selected the sub menu bar goes off the bottom of the screen abruptly forcing a new scroll bar into the browser and messing up the layout.
How do I get the menu popup to behave nicely and reposition itself upward when the default positioning would put it out of the browser viewport (the way that PopupPanel.showRelativeTo(uiTarget) positioning works)?
In looking at the MenuBar source, it looks like all the layout is done in private methods, so I can't fix it in subclass, and I don't see any events I can listen to that would allow me to do the repositioning myself.
Take a look at http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/6185225fec64c091/4954d91d1461c71f?lnk=gst&q=context+menu#4954d91d1461c71f.
We've been using this strategy quite successfully for a while now.
Update: There is a bit more to be done. Specifically:
Create a reposition() method, which:
Determines the max width of all the menu items
Checks the left edge of the menu + the max width; if greater than the Window's width, use "DOM.setStyleAttribute(elem, "left", left + "px");" to move the menu
Get the height of the menu; if top of the menu + height of the menu > Window's height, use "DOM.setStyleAttribute(elem, "top", top + "px");" to move it up.
In the onAttach() method, use a deferred command to invoke the reposition() method.
You can intercept the popup just before it is shown, but after its size has been created. This way you have the width of the popup and could move it to another position:
#Override
public void onContextMenu(ContextMenuEvent evt) {
int x = evt.getNativeEvent().getClientX();
int y = evt.getNativeEvent().getClientY();
popupMenu.setPopupPositionAndShow(new PositionCallback() {
#Override
public void setPosition(int offsetWidth, int offsetHeight) {
if (x + offsetWidth > Window.getClientWidth()) {
x = Window.getClientWidth() - offsetWidth;
}
//use same technique for height if you want for y, then
setPosition(x, y);
}
});
}
(I know this is an old question, but still comes up if you search for this, so I thought of providing present solution)
Emm...
It is an interesting question...
Looking at the MenuBar source code... especially the method 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);
}
}
}
});
}
It is interesting to point the snippet as
...
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);
}
}
}
});
...
... so I may suppose there is a sense to play around MenuItem object especially its UIObject inherited methods like getAbsoluteLeft() and getAbsoluteTop(), of course ...
I would recommend to extend MenuItem something in this way
//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;
}
//...
}
It is not the final solution but a basic conception.
Report if that helped
Good luck