How can I wrap the text inside the GWT CellTable cell? - gwt

I need to wrap the text of the column. My column size is small. So if i set column width some of the letters are not visible. Since the length of the text is bigger than the column size. If there is a space in the text then it wraps itself. So I need to wrap the text.
For example, emailColumn it's value is xxxxxxxxxxxxx#XXXXXXX.com.
I expect the result as xxxxxxxxxxx#x in the first line and xxxx.xom in the next line.
Is it possible?

I tried wrap text inside cell table, we can achieve this by creating custom column.
Create one abstract cell column for cell table,append html contant in that cell and add column to cell table like this.
Add this code in your main java file, which contains cell table and paste below code in neccessary place.
WrappedColumn<T> textDetail = new WrappedColumn<T>() {
// This is method in wrapped details column java file.
public WrapDetails getValue(T object) {
return new WrapDetails( T.<your method1 for wrap text>(), T.<your method2 for wrap text>());
}
};
<your cell table>.addColumn(textDetail);
Create new java file named like 'WrapDetails.java' for render dynamic data and paste below code.
public class WrapDetails extends Composite {
String mail_id;
String website;
public WrapDetails(String id, String site) {
this.mail_id = id;
this.website = site;
}
}
Create new java file for wrap text column with named 'WrappedColumn.java' and paste below code.
public abstract class WrappedColumn<T> extends Column<T, WrapDetails> {
public WrappedColumn() {
super(new WrapDetailsColumnCell());
}
/**
* Return the passed-in object.
* #param object The value to get
*/
#Override
public WrapDetails getValue(T object) {
return null;
}
}
Create new java file named as 'WrapDetailsColumnCell.java' and paste below code.
public class WrapDetailsColumnCell extends AbstractCell<WrapDetails> implements Cell<WrapDetails>{
String mail_id, website;
/**
* Add this constructor, if you want click event for this column.
*/
public WrapDetailsColumnCell() {
super("click", "keydown");
}
/**
* This method provides style for your wrap data
*
*/
#Override
public void render(Context context, WrapDetails value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant("<div><table width='100%'>");
sb.appendHtmlConstant("<tr><td><div style='your style here'>"+mail_id+"</div></td></tr>");
sb.appendHtmlConstant("<tr><td><div style='your style here'>"+website+"</div></td></tr>");
sb.appendHtmlConstant("</table></div>");
}
/**
* This method update cell value on click event.
*
*/
#Override
public void onBrowserEvent(Context context, Element parent,WrapDetails value, NativeEvent event, ValueUpdater<FaxDetails> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
setValue(context, parent, value);
valueUpdater.update(value);
}
}
It is working for me well. After tried this, let me know any issue if you get. Have a fun.

Related

I want to attach a widget to a cell built using TableCellBuilder in GWT . How do I do it?

