0

I want to add some objects into an Composite object. Objects can have different shapes (rectangle, circle, ellipse or even weird shape (represented by a polygon). So I defined classes like this:

public class Circle extends Canvas {
}

public class Rectangle extends Canvas {
}

...

I know how to draw in a Canvas to get the shape I want, but I also expected that the popup menu appears at each canvas only if the users click mouse inside the canvas area, so if I use these code in a composite class:

Menu aSampleMenu = new Menu(this);

Circle circle = new Circle(parent, style);
circle.setMenu(aSampleMenu);

the menu will appear if the user click right mouse button anywhere inside the canvas, even outside the shape area. How can I fix this problem?

Jarrod
  • 9,349
  • 5
  • 58
  • 73
Hieu Nguyen
  • 382
  • 2
  • 15
  • Have you looked at some other possibilities that already solve this problem for you? Like using a third-party API such as draw2d or GEF, this will make your trivial tasks such as these a lot easier. – Waqas Ilyas Dec 23 '12 at 15:16
  • I already tried suggesting alternatives [here](http://stackoverflow.com/a/13976303/1449199). GEF might be a little too heavy-weight. – Baz Dec 23 '12 at 21:44

2 Answers2

0

Have a look at the code snippet below. The trick is defining the Menu first and then setting it only to those Controls that should allow menu detection:

public class StackOverflow
{
    public static void main(String[] args)
    {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new GridLayout(2, true));

        Composite c1 = new Composite(shell, SWT.BORDER);
        c1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        Composite c2 = new Composite(shell, SWT.BORDER);
        c2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        Menu menu = new Menu(shell, SWT.POP_UP);
        MenuItem item = new MenuItem(menu, SWT.PUSH);
        item.setText("Popup");

        new Label(shell, SWT.BORDER).setText("No menu here");
        new Label(shell, SWT.BORDER).setText("No menu here");

        // Add menu only to c1 and c2, not to the shell and not to the labels
        c1.setMenu(menu);
        c2.setMenu(menu);

        shell.setSize(300, 300);
        shell.open();
        while (!shell.isDisposed())
        {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}

Here is a screenshot:

enter image description here

Baz
  • 36,440
  • 11
  • 68
  • 94
  • Thank you but it is not the answer yet. In your case, for example, if I draw a circle in the canvas `c1`, I want the popup menu appears only if user click **inside the circle area**, not inside all the canvas area. I found a solution using region (see my reply below). It can be applied perfectly for polygons, but I still can not figure out how its usage for circle (maybe I need to represent a circle by a point array). If you know, please let me know... – Hieu Nguyen Dec 23 '12 at 11:00
  • 1
    @HieuNguyen Ok, so my approach detects the `Canvas` where the click event occurred. I guess you know the radius and center of your cicle. Then you can determine if the click was within the circle by calculating the Euclidean distance between the click and the center. If that value is smaller than (or equal to) the radius, the click was inside and outside otherwise. – Baz Dec 23 '12 at 11:06
  • yeah I really appreciate your help, maybe the reason is that I still have a few difficulties in communicating in English :-). I will try to describe my problems clearer next time :D – Hieu Nguyen Dec 23 '12 at 11:08
  • @HieuNguyen Check the comment above yours. – Baz Dec 23 '12 at 11:23
0

One solution is using Region, but I still dont figure out how it can be applied to circle case:

    Region region = new Region();
    region.add(new int[] {3, 3, 20, 20, 3, 20});

    Canvas c = new Canvas(this, SWT.NONE);
    c.setBounds(35, 35, 60, 60);
    c.setRegion(region);

    Menu menu = new Menu(this);
    c.setMenu(menu);

    MenuItem mntmProperties = new MenuItem(menu, SWT.NONE);
    mntmProperties.setText("Properties");

    MenuItem mntmDelete = new MenuItem(menu, SWT.NONE);
    mntmDelete.setText("Delete");
Hieu Nguyen
  • 382
  • 2
  • 15