Java 画布上的弹出菜单:仅在特定边界内显示

Java 画布上的弹出菜单:仅在特定边界内显示,java,canvas,swt,popupmenu,Java,Canvas,Swt,Popupmenu,我正在画布上显示图像。当用户在画布上单击鼠标右键时,将显示关联菜单 如何仅在用户在图像范围内单击时显示菜单?我可以从事件中获得x和y位置,但现在肯定太迟了 final Menu pixelContextMenu = new Menu(canvas); canvas.setMenu(pixelContextMenu); final MenuItem resetImageItem = new MenuItem(pixelContextMenu, SWT.NONE); resetImageItem.

我正在
画布上显示
图像
。当用户在画布上单击鼠标右键时,将显示关联菜单

如何仅在用户在图像范围内单击时显示菜单?我可以从事件中获得
x
y
位置,但现在肯定太迟了

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;
    }
});
使用
Event#doit
并将其设置为
false
(如果事件不在您的区域内)。下面的示例将在
画布的左半部分显示菜单,而不是右半部分显示菜单:

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();
}

如果您想在任何情况下显示
菜单
,但根据事件位置禁用某些菜单项,请执行以下操作:

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();
}
publicstaticvoidmain(字符串[]args){
最终显示=新显示();
最终外壳=新外壳(显示);
shell.setText(“Stackoverflow”);
setLayout(新的FillLayout());
最终画布=新画布(shell,SWT.NONE);
菜单菜单=新菜单(画布);
最终菜单项=新菜单项(菜单,SWT.NONE);
项目.setText(“菜单项”);
canvas.setMenu(菜单);
addListener(SWT.MenuDetect,newlistener())
{
@凌驾
公共无效handleEvent(事件)
{
点位置=canvas.toControl(event.x,event.y);

item.setEnabled(location.x Brilliant!当库的行为与您期望的一样时,您难道不喜欢它:)实际上,我相信这里有一个错误,因为事件将在用户右键单击画布时执行,而不是在他们单击菜单时执行item@Robben_Ford_Fan_boy这是你的问题:“仅当用户在图像范围内单击时,我才显示菜单?"。这就是我提供的。无论如何,我用另一个选项更新了我的答案。也许这就是你要寻找的。我的意思是,在你的示例中,当用户右键单击画布时,侦听器代码就会执行。预期的行为是右键单击画布,获得弹出菜单,然后选择将执行侦听器代码的项。@Robben_Ford_Fan_boy好吧,然后在
菜单项
中添加一个选择项以捕获该项的选择事件只需暂时删除它,然后查看它是否有效。