I have a table declared and initialised in the following manner
TableRowBuilder detailCell;
detailCell = startRow();
TableCellBuilder td = detailCell.startTD();
Now I have an anchor declared and initialised in the following manner
Anchor removeAnchor = new Anchor(rowValue);
removeAnchor.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent arg0) {
Window.alert("clicked");
}
});
td.html(new SafeHtmlBuilder().appendHtmlConstant(removeAnchor.toString()).toSafeHtml());
detailCell.endTD();
Because I am not directly appending that anchor to the cell , the click event is not being handled. What I want is to append the anchor to the cell.How do I do it?
How about using JSNI
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#calling
public void onModuleLoad() {
exportStaticMethod();
HTML html=new HTML("<a onclick='doAlert()'>hello</a>");
RootPanel.get().add(html);
}
public final static void doAlert(){
Window.alert("hello");
}
public static native void exportStaticMethod() /*-{
$wnd.doAlert =
$entry(#com.akjava.gwt.test2.client.GWTTest2::doAlert());
}-*/;
It's not the use case of the CellTable.
You can create a custom Cell for your use case :
http://www.gwtproject.org/doc/latest/DevGuideUiCustomCells.html
static class AnchorCell extends AbstractCell<String> {
/**
* The HTML templates used to render the cell.
*/
interface Templates extends SafeHtmlTemplates {
/**
* The template for this Cell, which includes a balise.
*
* #param value the safe value. Since the value type is {#link SafeHtml},
* it will not be escaped before including it in the template.
* Alternatively, you could make the value type String, in which
* case the value would be escaped.
* #return a {#link SafeHtml} instance
*/
#SafeHtmlTemplates.Template("<a href=\"javascript:;\">{0}</div>")
SafeHtml cell(SafeHtml value);
}
/**
* Create a singleton instance of the templates used to render the cell.
*/
private static Templates templates = GWT.create(Templates.class);
public AnchorCell() {
/*
* Sink the click and keydown events. We handle click events in this
* class. AbstractCell will handle the keydown event and call
* onEnterKeyDown() if the user presses the enter key while the cell is
* selected.
*/
super("click", "keydown");
}
/**
* Called when an event occurs in a rendered instance of this Cell. The
* parent element refers to the element that contains the rendered cell, NOT
* to the outermost element that the Cell rendered.
*/
#Override
public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event,
ValueUpdater<String> valueUpdater) {
// Let AbstractCell handle the keydown event.
super.onBrowserEvent(context, parent, value, event, valueUpdater);
// Handle the click event.
if ("click".equals(event.getType())) {
// Ignore clicks that occur outside of the outermost element.
EventTarget eventTarget = event.getEventTarget();
if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
doAction(value, valueUpdater);
}
}
}
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
/*
* Always do a null check on the value. Cell widgets can pass null to
* cells if the underlying data contains a null, or if the data arrives
* out of order.
*/
if (value == null) {
return;
}
// If the value comes from the user, we escape it to avoid XSS attacks.
SafeHtml safeValue = SafeHtmlUtils.fromString(value);
SafeHtml rendered = templates.cell(safeValue);
sb.append(rendered);
}
/**
* onEnterKeyDown is called when the user presses the ENTER key will the
* Cell is selected. You are not required to override this method, but its a
* common convention that allows your cell to respond to key events.
*/
#Override
protected void onEnterKeyDown(Context context, Element parent, String value, NativeEvent event,
ValueUpdater<String> valueUpdater) {
doAction(value, valueUpdater);
}
private void doAction(String value, ValueUpdater<String> valueUpdater) {
// Alert the user that they selected a value.
Window.alert("You clicked on " + value);
// Trigger a value updater. In this case, the value doesn't actually
// change, but we use a ValueUpdater to let the app know that a value
// was clicked.
valueUpdater.update(value);
}
}

GWT Cell Tree Right Click Selection

So I have created a CellTree and what I want to do is select the cell that receives a right click so that when I open my context menu to do things, I will know what cell I am working with. Maybe I am going about it the wrong way, I can override the onBrowserEvent method and detect when someone right clicks on the tree but I can't figure out which cell is being clicked so I can manually select it. Has anyone found a solution for this problem?
The solution consists of two steps:
1)
Add a TreeViewModel to the constructor of your CellTree. With that model you can set the names of your elements in the tree. Here is a simple implementation from the API:
private static class CustomTreeModel implements TreeViewModel {
/**
* Get the {#link NodeInfo} that provides the children of the specified
* value.
*/
public <T> NodeInfo<?> getNodeInfo(T value) {
/*
* Create some data in a data provider. Use the parent value as a prefix
* for the next level.
*/
ListDataProvider<String> dataProvider = new ListDataProvider<String>();
for (int i = 0; i < 2; i++) {
dataProvider.getList().add(value + "." + String.valueOf(i));
}
// Return a node info that pairs the data with a cell.
return new DefaultNodeInfo<String>(dataProvider, new TextCell());
}
/**
* Check if the specified value represents a leaf node. Leaf nodes cannot be
* opened.
*/
public boolean isLeaf(Object value) {
// The maximum length of a value is ten characters.
return value.toString().length() > 10;
}
}
2) When you receive the right click Event, get the EventTarget name and compare it with the name of that item you set using the model.
I found a solution, I hope this helps others as I have been searching for this for a long time. There might be a better way, but here is how I accomplished the functionality that I desired:
In the cells that I used inside my tree, I did an override on the onbrowserevent to catch the mouse events and set the selection model. With abstract cells you can sink events you want it to listen to and in my case I chose mouse down.
public class CustomContactCell extends AbstractCell<ContactInfo> {
private SetSelectionModel<ContactInfo> selectionModel;
public CustomContactCell(SetSelectionModel<ContactInfo> selectionModel) {
super("mousedown");
this.selectionModel = selectionModel;
}
#Override
public void render(Context context, ContactInfo value, SafeHtmlBuilder sb) {
...
}
#Override
public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent, ContactInfo value, NativeEvent event, ValueUpdater<ContactInfo> valueUpdater) {
if (event.getButton() == NativeEvent.BUTTON_RIGHT) {
if (selectionModel != null) {
selectionModel.clear();
selectionModel.setSelected(value, true);
}
}
super.onBrowserEvent(context, parent, value, event, valueUpdater);
}
}

