且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

GWT单元格小部件与覆盖类型问题

更新时间:2023-12-03 11:35:04

这个问题的正确答案发布在GWT开发论坛(


$ h属性来自

实现JavaScriptObject#hashCode()(in
com.google.gwt.cire.client.impl.Impl#getHashCode(Object))。

在你的情况下,这是由于
AbstractEditableCell维护一个映射
的值为他们的视图数据,
和您使用(我猜)默认
的ProviderKey实现
(SimpleProvidesKey),它直接$ b $因此,在渲染时,EditTextCell
调用getViewData,它在地图中查找
键(因此需要密钥的
哈希码,因此调用
hashCode),关键是你r JSO
(因此是新的$ H属性)。

我相信给一个ProvideKey
实现(在你的情况下,返回
例如名称属性)到
Celltable将解决您的问题。



I have taken the Cell Table example from google developer's guide and made the following changes:

  • Use overlays instead of Java POJOs
  • Use a EditTextCell to edit one column

For my surprise, when running the code the Cell Table is adding an extra property to the overlay objects pushed into it. They should look like:

{"name":"John", "address":"123 Fourth Road"} {"name":"Mary", "address":"222 Lancer Lane"}

But instead they look like:

{"name":"John", "address":"123 Fourth Road", "$H":1} {"name":"Mary", "address":"222 Lancer Lane", "$H":2}

Here is the modified code that demonstrates the issue:

import java.util.Arrays;
import java.util.List;

import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Overlay implements EntryPoint {

    private static class Contact extends JavaScriptObject {

        protected Contact() {}

        public static native Contact create(String name, String address) /*-{
            return {"name" : name , "address" : address};
        }-*/;
        public final native String getName() /*-{
            return this["name"];
        }-*/;   
        public final native void setName(String name) /*-{
            this["name"] = name;
        }-*/;
        public final native String getAddress() /*-{
            return this["address"];
        }-*/;   
        public final native void setAddress(String address) /*-{
            this["address"] = address;
        }-*/;
    }

    private static List<Contact> CONTACTS = Arrays.asList(
            Contact.create("John", "123 Fourth Road"),
            Contact.create("Mary", "222 Lancer Lane"));

    /**
     * This is the entry point method.
     */
    public void onModuleLoad() {

        CellTable<Contact> table = new CellTable<Contact>();
        // Create name column.
        Column<Contact, String> nameColumn = new Column<Contact, String>(new EditTextCell()) {
            public String getValue(Contact object) {
                return object.getName();
            }
        };
        // Create address column.
        TextColumn<Contact> addressColumn = new TextColumn<Contact>() {
            public String getValue(Contact contact) {
                return contact.getAddress();
            }
        };
        // Add the columns.
        table.addColumn(nameColumn, "Name");
        table.addColumn(addressColumn, "Address");      
        table.setRowCount(CONTACTS.size(), true);
        // Push the data into the widget.
        printList();
        table.setRowData(0, CONTACTS);      
        printList();        
        RootPanel.get().add(table);
    }

    private void printList() {
        for(Contact contact : CONTACTS) {
            GWT.log(new JSONObject(contact).toString());
        }
    }

}

I have checked that it is the editable column the one that causes the issue. If I remove it the table does not modify my overlays.

Anyway, this is a very weird behaviour. I don't feel it is safe to work with overlays if your widgets can add them unexpected properties.

Has anyone encountered this issue before or is this behaviour documented anywhere? Any hints to solve it?

Thanks a lot

The correct answer to this issue was posted in the GWT development forum (link):

The $H property comes from the implementation of JavaScriptObject#hashCode() (in com.google.gwt.cire.client.impl.Impl#getHashCode(Object)).

In your case, this is due to AbstractEditableCell maintaining a map of value keys to their "view data", and your use (I guess) of the default ProvidesKey implementation (SimpleProvidesKey) which directly returns the item.

So, when rendering, the EditTextCell calls getViewData, which looks up the key in the map (and thus needs the hashcode of the key, hence the call to hashCode), and the key is your JSO (hence the new $H property).

I believe that giving a ProvidesKey implementation (in you case, returning the name property for instance) to the Celltable would solve your issue.