2

I have an RCP view with a GeoMap widget inside it. When the view is created, the map is centred on a position.

The problem I'm having is that when GeoMap calls getSize() it is wrong. It is returning (0,0).

I've found one method of fixing this but it required changing code in GeoMap even though I believe the problem is to do with the code in the view. If I change the setCenterPosition method for GeoMap to use the parents client area it works.

View

@PostConstruct
public void createPartControl(final Composite parent) {
    Display.getDefault().asyncExec(() -> setInitialPosition());
}

private void setInitialPosition() {
    widget.setCenterPosition(new PointD(longitude, latitude));
    widget.redraw();
}

GeoMap

public void setCenterPosition(final Point p) {

    // `parent.getClientArea()` instead of `getSize()`
    final Rectangle size = getParent().getClientArea();

    setMapPosition(p.x - (size.width / 2), p.y - (size.height / 2));
}

The problem with this is that I've had to change code in GeoMap to fix a problem that is likely to do with getting the size of the view. The view hasn't had the size set by the time I call to centre the map.

I've also tried adding a resize listener to the view. This wouldn't always produce the same results when getting the size of the GeoMap widget.

parent.addListener(SWT.Resize, new Listener() {
    @Override
    public void handleEvent(final org.eclipse.swt.widgets.Event e) {
        if (firstResize) {
            setInitialPosition();
            firstResize = false;
        }
    }
});

Here mentions that a resize listener should be used, and getClientArea. The problem is that GeoMap doesn't use getClientArea but I don't know if it should be.

Is this a problem with how I'm calling setCenterPosition or a bug in GeoMap?

Update

I've also tried adding a resize listener to the widget.

widget.addListener(SWT.Resize, new Listener() {
    @Override
    public void handleEvent(final org.eclipse.swt.widgets.Event e) {
        if (firstResize) {
            setInitialPosition();
            firstResize = false;
        }
    }
});

For some reason the size the widget gets is too small. It is getting a size of (615, 279) when it should be (768, 388). By adding a button to call setCenterPosition again it gets the correct size of (768, 388).

I can fix this if I add it inside an async block but this seems more like a workaround than an actual fix.

widget.addListener(SWT.Resize, new Listener() {
    @Override
    public void handleEvent(final org.eclipse.swt.widgets.Event e) {
        if (firstResize) {
            Display.getDefault().asyncExec(() -> {
                setInitialPosition();
                firstResize = false;
            });
        }
    }
});
Michael
  • 3,411
  • 4
  • 25
  • 56
  • You probably need to add the resize listener to the GeoMap control, **not** the parent composite. By the time that resize is fired `getSize()` should be returning the correct value. – greg-449 Feb 07 '20 at 13:55
  • I've tried this and I get strange results. On the first time it is centred the size of the widget is too small. `(615, 279)`. If I call `setCenterPosition` again by clicking a button it gets a different size of `(768, 388)`. I've print screened and checked the dimensions and in both cases when it is displayed it is `(768, 388)`. – Michael Feb 07 '20 at 16:21
  • @greg-449 I've updated my question to show what I tried. – Michael Feb 07 '20 at 16:23
  • Resize is often called several times (at least twice) during the layout of a control, just doing the set on the first resize is not likely to be enough. – greg-449 Feb 07 '20 at 17:09
  • @greg-449 Is it possible to know when the final resize is done? I'm assuming it wouldn't be easy. We want it to centre when the map is first displayed and no more after that. – Michael Feb 07 '20 at 17:26
  • Testing here the `Display.asyncExec` runnable does run after the resizes have finished, but I am not sure if that is guaranteed on all platforms (I am using macOS, very different SWT internals to Linux or Windows). – greg-449 Feb 08 '20 at 08:00

0 Answers0