GWT Header CheckBox requires two clicks to fire setValue, after changing its value programatically

I have a GWT DataGrid, and a CheckBox in the Header to select/deselect all rows in the grid.
The code for the CheckBox Header is as follows:
private class CheckboxHeader extends Header<Boolean> implements HasValue<Boolean> {
private boolean checked;
private HandlerManager handlerManager;
/**
* An html string representation of a checked input box.
*/
private final SafeHtml INPUT_CHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\" checked/>");
/**
* An html string representation of an unchecked input box.
*/
private final SafeHtml INPUT_UNCHECKED = SafeHtmlUtils.fromSafeConstant("<input type=\"checkbox\" tabindex=\"-1\"/>");
#Override
public void render(Context context, SafeHtmlBuilder sb) {
if (Boolean.TRUE.equals(this.getValue())) {
sb.append(INPUT_CHECKED);
} else {
sb.append(INPUT_UNCHECKED);
}
};
public CheckboxHeader() {
super(new CheckboxCell(true, false));
checked = true;
}
// This method is invoked to pass the value to the CheckboxCell's render method
#Override
public Boolean getValue() {
return checked;
}
#Override
public void onBrowserEvent(Context context, Element elem, NativeEvent nativeEvent) {
int eventType = Event.as(nativeEvent).getTypeInt();
if (eventType == Event.ONCHANGE) {
nativeEvent.preventDefault();
// use value setter to easily fire change event to handlers
setValue(!checked, true);
}
}
#Override
public HandlerRegistration addValueChangeHandler(ValueChangeHandler<Boolean> handler) {
return ensureHandlerManager().addHandler(ValueChangeEvent.getType(), handler);
}
#Override
public void fireEvent(GwtEvent<?> event) {
ensureHandlerManager().fireEvent(event);
}
#Override
public void setValue(Boolean value) {
setValue(value, true);
}
#Override
public void setValue(Boolean value, boolean fireEvents) {
checked = value;
if (fireEvents) {
ValueChangeEvent.fire(this, value);
}
}
private HandlerManager ensureHandlerManager() {
if (handlerManager == null) {
handlerManager = new HandlerManager(this);
}
return handlerManager;
}
}
So, I add the Header to the grid, and I add a ValueChangeHandler to it to do the actual selecting/deselecting of individual CheckBox cells in every row of the grid. This all works.
Every CheckBoxCell has a Field Updater, and on every update it loops through every item in the grid to see if they are all checked, and update the header check box. If at least one is unchecked, the header checkbox will be unchecked. I call setValue() on the header check box, and after that I call redrawHeaders() on the entire grid. This also works.
What doesn't work is - after changing the "state" of the header check box programatically, it takes two clicks for it to fire it's internal setValue again, and therefore trigger my handler. And what's even funnier - the first click does change the state of the check box, but it just doesn't fire the event.
Any help would be appreciated.
How are you constructing the CheckboxCells themselves? I ran into a similar issue with a column of checkboxes "eating" clicks, and the solution was to call CheckboxCell cell = new CheckboxCell(true,true) and then pass that cell into the constructor of the column.

