Sending events from the client to the server using RPC
server component. The server component can then take appropriate action - e.g updating the shared state or calling event listeners.
To set up client-server RPC we need to create one interface defining the
RPC methods, and then make use of that interface on both the client and
the server. Place the MyComponentServerRpc
interface in the client
package:
package com.example.mycomponent.client;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.communication.ServerRpc;
public interface MyComponentServerRpc extends ServerRpc {
public void clicked(MouseEventDetails mouseDetails);
}
Note that the RPC methods can not have return values. In this example,
we pass MouseEventDetails
to get a more complete example, but you
could pass almost any (or no) parameters.
In the server side MyComponent
we need to implement the interface, and
register it for use:
package com.example.mycomponent;
import com.example.mycomponent.client.MyComponentServerRpc;
import com.example.mycomponent.client.MyComponentState;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.ui.AbstractComponent;
public class MyComponent extends AbstractComponent {
private int clickCount = 0;
private MyComponentServerRpc rpc = new MyComponentServerRpc() {
public void clicked(MouseEventDetails mouseDetails) {
clickCount++;
setText("You have clicked " + clickCount + " times");
}
};
public MyComponent() {
registerRpc(rpc);
}
/* Previous code commented out for clarity:
@Override
public MyComponentState getState() {
return (MyComponentState) super.getState();
}
public void setText(String text) {
getState().text = text;
}
public String getText() {
return getState().text;
}
*/
}
Here we react to the RPC call by incrementing a counter. We do not make
use of the MouseEventDetails
(yet). Notice the important call to
registerRpc()
in the added constructor.
In the client side MyComponentConnector
, we use RpcProxy
to get an
implementation of the RPC interface, and call the clicked()
method
when the widget is clicked:
package com.example.mycomponent.client;
// imports removed for clarity
import com.vaadin.terminal.gwt.client.communication.RpcProxy;
@Connect(MyComponent.class)
public class MyComponentConnector extends AbstractComponentConnector {
MyComponentServerRpc rpc = RpcProxy
.create(MyComponentServerRpc.class, this);
public MyComponentConnector() {
getWidget().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
.buildMouseEventDetails(event.getNativeEvent(),
getWidget().getElement());
rpc.clicked(mouseDetails);
}
});
}
/* Previous code commented out for clarity:
@Override
protected Widget createWidget() {
return GWT.create(MyComponentWidget.class);
}
@Override
public MyComponentWidget getWidget() {
return (MyComponentWidget) super.getWidget();
}
@Override
public MyComponentState getState() {
return (MyComponentState) super.getState();
}
@OnStateChange("text")
void updateText() {
getWidget().setText(getState().text);
}
*/
}
Notice that most of the code is for attaching the click handler and
creating the MouseEventDetails
, the code for the actual RPC is quite
minimal.
Compile the widgetset, and the label text should be updated with the click count whenever you click it (remember that the counting is done on the server-side).
Finally, note that you can use multiple RPC interfaces in one component, allowing for better code separation and reuse.
You can do the same thing in the other direction, see the article about server to client RPC for details.