Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSNI vs jsinterop #7

Open
olivergg opened this issue Apr 30, 2017 · 7 comments
Open

JSNI vs jsinterop #7

olivergg opened this issue Apr 30, 2017 · 7 comments

Comments

@olivergg
Copy link
Contributor

How come there is still some JSNI usage in gwty-leaflet/src/main/java/com/gwidgets/api/leaflet/events/Event.java ?
Does this mean there is still work to be done to fully migrate to jsinterop ?

@zak905
Copy link
Member

zak905 commented May 2, 2017

Hi @olivergg,

Thanks for your remark. I wanted also the project to be 100% JsInterop, but I run into a cast exception when casting the Event class to it's subclasses using JsInterop. For example, when I wrote the Event class and its subclasses using JsInterop class I did something like:

map.on(EventTypes.Map.CLICK, new Function(){
                        @Overeride
                        public Event call(Event event) {
                                //Throws cast exception
                                MouseEvent msEvent = (MouseEvent) Event;
                                
                                map.openPopup("hello", msEvent.getLatlng(), new PopupOptions.Builder().build());
                                return null;
                        }
                        
                });

So I had to change it to JSNI which works fine using the cast method:

map.on(EventTypes.Map.CLICK, new Function(){
                        @Override
                        public JavaScriptObject call(JavaScriptObject event) {

                                MouseEvent msEvent = event.cast();
                                
                                map.openPopup("hello", msEvent.getLatlng(), new PopupOptions.Builder().build());
                                return null;
                        }
                        
                });

If you have any better idea please let me know.

@olivergg
Copy link
Contributor Author

olivergg commented May 3, 2017

@zak905 thanks for your answer. I did not know about this technical limitation. I've found this https://docs.google.com/document/d/10fmlEYIHcyead_4R1S5wKGs1t2I7Fnp_PaNaa7XTEk0/edit#heading=h.kog1ji9nzq7y that might be relevant.
I'll try to find some time to think of a better way to do that. Is there some sample minimal project to try out gwty-leaflet (in order to test a solution) ?

@zak905
Copy link
Member

zak905 commented May 4, 2017

You can find a demo project here: https://github.com/gwidgets/gwty-leaflet-starter-guide

Thanks.

@olivergg
Copy link
Contributor Author

olivergg commented May 7, 2017

Ok, so here is my solution. It somehow relies on lambda type inference instead of type casting.

Event2 is just the jsinterop version of Event :

@JsType(isNative = true)
public class Event2
{

@JsProperty
public native String getType();

@JsProperty
public native HTMLElement getTarget();
}

Then for example :

public class MouseEvent extends Event2 {
   
@JsProperty
public final native LatLng getLatlng();

@JsProperty
public final native Point getLayerPoint();

@JsProperty
public final native Point getContainerPoint();

@JsProperty
public final native DOMMouseEvent getOriginalEvent();

}

I've also replaced the elemental Function with a more generic functional interface :

@JsFunction
@FunctionalInterface
public interface EventCallback<T extends Event2>{
	
	public void call(T event);

}

Then you can use the whole thing with :

map.on(EventTypes.MapEvents.CLICK, (MouseEvent evt) -> {
	if (firstClickFlag) {
       PopupOptions popoptions = new PopupOptions.Builder()
   				               .zoomAnimation(false)
				               .build();
	StringBuilder sb = new StringBuilder();
        sb.append("Hello,");
	sb.append("event type = ").append(evt.getType());
	sb.append("mouse event latlng = ").append(evt.getLatlng());
	map.openPopup(sb.toString(), L.latLng(52.51, 13.40), popoptions);
	firstClickFlag = false;
	}
});

Let me know what you think

@zak905
Copy link
Member

zak905 commented May 8, 2017

Thanks, I will give it a try asap.

@zak905
Copy link
Member

zak905 commented Jul 2, 2017

@olivergg Thanks for your fix. This works.
For the lambda, the type should be either of type Event or casted explicitly inside the call, it will not work in this way. or maybe keeping the normal function form:

map.on(EventTypes.MapEvents.CLICK, new EventCallback<MouseEvent>() {
			@Override
			public void call(MouseEvent event) {
				GWT.log("Mouse event "+event.getLayerPoint().x);
				
			}
		}); 

I am converting all events to jsinterop.

@zak905
Copy link
Member

zak905 commented Jul 2, 2017

3c278a5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants