Как я могу отобразить ClickableTextCell в качестве привязки в CellTable GWT?

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

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

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

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

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


person Kieveli    schedule 14.01.2011    source источник


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

person ramon_salla    schedule 17.01.2011
comment
Я еще не вернулся к этому! Выглядит многообещающе! Спасибо! - person Kieveli; 21.01.2011
comment
Где действие по клику? Это кажется неполным ответом. - person Robert; 28.12.2016

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

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

person thomas    schedule 06.08.2011
comment
О, какой спасатель!! - person user949110; 05.10.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();
        }
    };
person Marcelo    schedule 21.03.2013

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

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

        }
    });
person Arash    schedule 11.06.2012
comment
Без href и якоря он отображается только в виде синего текста в Chrome. href, предложенный @thomas из href='javascript:;' кажется, помогает. - person David Mann; 08.02.2013

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

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

person Ben    schedule 16.07.2014
comment
Вы захотите использовать anchor.getElement().getString()- у меня есть вывод отладки Javascript с a.toString() - person J. Dimeo; 18.08.2014

Если вы посмотрите на html-код clickableTextCell, сгенерированный gwt, вы увидите что-то вроде (взято из демонстрации gwt)

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

Поэтому я рекомендую вам сделать что-то вроде:

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

а в style.css делай что хочешь.

.yourStyle div{

text-decoration:underline;

}
person ramon_salla    schedule 14.01.2011
comment
Только у ClickableTextCell нет такого метода. - person Kieveli; 17.01.2011
comment
Извините, я не имел в виду, что вы можете использовать его напрямую. Вам нужно создать собственную реализацию ClickableTextCell. Переопределите onRender() и выполните sb.append(‹div›);s - person ramon_salla; 17.01.2011

По сути, это хак для использования 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());
}

Я только что столкнулся со случаем, когда ячейка привязки работала нормально в режиме суперразработчика, но ее компиляция (вероятно, с более агрессивными настройками оптимизации), а затем ее развертывание вручную приводили к совершенно пустой ячейке без каких-либо изменений в коде, воспроизводимых в нескольких системах. Использование описанного выше механизма шаблонов заставило его работать правильно (GWT 2.7).

person f4lco    schedule 01.07.2015

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

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

2-й — переопределите метод «render ()» в вашем экземпляре столбца и создайте свой 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 (столбец, «Имя»);

person BeingSuman    schedule 28.11.2015