Adding a row-number column to GWT CellTable - gwt

I need to insert a new first-column into a CellTable, and display the RowNumber of the current row in it. What is the best way to do this in GWT?

Get the index of the element from the list wrapped by your ListDataProvider. Like this:
final CellTable<Row> table = new CellTable<Row>();
final ListDataProvider<Row> dataProvider = new ListDataProvider<Starter.Row>(getList());
dataProvider.addDataDisplay(table);
TextColumn<Row> numColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return Integer.toString(dataProvider.getList().indexOf(object) + 1);
}
};
See here for the rest of the example.

Solution from z00bs is wrong, because row number calculating from object's index in data List. For example, for List of Strings with elements: ["Str1", "Str2", "Str2"], the row numbers will be [1, 2, 2]. It is wrong.
This solution uses the index of row in celltable for row number.
public class RowNumberColumn extends Column {
public RowNumberColumn() {
super(new AbstractCell() {
#Override
public void render(Context context, Object o, SafeHtmlBuilder safeHtmlBuilder) {
safeHtmlBuilder.append(context.getIndex() + 1);
}
});
}
#Override
public String getValue(Object s) {
return null;
}
}
and
cellTable.addColumn(new RowNumberColumn());

Related

Delete Multiple rows from Nattable

I am trying to delete more than one row from NatTable. Following the solution described in Delete rows from Nattable. I have created a the following classes:
the Command class looks like this :
public class DeleteMultiRowCommand extends AbstractMultiRowCommand {
public DeleteMultiRowCommand(AbstractMultiRowCommand command) {
super(command);
}
protected DeleteMultiRowCommand(ILayer layer, int[] rowPositions) {
super(layer, rowPositions);
}
#Override
public ILayerCommand cloneCommand() {
return new DeleteMultiRowCommand(this);
}
}
Command Handler class:
public class DeleteMultiRowCommandHandler<T> implements ILayerCommandHandler<DeleteMultiRowCommand> {
private List<T> bodyData;
private SelectionLayer layer;
public DeleteMultiRowCommandHandler(List<T> bodyData, SelectionLayer selectionLayer) {
this.bodyData = bodyData;
this.layer = selectionLayer;
}
public DeleteMultiRowCommandHandler(List<T> bodyData){
this.bodyData = bodyData;
}
#Override
public Class<DeleteMultiRowCommand> getCommandClass() {
return DeleteMultiRowCommand.class;
}
#Override
public boolean doCommand(ILayer targetLayer, DeleteMultiRowCommand command) {
//convert the transported position to the target layer
if (command.convertToTargetLayer(targetLayer)) {
Collection<Integer>rowpos = command.getRowPositions();
//remove the element
for(Integer val : rowpos){
this.bodyData.remove(val.intValue());
targetLayer.fireLayerEvent(new RowDeleteEvent(targetLayer, val.intValue()));
}
return true;
}
return false;
}
}
and the Command will be triggered on clicking a MenuItem
this.contextMenu = new PopupMenuBuilder(natTable)
.withInspectLabelsMenuItem()
.withClearAllFilters()
.withColumnRenameDialog()
.withMenuItemProvider(new IMenuItemProvider() {
#Override
public void addMenuItem(final NatTable natTable, Menu popupMenu) {
MenuItem deleteRow = new MenuItem(popupMenu, SWT.PUSH);
deleteRow.setText("Delete Row(s)");
deleteRow.setEnabled(true);
deleteRow.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
//int rowPosition = MenuItemProviders.getNatEventData(event).getRowPosition();
ILayer bl = ((GridLayer)natTable.getLayer()).getBodyLayer();
BodyLayerStack bl1 = (BodyLayerStack) bl;
SelectionLayer sl = bl1.getSelectionLayer();
int []poss = new int[sl.getFullySelectedRowPositions().length];
int i=0;
for(int pos1 : sl.getFullySelectedRowPositions()){
poss[i]=sl.getRowIndexByPosition(pos1);
i++;
}
//System.out.println("Menu item selected "+rowPosition);
//natTable.doCommand(new DeleteRowCommand(natTable, rowPosition));
natTable.doCommand(new DeleteMultiRowCommand(natTable, poss));
}
});
}
})
.build();
when I try to delete the rows, rows which not selected are deleted. Seems like an issue with the row postion to row index conversion. is the row postion to row index conversion correct within my IMenuItemProvider right ?
It seems like you do the conversion from position to index twice: once in the menu item selection listener and once in the command handler (by calling convertToTargetLayer). The first is not necessary.
That is not an issue of NatTable, but an issue on how to work with collections. You need to remove the items backwards if you remove the elements one by one. Otherwise the items for the indexes are changing while processing.
Let's assume you want to delete the elements at index 1 and 2. After removing the element at index 1, the elements below will move up. So the element that was before on index 2 will be on index 1 now, and the element at index 3 will be on index 2. Therefore the removal of the element at index 2 in the next iteration will remove the item that was before on index 3.
I'd suggest to sort and reverse the collection of indexes before iterating to remove items from the collection. Than it should work.