GWT CellTable, disable ButtonCell when clicked

I'm pretty new to GWT, but I've been making pretty fast progress until now.
I have a cell table, most of which is read only data returned from an RPC.
I have two columns in the cell table that the user can interact with. One is a TextInputCell, one is a ButtonCell.
When the user clicks the ButtonCell, i want to send the value in the TextInputCell for that row to an RPC.
I have all this working.
The part I cannot get to work is that when the button (ButtonCell) is clicked, I want to disable the button in that row until the RPC returns, and then re-enable it. I also want to clear the text in the input cell for that row when the RPC returns.
I cannot figure out how to get handles to the actual ButtonCell object that was clicked or the TextInputCell to monkey with them.
Any help appreciated.
bq
The problem is that there's no object for the button that was clicked. Your ButtonCell creates HTML that renders buttons - every button in the whole column was written by the same button cell, but there's no java object associated with them.
To disable the button directly, you'll have to first create a handle to it. You could do this by rendering an id in the html your ButtonCell creates, and then getting the element by id from the DOM.
What I do in a similar case is just re-render the entire table when there's a state change. It doesn't take that long, and you don't need to store any references (the whole reason you're using CellTable instead of Grid anyway). When you know your button should be disabled, you just render it disabled.
Both of these suggestions would require you to subclass your Cell objects so that you can do some custom rendering. It's not very difficult, but wrapping your head around the order of operations can be confusing. Good luck!
PS: If you just want to disable the button (and not empty the text field), I think onBrowserEvent gives you a handle to the Element that was clicked - you might be able to use that to disable it.
I have gone through this problem, but eventually I solved it.
check this code
package com.ex7.client;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
public class CWButton extends ButtonCell {
private int row = -1;
private String alternativevalue;
private String exTitle = "";
private String value;
private String title = "";
public CWButton( ) {
super();
}
#Override
public void render(com.google.gwt.cell.client.Cell.Context context,
String src, SafeHtmlBuilder sb) {
if (row == -1) {
sb.appendHtmlConstant("<button title='" + title + "' >" +value+"</button>");
return;
}
if (row != context.getIndex()) {
sb.appendHtmlConstant("<Button disabled='disabled' title='" + title + "' >"+ value+"</button>");
} else {
sb.appendHtmlConstant("<button title='" + exTitle + "' >"+ alternativevalue+"</button>");
}
}
#Override
public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context,
Element parent, String value, NativeEvent event,
ValueUpdater<String> valueUpdater) {
if (row == -1 || row == context.getIndex()) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
return;
}
}
public void setTitle(String title) {
this.title = title;
}
public int getRow() {
return row;
}
public String getExTitle() {
return exTitle;
}
public void setExTitle(String exTitle) {
this.exTitle = exTitle;
}
public void setRow(int row) {
this.row = row;
}
public String getAlternativeValue() {
return alternativevalue;
}
public void setAlternativeValue(String alternativeValue) {
this.alternativevalue = alternativeValue;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

gwt celltable: Possible to only make some cells in a column editable?

I'm using GWT 2.4. When using a CellTable, I've seen its possible to add a column in which all of the cells are editable ...
final TextInputCell nameCell = new TextInputCell();
Column<Contact, String> nameColumn = new Column<Contact, String>(nameCell) {
#Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");
but what if I don't want every cell in the column to be editable, only specific ones, based on properties in my "Contact" object? How would I set this up? Thanks, - Dave
The way I would do it is extend the TextInputCell and override the render method to render something else, if you don't want the value in that particular row editable.
Something like this:
public class MyTextInputCell extends TextInputCell {
#Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
YourObject object = getYourObject();
if ( object.isThisCellEditable() ) {
super.render(context,value,sb);
} else {
sb.appendEscaped(value); // our some other HTML. Whatever you want.
}
}
}
In the render method you have access to the cell's context. Context.getIndex() returns the absolute index of the object. I can't remember of the top of my wad right now, but if you do not provide a ProvidesKey implementation when creating your CellTable you will get one that will use the object itself as the key. So you can get the object using Context.getKey().