• GWT异步更改cellTable中cell的数据显示


      项目中遇到一个棘手的问题,使用GWT的cellTable的时候,要更改一个单元格的显示问题。如果仅仅是一个单独的cell 可能会有比较好的处理办法,比如可以找到这一列,然后更新整个cellTable,但此处我用到的是一个复合cell,即compositeCell,API如下:

      

    1 public class CompositeCell<C>
    2 extends AbstractCell<C>
    3 A Cell that is composed of other Cells.
    4 
    5 When this cell is rendered, it will render each component Cell inside a span. If the component Cell uses block level elements (such as a Div), the component cells will stack vertically.

      所以要取到具体的cell有些不易。

      此次更改cell的情景是: 一个entity中字段没有关联到实体,而是存储的一个实体的ID,但是cellTable显示的时候,不可能显示一个关联ID的,而是需要根据这个ID去查找该关联实体的表,而此处的查询又是异步的。

      首先思路是这样的: 第一步肯定是要先取得要更改数据的那一列的;第二步取到具体的那一个cell; 第三步就是更改cell里面的数据了。

      这里的cell 需要使用样式,所以代码是这样的:

     1 final Cell<String> cell = new TextCell(new SafeHtmlRenderer<String>() {
     2             
     3             @Override
     4             public void render(String arg0, SafeHtmlBuilder arg1) {
     5             }
     6             
     7             @Override
     8             public SafeHtml render(String str) {
     9                 return new SafeHtmlBuilder().appendHtmlConstant("<span class='categoryName'>"+str+"</span>").toSafeHtml();
    10             }
    11         });

    会被渲染加上一个class为"categoryName"的span 标签。

      首先查找出这个cell,这里关键代码如下:

      

     1 int index = dataProvider.getList().indexOf(item);
     2 NodeList<TableCellElement> nodeList = entityTable.getRowElement(index).getCells();
     3 for (int i = 0; i < nodeList.getLength(); i++) {
     4    TableCellElement tableCellElement =  nodeList.getItem(i);
     5    List<Element> elements = getRowElements(tableCellElement);
     6    for (Element element : elements) {
     7         String className = element.getClassName();
     8         if(className!=null && className.equals("categoryName")){
     9              element.setInnerHTML(caterotyString + "&nbsp;&nbsp;");
    10          }
    11       }
    12    elements.clear(); //每次循环完一列就清空保存元素的集合
    13  }

      每个cellTable 都需要一个dataProvider来显示数据,一条数据为一行,那么可以根据这个dataProvider中存放数据的位置来确定此数据是第几行的,这样就实现了上面说的第一步操作。代码中第2行根据行数取得这一行的所有单元格元素,第3行代码是取得每一个单元格中的元素。这样做的话就能解析那些复合单元格中每个单元格了。实现了上面所说的第二步操作。在取得所有的元素之后,我们可以利用刚刚设置的class名字来定位到精确的元素, 也可以根据node的id。因为有复合控件的存在,可能存在要解析遍历多次的问题,所以第5行代码使用了一个递归循环,取得所有的元素,代码如下:

     1     // 递归取得每一列中的所有元素,包括自身
     2     private List<Element> elements = new ArrayList<Element>();
     3     private List<Element> getRowElements(Element element){
     4         elements.add(element);
     5         NodeList<Node> nodes = element.getChildNodes();
     6         for (int i = 0; i < nodes.getLength(); i++) {
     7             Node node = nodes.getItem(i);
     8             Element childElement = node.cast();
     9             if(childElement.getChildCount()>0){
    10                 getRowElements(childElement);
    11             }else{
    12                 elements.add(childElement);
    13             }
    14         }
    15         return elements;
    16     }

    其中第8行代码中使用了一个cast方法,cast方法的API如下:

    1 <T extends JavaScriptObject> T
    2 cast() 
    3           A helper method to enable cross-casting from any JavaScriptObject type to any other JavaScriptObject type.

    是对JavaScriptObject类进行互相转换的,Element和Node 都是JavaScriptObject的子类。继承关系如下:

      

    1 java.lang.Object
    2   extended by com.google.gwt.core.client.JavaScriptObject
    3       extended by com.google.gwt.dom.client.Node
    4           extended by com.google.gwt.dom.client.Element

    这里也可以不转换类型,而是在调用递归的地方使用,返回一个Node的List,然后在循环Node的时候进行cast操作,因为className只有Element才有,所以必须要转换。

    总结:gwt因为是用java写"html",所以提供了很多可以操作底层的类供我们使用,可以取得我们想要的"html"标签或者元素,善于发掘,就会找到我们想要的。

      

  • 相关阅读:
    Java 线程池概念、原理、简单实现
    Java 中的等待唤醒机制透彻讲解
    Java 多线程安全问题简单切入详细解析
    理解 Java 多线程
    Java 异常的处理
    Android MediaPlayer的生命周期
    Node.js 撸第一个Web应用
    Android简易实战教程--第三十四话《 自定义SeekBar以及里面的一些小知识》
    使用Intent传递对象
    Android 异步查询框架AsyncQueryHandler的使用
  • 原文地址:https://www.cnblogs.com/bigbang92/p/gwt-update-compositeCell.html
Copyright © 2020-2023  润新知