如何将ClickableTextCell渲染为GWT CellTable中的锚点?

时间:2011-01-14 13:58:23

标签: gwt anchor cell

我在简单的TextCell()中有一个包含多列的CellTable。其中两列是通过ClickableTextCell()类“可点击”的,但我想改变它们的外观。什么是使单元格内容类似于锚标记的最简单方法,同时仍然使用表格中的单元格?

我尝试过以下方法:   1.实现自定义渲染器以添加锚标记   2.搜索谷歌寻找提示   3.忽略'我的库做它你只需要改变你的整个框架'链接   4.将头转过他们的键盘

有趣的是,这个简单的改变是多么令人讨厌。

我目前的想法是实现一个自定义的AnchorCell类型,它放入一个Anchor小部件,而不是它在其他小部件中做的任何事情,但我不确定需要做什么。

感谢任何帮助。

8 个答案:

答案 0 :(得分:8)

举个例子:

public class MyClickableCellText extends ClickableTextCell {

    String style;   
    public MyClickableCellText()
    {
        super();
        style = "myClickableCellTestStyle";
    }


     @Override
      protected void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
        if (value != null) {
          sb.appendHtmlConstant("<div class=\""+style+"\">");
          sb.append(value);
          sb.appendHtmlConstant("</div>");
        }
      }

     public void addStyleName(String style)
     {
         this.style = style; 
     }


}

风格(没有div,因为你正在硬编码风格):

.myClickableCellTestStyle{
    text-decoration:underline;

}

您甚至可以通过不扩展ClickableTextCell但扩展AbstractCell来创建自己的单元格(更强大但需要更多解释)。问你是否需要它!

答案 1 :(得分:5)

提到的解决方案有问题,这些都没有链接和样式表:hover等等不起作用。

这是我的解决方案:

private class SellerName {
    private final String sellerName;
    private final Command cmd;

    private SellerName(String displayName, Command cmd) {
      this.sellerName = displayName;
      this.cmd = cmd;
    }

    public String getDisplayName() {
      return sellerName;
    }

    public Command getCommand() {
        return cmd;
    }
};

private class SellerNameCell extends AbstractCell<SellerName> {

    public SellerNameCell() {
        super("click", "keydown");
    }

    @Override
    public void render(com.google.gwt.cell.client.Cell.Context context, SellerName value, SafeHtmlBuilder sb) {
         if (value != null) {
             sb.appendHtmlConstant("<a href='javascript:;'>");
             sb.appendEscaped(value.getDisplayName());
             sb.appendHtmlConstant("</a>");
         }
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, SellerName value, NativeEvent event, ValueUpdater<SellerName> valueUpdater) {
        if (value == null)
            return;

        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if ("click".equals(event.getType())) {
            if (value.getCommand() != null)
                value.getCommand().execute();
        }
    }
};

它创建了一个可点击的真实锚单元:)

答案 2 :(得分:4)

您的第一直觉(实现自定义渲染器)似乎更容易:

SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>()
    {
        @Override
        public SafeHtml render(String object) {
            SafeHtmlBuilder sb = new SafeHtmlBuilder();
            sb.appendHtmlConstant("<a href=\"javascript:;\">")
                    .appendEscaped(object).appendHtmlConstant("</a>");
            return sb.toSafeHtml();
        }
    };

然后:

Column<YourThingy, String> anchorCol = new Column<YourThingy, String>(
            new ClickableTextCell(anchorRenderer))
    {

        @Override
        public String getValue(YourThingy object) {
            return object.toString();
        }
    };

答案 3 :(得分:3)

这就是你需要的:

public class ClickableSafeHtmlCell extends AbstractCell<SafeHtml> {
/**
 * Construct a new ClickableSafeHtmlCell.
 */
public ClickableSafeHtmlCell() {
    super("click", "keydown");
}

@Override
public void onBrowserEvent(Context context, Element parent, SafeHtml value, NativeEvent event,
        ValueUpdater<SafeHtml> valueUpdater) {
    super.onBrowserEvent(context, parent, value, event, valueUpdater);
    if ("click".equals(event.getType())) {
        onEnterKeyDown(context, parent, value, event, valueUpdater);
    }
}

@Override
protected void onEnterKeyDown(Context context, Element parent, SafeHtml value,
        NativeEvent event, ValueUpdater<SafeHtml> valueUpdater) {
    if (valueUpdater != null) {
        valueUpdater.update(value);
    }
}

@Override
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
    if (value != null) {
        sb.append(value);
    }
}

然后用法:

