我是vaadin的新手,正在编写一个websocket客户端,它与android上的websocket服务器连接。
客户端会在左侧生成所有电话联系人组的列表,每次点击此组后,客户端都会将关联的联系人加载到计算机屏幕的右侧。
到目前为止一切正常,但是在第一次点击它之后,加载的联系人不会出现,但仅在第二次之后。它总是加载在实际点击之前点击的组。在调试器中我可以看到正确的联系人已经加载到布局中,但它们仍然只在下一次单击后出现。它始终显示“旧联系人”,而不是使用当前点击创建的联系人。我需要以某种方式强制布局刷新,但到目前为止没有成功
到目前为止我找到的答案都没有帮助:既不使用setImmediate(true),也不使用requestRepaint(true);
@Override
protected void init(VaadinRequest vaadinRequest) {
layoutMain = new HorizontalLayout();
setContent(layoutMain);
layoutLeft = new VerticalLayout();
layoutRight = new VerticalLayout();
layoutMain.addComponent(layoutLeft);
layoutMain.addComponent(layoutRight);
final Client client;
try {
client = new Client(new URI("ws://192.168.0.14:8080"));
Client.ClientListener clientListener = new Client.ClientListener() {
@Override
public void onOpen(ServerHandshake serverHandshake) {
short httpStatus = serverHandshake.getHttpStatus();
}
@Override
public void onMessage(String message) { // getting a json string with the data needed to fill the layout
try {
final JSONObject jsonObj = new JSONObject(message);
JsonHelper jsonHelper = new JsonHelper(jsonObj);
if (jsonHelper.isEvent("selectGroups")) {
JSONArray list = jsonHelper.getList();
for (int i = 0; i < list.length(); i++) {
JSONObject jsonGroup = (JSONObject) list.get(i);
final Button button = new Button(jsonGroup.getString("id") + ": " + jsonGroup.getString("name"));
button.setData(jsonGroup.getString("id"));
button.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(Button.ClickEvent clickEvent) {
try {
... // generate a json object to send to the server
client.send(jsonHelperClick.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
});
layoutLeft.addComponent(button); // adding the group as a button to the left side of the layout
}
// problem could be solved with push()
return;
}
if (jsonHelper.isEvent("availableContacts")) {
layoutRight.removeAllComponents();
JSONArray list = jsonHelper.getList(); // getting the list of all contacst from the phone
for (int i = 0; i < list.length(); i++) {
JSONObject jsonContact = (JSONObject) list.get(i);
HorizontalLayout rowContact = new HorizontalLayout();
... // filling the row representing the contact
layoutRight.addComponent(rowContact); // adding a contactrow to the right side of the layout
}
// problem could be solved with push()
// at this point i already see the right data added to layoutRight, but at the end still the old data is shown, not the new one
// layoutRight.requestRepaint(true);
// layoutRight.setImmediate(true);
// layoutRight.beforeClientResponse(true);
// layoutMain.requestRepaint(true);
// layoutMain.setImmediate(true);
//layoutMain.beforeClientResponse(true);
}
} catch (JSONException e) {
String message1 = e.getMessage();
e.printStackTrace();
}
}
};
client.setClientListener(clientListener);
client.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
编辑:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
id="WebApp_ID" version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>VaadinApplicationServlet</servlet-name>
<servlet-class>
com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>at.richardlederer.RemoteSms</param-value>
</init-param>
<!-- Enable server push -->
<init-param>
<param-name>pushmode</param-name>
<param-value>manual</param-value>
</init-param>
<async-supported>false</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>VaadinApplicationServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
编辑: 我将pushmode更改为手动,因此只有在我调用push()方法时才会发生更改。
答案 0 :(得分:0)
您需要在vaadin应用程序中enable server push。
稍后调用onMessage回调处理程序, 当应用程序收到json数据时。 然后,这将更新服务器端的UI状态。
当浏览器端的下一次交互完成后, 然后将所有服务器端更新发送到浏览器。
启用它很简单:
@Push
public class PushyUI extends UI {
答案 1 :(得分:0)
在组件填充后调用方法push()解决了问题