Robben_Ford_Fan_boy Robben_Ford_Fan_boy - 5 months ago 11
Java Question

Pop up menu on Canvas: only display within specific boundary

I am displaying an

Image
on a
Canvas
. When the user right-clicks on the canvas, a context-menu is displayed.

How do I only display the menu if the user clicked within the bounds of the image? I can get the
x
and
y
position from the event, but surely it is too late at that point!

final Menu pixelContextMenu = new Menu(canvas);
canvas.setMenu(pixelContextMenu);

final MenuItem resetImageItem = new MenuItem(pixelContextMenu, SWT.NONE);
resetImageItem.setText("Reset Image");
resetImageItem.addListener(SWT.MenuDetect, new Listener() {
@Override
public void handleEvent(Event event) {
int x = event.x;
int y = event.y;
}
});

Baz Baz
Answer

Use Event#doit and set it to false if the event is outside of your area. Here's an example that'll show the menu on the left half, but not the right half of the Canvas:

public static void main(String[] args)
{
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Stackoverflow");
    shell.setLayout(new FillLayout());

    final Canvas canvas = new Canvas(shell, SWT.NONE);

    Menu menu = new Menu(canvas);
    new MenuItem(menu, SWT.NONE).setText("MenuItem");
    canvas.setMenu(menu);

    canvas.addListener(SWT.MenuDetect, new Listener()
    {
        @Override
        public void handleEvent(Event event)
        {
            Point location = canvas.toControl(event.x, event.y);
            if(location.x > canvas.getBounds().width / 2f)
                event.doit = false;
        }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}

If you want to show the Menu in any case, but disable some menu items based on the event position, then do this:

public static void main(String[] args) {
    final Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("Stackoverflow");
    shell.setLayout(new FillLayout());

    final Canvas canvas = new Canvas(shell, SWT.NONE);

    Menu menu = new Menu(canvas);
    final MenuItem item = new MenuItem(menu, SWT.NONE);
    item.setText("MenuItem");
    canvas.setMenu(menu);

    canvas.addListener(SWT.MenuDetect, new Listener()
    {
        @Override
        public void handleEvent(Event event)
        {
            Point location = canvas.toControl(event.x, event.y);

            item.setEnabled(location.x <= canvas.getBounds().width / 2f);
        }
    });

    shell.pack();
    shell.open();

    while (!shell.isDisposed())
    {
        if (!display.readAndDispatch())
            display.sleep();
    }
    display.dispose();
}