Hide Column in CellTable

How to hide the columns in Cell table? I need column for grouping purpose but don't want to show in table. Is there any way to hide? Any clue? See the below Code..
TextColumn<ContactInfor> ageTxt = new TextColumn<ContactInfor>() {
#Override
public String getValue(ContactInfor object) {
return object.age;
}
};
cellTable.addColumn(ageTxt, "AGE");
TextColumn<ContactInfor> empIdTxt = new TextColumn<ContactInfor>() {
#Override
public String getValue(ContactInfor object) {
return object.empId;
}
};
cellTable.addColumn(empIdTxt, "EMPLOYEE ID");
TextColumn<ContactInfor> addressTxt = new TextColumn<ContactInfor>() {
#Override
public String getValue(ContactInfor object) {
return object.address;
}
};
cellTable.addColumn(addressTxt, "ADDRESS");
Want to hide addressTxt column from cell table?
Assuming you can't actually remove it from the table, perhaps just set the width to 0:
cellTable.setColumnWidth(addressTxt, "0px");
Javadocs: http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/cellview/client/CellTable.html#setColumnWidth(com.google.gwt.user.cellview.client.Column,java.lang.String)

How to style specific cells in CellTable depending the value of that cell (GWT)?

Ok, i have a CellTable that has 3 columns and 2 rows. I want the text in SOME specific cells (not all cell) in the table to be BOLD.
Please look at this code:
ListDataProvider<List<String>> dataProvider = new ListDataProvider<List<String>>();
dataProvider.addDataDisplay(table);
List<List<String>> list = dataProvider.getList();
List<String> sublist1= Arrays.asList("223","546","698");
List<String> sublist2= Arrays.asList("123","876","898");
List<String> sublist2= Arrays.asList("123","896","438");
IndexedColumn column1=new IndexedColumn(0);
table.addColumn(column1, "Col1");
IndexedColumn column2=new IndexedColumn(1);
table.addColumn(column2, "Col2");
IndexedColumn column3=new IndexedColumn(2);
table.addColumn(column3, "Col3");
Now, I want the Cell that is the intersect of row2 & col3 (ie "898") to be BOLD, so if i do like this
column3.setCellStyleNames(getView().getRes().css().myBoldColor());
Then it will make the whole column BOLD.
So, i think properly we need to loop over each cell in column3 & set the style accordingly, so that we can have the result like this:
Col1 - Col2 - Col3
223 - 546 - 698
123 - 876 - 898
123 - 896 - 438
You can try it be extending AbstractCell also.
Read here about Implementing the render() Method.
Sample code:
static class BoldCell extends AbstractCell<String> {
/**
* The HTML templates used to render the cell.
*/
interface Templates extends SafeHtmlTemplates {
#SafeHtmlTemplates.Template("<div style=\"{0}\">{1}</div>")
SafeHtml cell(SafeStyles styles, SafeHtml value);
}
/**
* Create a singleton instance of the templates used to render the cell.
*/
private static Templates templates = GWT.create(Templates.class);
#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);
// Use the template to create the Cell's html.
FontWeight weight = FontWeight.NORMAL;
if (safeValue.asString().equals("898")) {
weight = FontWeight.BOLD;
}
SafeStyles styles = SafeStylesUtils.forFontWeight(weight);
SafeHtml rendered = templates.cell(styles, safeValue);
sb.append(rendered);
}
}
In above code you can try it with row no also (Bold value for 0th column of 3rd row)
...
FontWeight weight = FontWeight.NORMAL;
if (context.getIndex()==2) {
weight = FontWeight.BOLD;
}
...
Cell<String> cell = new BoldCell();
Column<Contact, String> nameColumn = new Column<Contact, String>(cell) {
#Override
public String getValue(Contact object) {
return object.name;
}
};
table.addColumn(nameColumn, "Name");
Override getCellStyleNames() for a column:
Column<Document, Date> dueColumn = new Column<Document, Date>(new DateCell(DateTimeFormat.getFormat(PredefinedFormat.MONTH_ABBR_DAY))) {
#Override
public Date getValue(Document document) {
return document.getDueDate();
}
#Override
public String getCellStyleNames(Context context, Document document) {
if (document.getDueDate().getTime() < new Date().getTime()) {
return "boldStyle";
}
};

GWT Celltable with data in map

I have my datas as a Map<Key,ArrayList<Value>> So i want my col1 to represent my key and the other columns to represent data in my values. And this Value can be or multiple rows. So i was thinking of putting a celltable inside a celltable but then it will affect my headers(since the number of columns for the outer celltable will be just 2) and also the sorting.
And also if i pass the map directly to ListDataProvider it assumes the number of rows is the number of rows of the map but it is not the case.
So what is the best way to do this ?
I'd suggest using a class RowObject like this:
class RowObject {
private final Key key;
private final Value value;
RowObject(Key key, Value value) {
this.key = key;
this.value = value;
}
/* Getters omitted */
}
Then convert the map to a list of RowObjects and feed the list to the data provider:
List<RowObject> rowObjects = new ArrayList<RowObject>();
for (Entry<Key, ArrayList<Value>> entry : map.entrySet()) {
for (Value value : entry.getValue()) {
rowObjects.add(new RowObject(entry.getKey(), value));
}
}
ListDataProvider<RowObject> dataProvider = new ListDataProvider<RowObject>();
dataProvider.addDataDisplay(cellTable);
dataProvider.setList(rowObjects);
Add columns like this:
Column column = new Column<RowObject, String>(new TextCell()) {
#Override
public String getValue(RowObject object) {
return getStringValueFor(object);
}
};
cellTable.addColumn(column);

How to hide column in Cell table GWT?

I am using Cell Table in GWT.In that cell table I am adding these columns.
TextColumn<Document> idColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return Long.toString(object.getId());
}
};
TextColumn<Document> refColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getReferenceNumber();
}
};
/*
* DateCell dateCell = new DateCell(); Column<Contact, Date> dateColumn
* = new Column<Contact, Date>(dateCell) {
*
* #Override public Date getValue(Contact object) { return
* object.birthday; } };
*/
TextColumn<Document> nameColumn = new TextColumn<Document>() {
#Override
public String getValue(Document object) {
return object.getDocumentName();
}
};
table = new CellTable<T>();
table.addColumn(idColumn, "Id");
table.addColumn(refColumn, "Reference Number");
table.addColumn(nameColumn, "Name");
}
Now I have some queries:
How to hide the id column?
On click of row how can i get the from selected row?
Please help me out.
Thanks in advance.
Well you could try to use fixed layout for the CellTable and set the width of the specific column you want to hide to 0px.
I did use another approach.
In my case I have a cellTable which should display a checkbox column as soon as I press a button (which puts the celltable in edit mode).
I do this by creating a CheckBoxColumn and inserting and removing it when I press on the button. It looks seomething like that:
#Override
public void insertCheckBoxColumn(Column<Object,Boolean> column) {
if (cellTable.getColumnIndex(column) == -1) {
cellTable.addColumn(column,"");
cellTable.setColumnWidth(column,50, Unit.PX);
}
}
#Override
public void removeCheckBoxColumn(Column<Object, Boolean> column) {
int index = cellTable.getColumnIndex(column);
if (index != -1)
cellTable.removeColumn(index);
}
However note that you might run into this issue on google chrome.