Position Window relative to another component

Hello,

I have a requirement to show a “drop-down” relative to a button/link/embedded icon when a server side event is pushed to the client. since i have no click event i have no X/Y to use to position the popup window. Is there any way to tell a component to position itself relative to another component? Has anyone done this before using a custom widget they would be willing to share?

Hello,
yes, i have done that. I have extended AbstractComponent:

public class Position extends AbstractExtension {
private static final long serialVersionUID = 1L;

private int positionX = -1;
private int positionY = -1;

private PositionServerRpc rpc = new PositionServerRpc() {
private static final long serialVersionUID = 1L;

@Override
public void absolutePosition(int absoluteLeft, int absoluteTop) {
positionX = absoluteLeft;
positionY = absoluteTop;
}
};

public Position() {
registerRpc(rpc);
}

public Position(AbstractComponent component) {
this();
extend(component);
}

public void extend(AbstractComponent component) {
super.extend(component);
}

public static Position addTo(AbstractComponent component) {
Position position = new Position();
position.extend(component);
return position;
}

public int getPositionX() {
return positionX;
}

public int getPositionY() {
return positionY;
}
}

The corresponding connector class looks like:

@Connect(Position.class)
public class PositionConnector extends AbstractExtensionConnector {

private static final long serialVersionUID = 1L;

private PositionServerRpc rpc = RpcProxy.create(PositionServerRpc.class, this);
private Widget widget;

private AttachEvent.Handler attachHandler = new AttachEvent.Handler() {
@Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
rpc.absolutePosition(widget.getAbsoluteLeft(), widget.getAbsoluteTop());
}
};
};

public PositionConnector() {
}

@Override
protected void extend(ServerConnector target) {
widget = ((ComponentConnector) target).getWidget();
widget.addAttachHandler(attachHandler);
}

}

With a PositionServerRpc as follows:

public interface PositionServerRpc extends ServerRpc {
public void absolutePosition(int absoluteLeft, int absoluteTop);
}

Addition:

There are some caveats:

  • The GWT-methods getAbsoluteXxxx don’t take the margin of the body into account.
  • For a TextField the returned position is the position of the HTML input element (a caption is not considered).
  • If used within HorizontalSplitPanel / VerticalSplitPanel the returned position is relative to the subcomponent of these panels. So the offset of the subcomponent must be added in order to get the correct position.