Как я могу отобразить ClickableTextCell как якорь в GWT CellTable? - PullRequest
5 голосов
/ 14 января 2011

У меня есть CellTable с несколькими столбцами в простых TextCell (). Два из столбцов «кликабельны» с помощью класса ClickableTextCell (), но я хочу изменить их внешний вид. Какой самый простой способ получить содержимое ячейки, похожее на тег привязки, при этом используя ячейку в таблице?

Я пробовал следующее: 1. Реализовать пользовательский рендер для добавления тегов привязки. 2. Обыскивая Google в поисках подсказок 3. Не обращая внимания на то, что «моя библиотека делает это, нужно просто изменить всю структуру». 4. Катаюсь головой по клавиатуре

Забавно, как раздражает это простое изменение.

Моя текущая мысль - реализовать собственный тип AnchorCell, который вставляет виджет Anchor вместо того, что он делает в других, но я не уверен, что все должно быть сделано.

Любая помощь приветствуется.

Ответы [ 8 ]

8 голосов
/ 17 января 2011

В качестве примера:

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 (более мощный, но требует большего объяснения).Спроси меня, если тебе это нужно!

5 голосов
/ 06 августа 2011

Упомянутое решение имеет проблему, это не ссылки и таблицы стилей с: 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();
        }
    }
};

Создает настоящую якорную ячейку, на которую можно кликать :)

4 голосов
/ 21 марта 2013

Казалось бы, ваш первый инстинкт (реализация пользовательского рендерера) намного проще:

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 голосов
/ 16 июля 2014

Это на самом деле довольно просто, но удивительно, как много неправильных и запутанных ответов есть в 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();
        }
    };
}    

Измените объект на то, что вы пытаетесь отобразить в таблице, затем запустите этот метод при создании столбца, просто!

3 голосов
/ 12 июня 2012

Это то, что вам нужно:

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());

        }
    });
0 голосов
/ 28 ноября 2015

Перво-наперво - каждый столбец GWT CellTable - это просто набор ячеек, так как нам нужно, чтобы каждая ячейка выглядела как якорь, который может прослушивать событие Click, что позволяет предоставлять ClickableTextCell в качестве аргумента для Column.

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

2nd - переопределите метод render () в вашем экземпляре Column и создайте нужный HTML-шаблон, здесь нам нужно создать привязку.

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

3-ий - поскольку мы используем 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, «Имя»);

0 голосов
/ 01 июля 2015

По сути, это взломать 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).

0 голосов
/ 14 января 2011

Если вы посмотрите HTML-код clickableTextCell, сгенерированный gwt, вы увидите что-то вроде (взято из 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;

}
...