public static void main(String[] args) {
final Display display = Display.getDefault();
Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final Button button = new Button(shell, SWT.PUSH);
button.setText("Button");
GridData buttonGridData = new GridData();
buttonGridData.verticalAlignment = SWT.BOTTOM;
buttonGridData.grabExcessVerticalSpace = true;
button.setLayoutData(buttonGridData);
final Menu menu = new Menu(shell, SWT.POP_UP);
final MenuItem item = new MenuItem(menu, SWT.NONE);
item.setText("Item");
button.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
menu.setVisible(true);
display.asyncExec(new Runnable() {
public void run() {
Rectangle bounds = getMenuBoundsReflect(menu);
int verticalSpacing = 3;
Point location = display.map(button, null, 0, -verticalSpacing);
menu.setVisible(false);
menu.setLocation(location.x, location.y - bounds.height);
menu.setVisible(true);
}
});
}
});
shell.setSize(300, 200);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
public static Rectangle getMenuBoundsReflect(Menu menu) {
try {
Method m = Menu.class.getDeclaredMethod("getBounds", (Class[]) null);
m.setAccessible(true);
return (Rectangle) m.invoke(menu, (Object[]) null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
I have tested this code only on Windows (7).