1

I'm developing a GWT widget for an existing vaadin application and so far everything has worked out fine, until I needed to call a server-side function from the client and get a value from it to the client.

more detailed issue: There is a server-side function that gets certain values from a connected database. Now I want to get access this function from the client-side, since I need the values to update something in the widget.

According to Vaadin and GWT documentations you're supposed to use RPC for this, and I already implemented multiple functions on the server-side that bascially do the opposite (send something from the server to the client, initiate a call of a client function from server code etc.)

From my understanding I'm supposed to call a void return function on the server by using rpc (the part I can't get to work) then I could make that function on the server use a server=>client rpc to send that value back to the client (already working)

Is this the definite solution and if so how do I properly implement the client=>server part and if not, what would be a good solution?

I've already tried something like https://vaadin.com/wiki/-/wiki/Main/Sending+events+from+the+client+to+the+server+using+RPC but somehow can't figure out how to call the method while in the widget class and not in the connector class There just seems to be something missing? and is this even the right approach?

parts of the current code:

DrawwServerRPC

public interface DrawwServerRPC extends ServerRpc {
   public void updateE(String e);
}

relevant part of Draww.java on server

protected DrawwServerRPC = new DrawwServerRPC () {
    public void updateE(String e){
        // gets some values from a db and then sends them back to the client 
        // via rpc (both points working fine)
    }
};

public Draww() {
    registerRpc(rpc);
}

part of the connector class, this is supposed to be called when a specific method in the DrawwWidget class (client) is called, instead of on a click

getWidget().addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
                .buildMouseEventDetails(event.getNativeEvent(),
                            getWidget().getElement());
            rpc.updateE("test");
        }
    });

So my main issue is, how do I now properly access this method (most likely over the connector method) when a specific function in the DrawwWidget class on the Client is called?

And how do I then pass the value from the client method to the connector (or even server side) method? => need to somehow call the updateE method on the server from client side code (by using connector/rpc)

edit: so here is a bit longer explanation of how I solved it in the end according to the idea I got from Mika's answer and this

added an Interface

public interface customListener {
    void customEvent (String s);
}

adjusted the DrawwWidget:

public class DrawwWidget extends Label{
private customListener MyListener;
//...
private void someFunction() {
    String something = ...;
    if (myListener != null) myListener.customEvent(something);
    }

public void setMyListener(customListener listener) {
    this.myListener = listener;
    }

}

and finally implemented the listener in the connector class:

public class DrawwConnector extends AbstractComponentConnector implements customListener {
DrawwServerRpc rpc = RpcProxy.create(DrawwServerRpc.class, this);
public DrawwConnector () {
    //lots of irrelevant Server => Client rpc things
    getWidget().setMyListener(this);
}

@Override
public void customEvent(String s) {
    rpc.doSomething(s);
}

Now I can call the server side "doSomething" method from wherever I want in the widget by using the "customEvent (String s)" Method

1 Answers1

0

You can interact with client side with custom widgets or javascript extensions. For visible components custom widget is usually suitable solution.

You can follow similar convention in client side as Vaadin generally follows in server side and register a listener from connector to your widget. For example:

@Override
protected Widget createWidget() {
    MyWidget widget = GWT.create(MyWidget.class);
    widget.addMyListener(new MyListener() {
        @Override
        public void onSomeEvent(ClientData data) {
            rpc.onEventFromClient(data);
        }
    });
    return widget;
}

Widget is a GWT component and usually you can find some existing GWT component that you can extend. If not, then it is possible to create plain HTML elements from the widget, good reference for this is the source code for existing GWT components.

Here is an example of a widget that has a text and you can click on the widget.

import com.google.gwt.user.client.ui.Label;
// ... only relevant imports included
public class MyWidget extends Label {
    private List<MyListener> listeners = new ArrayList<MyListener>();

    public MyWidget() {
        addStyleName("m-my-label");
        // Add GWT event listeners for events that you want to capture.
        addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                notifyListeners();
            }
        });
    }

    private void notifyListeners() {
        for (MyListener listener : listeners) {
            listener.onSomeEvent(new ClientData("Hello from widget"));
        }
    }
}
Mika
  • 1,256
  • 13
  • 18
  • yes, I did something like this in the connector class before already with a clickHandler. now my question is, how do I make this "listen for"/handle/... a certain method being called in the actual widget? So for example it should call the "onEventFromClient..." method, when I call the dataUpdate... Method in the Widget. GWT seems to provide some things like "addDomHandler", but I don't know if that would work since I can't really figure out how to use it –  Jul 10 '17 at 08:46
  • also added some code to my question to hopefully make it more clear –  Jul 10 '17 at 09:04
  • I added an example of an label widget. What kind of event is it that you want to listen? If there is existing GWT widget that you can extend then do that and use existing GWT event listeners. If you need to create HTML elements then that is slightly more work and in this case you need to choose JavaScript event that you want to listen. – Mika Jul 10 '17 at 19:53
  • thanks, this helped me enough to solve it. I wrote my own listener according to [this](https://stackoverflow.com/questions/33948916/java-custom-event-handler-and-listeners) and implemented it in the connector. Now I can call it from the widget,pass the values I need and everything seems to work as I wanted. –  Jul 11 '17 at 06:06