Column<YourProxy, SafeHtml> nameColumn = new Column<YourProxy, SafeHtml>(
        new ClickableSafeHtmlCell()) {
    @Override
    public SafeHtml getValue(YourProxy object) {
        SafeHtmlBuilder sb = new SafeHtmlBuilder();
        sb.appendHtmlConstant("<a>");
        sb.appendEscaped(object.getName());
        sb.appendHtmlConstant("</a>");
        return sb.toSafeHtml();
    }
};

nameColumn.setFieldUpdater(new FieldUpdater<YourProxy, SafeHtml>() {
        @Override
        public void update(int index, YourProxy object, SafeHtml value) {
             Window.alert("You have clicked: " + object.getName());

        }
    });

答案 4 :(得分:3)

这实际上非常简单,但令人惊讶的是Google上有多少错误和错综复杂的答案,而且似乎没有正确答案!无论如何,这里是代码:

private Column<Object, SafeHtml> getAnchorColumn() {
    return new Column<Object, SafeHtml>(new SafeHtmlCell()) {
        @Override
        public SafeHtml getValue(final Object object) {
            Anchor anchor = new Anchor();
            anchor.setHref(object.getURL());
            anchor.setText(object.getText());

            SafeHtmlBuilder sb = new SafeHtmlBuilder();
            sb.appendHtmlConstant(anchor.toString());
            return sb.toSafeHtml();
        }
    };
}    

将对象更改为您正在尝试在表格中渲染的任何内容,然后在创建列时运行此方法,这很简单!

答案 5 :(得分:0)

如果您查看gwt生成的clickableTextCell html代码,您会看到类似的内容(取自gwt showcase)

<div style="outline:none;" tabindex="0">Click Robert</div>

所以我建议你这样做:

ClickableTextCell cell = new ClickableTextCell();
cell.addStyleName("yourStyle");

在你的style.css做任何你想做的事。

.yourStyle div{

text-decoration:underline;

}

答案 6 :(得分:0)

使用appendHtmlConstant本质上是一种破解。简单地使用toString或其元素的Anchor或传递HTML字符串完全违反了SafeHtml背后的概念。

在我看来,应该使用正确的SafeHtmlTemplates来解决HTML的不可读和不安全的字符串连接问题。类似于:

protected interface AnchorTemplate extends SafeHtmlTemplates {
    @Template("<a href=\"{0}\">{1}</a>")
    SafeHtml anchor(String url, String text);
}

然后你可以在它上面使用GWT.create并正确插入参数。

第二部分是可以优化读取小部件的HTML字符串。我正在扩展AbstractCell并采用这种方法:

/* do not dare to copy - considered broken */
@Override
public void render(final Context context, final String value, final SafeHtmlBuilder sb) {
    final Anchor anchor = new Anchor();
    anchor.setText(value);
    sb.appendHtmlConstant(anchor.getElement().toString());
}

我刚刚经历过一个案例,其中锚单元在superdev模式下工作正常,但编译它(可能采用更积极的优化设置),然后手动部署它导致一个完全空的单元格,几个系统中的代码没有重复变化。使用上述模板机制使其正常工作(GWT 2.7)。

答案 7 :(得分:0)

首先 - 每个GWT CellTable列只是一个Cell的堆栈,因为我们需要使每个Cell看起来像一个可以监听Click事件的锚点,让ClickableTextCell作为Column的参数。

Column<YourObj, String> col = new Column<YourObj, String>(new ClickableTextCell()) {};

2nd - 覆盖Column实例中的“render()”方法并构建您想要的HTML模板,这里我们需要创建一个锚点。

@Override
        public void render(Context context, YourObj yourObj, SafeHtmlBuilder sb) {
            sb.appendHtmlConstant("<a style='text-decoration:underline; cursor: pointer;'>" + yourObj.getX() + "</a>");
        }

3rd - 因为我们正在使用ClickableTextCell,它用作Click事件源。我们需要提供ClickEvent监听器,我们通过覆盖“onBrowserEvent()”方法来实现。

@Override
        public void onBrowserEvent(Context context, Element elem, Customer customer, NativeEvent event) {
            if ("click".equals(event.getType())) {
                Window.alert("ID is : " + customer.getId());
            }
        }

完整的代码段:

Column<YourObj, String> col = new Column<YourObj, String>(new ClickableTextCell()) {

        @Override
        public String getValue(final YourObj yourObj) {
            return yourObj.getX();
        }

        @Override
        public void render(Context context, YourObj yourObj, SafeHtmlBuilder sb) {
            sb.appendHtmlConstant("<a style='text-decoration:underline; cursor: pointer;'>" + yourObj.getX() + "</a>");
        }

        @Override
        public void onBrowserEvent(Context context, Element elem, YourObj yourObj, NativeEvent event) {
            if ("click".equals(event.getType())) {
                Window.alert("ID is : " + yourObj.getId());
            }
        }
    };

cellTable.addColumn(col,“First Name”);