I want to sort celltable column, have written so far this, but it doesn't seem to be working, i did it all like in gwt showcase with celltable column sorting:
ListHandler<M> sort;
public View() {
getM(0,m);
createM();
}
void createM() {
Column<M, String> firstColumn = new Column<M, String>(
new TextCell()) {
#Override
public String getValue(M object) {
return object.getName();
}
};
table.addColumn(firstColumn,"Name");
firstColumn.setSortable(true);
sort.setComparator(firstColumn, new Comparator<M>() {
#Override
public int compare(M m1, M m2) {
return m1.getName().compareTo(m2.getName());
}
});
void getM(int dataID, M m) {
final ListDataProvider<M> listProvider = new ListDataProvider<M>();
listProvider.addDataDisplay(table);
listProvider.refresh();
final List<M> mList = listProvider.getList();
sort = new ListHandler<M>(mList);
AsyncCallback<List<M>> callback = new AsyncCallback<List<M>>() {
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
#Override
public void onSuccess(final List<M> result) {
for (final M m : result) {
mList.add(m);
}
table.addColumnSortHandler(sort);
}
};
rpcService.getDataSource(dataID, m, callback);
any suggestion, what is wrong here? How can i solve this?
i moved my code from getM() into createM() like:
void createM() {
final ListDataProvider<M> listProvider = new ListDataProvider<M>();
listProvider.addDataDisplay(table);
listProvider.refresh();
final List<M> mList = listProvider.getList();
sort = new ListHandler<M>(mList);
Column<M, String> firstColumn = new Column<M, String>(
new TextCell()) {
#Override
public String getValue(M object) {
return object.getName();
}
};
table.addColumn(firstColumn,"Name");
firstColumn.setSortable(true);
sort.setComparator(firstColumn, new Comparator<M>() {
#Override
public int compare(M m1, M m2) {
return m1.getName().compareTo(m2.getName());
}
});
and it sort the column, but if i choose the next data to show in column it will be added to the existing items in column, can anyone point me why it is so?
The first example is not working because you re-initialize your sort object:
sort = new ListHandler<M>(mList);
This removes all settings from sort.
In the second example, you need to call
mList.clear();
before you add new items to this list. Also, move
table.addColumnSortHandler(sort);
from the callback to your create method. There is no need to call it every time you add data.
Related
Is there a default way to allow the users deselect a selected row?
If not, I want to make the row to be deselected on another click. How can I achieve it?
In the bellow I attached the code piece for my tree grid tg
// ---------------------- set up columns ------------------------ \\
// set up name column
ColumnConfig<ProductMapping, String> cc1 = new ColumnConfig<ProductMapping, String>(new ValueProvider<ProductMapping, String>(){
#Override
public String getValue(ProductMapping object) {
return object.getName();
}
#Override
public void setValue(ProductMapping object, String value) {
object.setName(value);
}
#Override
public String getPath() {
return "name";
}
});
cc1.setWidth(200);
cc1.setHeader("Name");
// setup solution column
ColumnConfig<ProductMapping, String> cc2 = new ColumnConfig<ProductMapping, String>(new ValueProvider<ProductMapping, String>() {
#Override
public String getValue(ProductMapping object) {
return object.getSolution();
}
#Override
public void setValue(ProductMapping object, String value) {
object.setSolution(value);
}
#Override
public String getPath() {
return "solution";
}
});
cc2.setHeader("Solution");
cc2.setWidth(200);
// setup condition column
ColumnConfig<ProductMapping, String> cc3 = new ColumnConfig<ProductMapping, String>(new ValueProvider<ProductMapping, String>() {
#Override
public String getValue(ProductMapping object) {
return object.getCondition();
}
#Override
public void setValue(ProductMapping object, String value) {
object.setCondition(value);
}
#Override
public String getPath() {
return "condition";
}
});
cc3.setHeader("Condition");
cc3.setWidth(200);
// create column model
List<ColumnConfig<ProductMapping,?>> ccl = new LinkedList<ColumnConfig<ProductMapping,?>>();
ccl.add( cc1);
ccl.add( cc2);
ccl.add( cc3);
ColumnModel<ProductMapping> cm = new ColumnModel<ProductMapping>(ccl);
// Create the tree grid using the store, column model and column config for the tree column
tg = new TreeGrid<ProductMapping>(treeStore, cm, ccl.get(0));
// tg.getSelectionModel().get
tg.addRowClickHandler(new RowClickEvent.RowClickHandler(){
#Override
public void onRowClick(RowClickEvent event) {
tgRowClicked(event);
}
});
So i have here a Cellbutton :
Column<dateiles, String> column_2 = new Column<dateiles, String>(new ButtonCell()) {
#Override
public String getValue(dateiles object) {
int s = object.comments.size();
String ss = String.valueOf(s);
return ss;
}
};
cellTable.addColumn(column_2, "Comments");
cellTable.setColumnWidth(column_2, "100px");
i want to add to my buttons for each cell column a Tooltip but how is it possible
this.addCellPreviewHandler(new Handler<Tabletype>() {
#Override
public void onCellPreview(final CellPreviewEvent<Tabletype> event) {
int columnID = event.getColumn();
}
});
}
Just replace tabletype with the object you definded when instantiating the table ( The T of CellTable<T> ) Then with the columnID you can detect the right column.
Following Situation: I have a J(X)Table with RowHeader (As guidline I used one of Rob Camicks great Examples). All worked as expected.
By requirement the data I receive from server already contains a tablerownumber, which I have to show in the rowheader and the data should be filterable. So I extended the example, and I added a filter. When I filtered the view I saw gaps in my row numbers (for example: 1, 3, 6,..), which is the desired effect.
To be able to filter and sort the table by my own tablerow, I added a TableRowSorter. And here I started to get confused. The Example uses the same TableModel and SelectionModel for mainTable and rowHeaderTable:
setModel( main.getModel() );
setSelectionModel( main.getSelectionModel() );
This is great, since I don’t have to synchronize them. But concerning TableRowSorter I suddenly wasn’t sure, if I also can or even have to use the same TableRowSorter-Instance or if I have to create a TableRowSorter for each table. First I added the same to both Tables, since this seemed practically, but then I got IndexOutOfBound-Exceptions in many cases. After some digging I found out that this is because the TableRowSorter gets updated twice at each TableModelEvent, because each table (RowHeader and MainTable) notifies the TableRowSorter about tablechanges on its own.
Now I am not sure which the right way to go is. Following solutions came into my mind: Should I add a second TableRowSorter (one for each table) and synchronize these, or should I wrap the TableModel within the RowHeaderTable and let it not fireing any Events? Or maybe I should create my own kind of RowHeaderTable which doesn’t notify Sorters about changes at all?
Here's a quick (beware: not formally tested! the usage example works fine, though) implementation of a wrapping RowSorter.
does nothing on receiving notification of model changes
delegates all status queries
listens to wrapped rowSorter and propagates its events
It's client's responsibility to keep it in synch with the rowSorter used in the main table
Usage example (in terms of SwingX test infrastructure and with SwingX sortController/table):
public void interactiveRowSorterWrapperSharedXTable() {
final DefaultTableModel tableModel = new DefaultTableModel(list.getElementCount(), 2) {
#Override
public Class<?> getColumnClass(int columnIndex) {
return Integer.class;
}
};
for (int i = 0; i < tableModel.getRowCount(); i++) {
tableModel.setValueAt(i, i, 0);
tableModel.setValueAt(tableModel.getRowCount() - i, i, 1);
}
final JXTable master = new JXTable(tableModel);
final TableSortController<TableModel> rowSorter = (TableSortController<TableModel>) master.getRowSorter();
master.removeColumn(master.getColumn(0));
final JXTable rowHeader = new JXTable(master.getModel());
rowHeader.setAutoCreateRowSorter(false);
rowHeader.removeColumn(rowHeader.getColumn(1));
rowHeader.setRowSorter(new RowSorterWrapper<TableModel>(rowSorter));
rowHeader.setSelectionModel(master.getSelectionModel());
// need to disable selection update on one of the table's
// otherwise the selection is not kept in model coordinates
rowHeader.setUpdateSelectionOnSort(false);
JScrollPane scrollPane = new JScrollPane(master);
scrollPane.setRowHeaderView(rowHeader);
JXFrame frame = showInFrame(scrollPane, "xtables (wrapped sortController): shared model/selection");
Action fireAllChanged = new AbstractAction("fireDataChanged") {
#Override
public void actionPerformed(ActionEvent e) {
tableModel.fireTableDataChanged();
}
};
addAction(frame, fireAllChanged);
Action removeFirst = new AbstractAction("remove firstM") {
#Override
public void actionPerformed(ActionEvent e) {
tableModel.removeRow(0);
}
};
addAction(frame, removeFirst);
Action removeLast = new AbstractAction("remove lastM") {
#Override
public void actionPerformed(ActionEvent e) {
tableModel.removeRow(tableModel.getRowCount() - 1);
}
};
addAction(frame, removeLast);
Action filter = new AbstractAction("toggle filter") {
#Override
public void actionPerformed(ActionEvent e) {
RowFilter filter = rowSorter.getRowFilter();
if (filter == null) {
rowSorter.setRowFilter(RowFilter.regexFilter("^1", 1));
} else {
rowSorter.setRowFilter(null);
}
}
};
addAction(frame, filter);
addStatusMessage(frame, "row header example with RowSorterWrapper");
show(frame);
}
The RowSorterWrapper:
/**
* Wrapping RowSorter for usage (f.i.) in a rowHeader.
*
* Delegates all state queries,
* does nothing on receiving notification of model changes,
* propagates rowSorterEvents from delegates.
*
* Beware: untested!
*
* #author Jeanette Winzenburg, Berlin
*/
public class RowSorterWrapper<M> extends RowSorter<M> {
private RowSorter<M> delegate;
private RowSorterListener rowSorterListener;
public RowSorterWrapper(RowSorter<M> delegate) {
this.delegate = delegate;
delegate.addRowSorterListener(getRowSorterListener());
}
/**
* Creates and returns a RowSorterListener which re-fires received
* events.
*
* #return
*/
protected RowSorterListener getRowSorterListener() {
if (rowSorterListener == null) {
RowSorterListener listener = new RowSorterListener() {
#Override
public void sorterChanged(RowSorterEvent e) {
if (RowSorterEvent.Type.SORT_ORDER_CHANGED == e.getType()) {
fireSortOrderChanged();
} else if (RowSorterEvent.Type.SORTED == e.getType()) {
fireRowSorterChanged(null); }
}
};
rowSorterListener = listener;
}
return rowSorterListener;
}
#Override
public M getModel() {
return delegate.getModel();
}
#Override
public void toggleSortOrder(int column) {
delegate.toggleSortOrder(column);
}
#Override
public int convertRowIndexToModel(int index) {
return delegate.convertRowIndexToModel(index);
}
#Override
public int convertRowIndexToView(int index) {
return delegate.convertRowIndexToView(index);
}
#Override
public void setSortKeys(List keys) {
delegate.setSortKeys(keys);
}
#Override
public List getSortKeys() {
return delegate.getSortKeys();
}
#Override
public int getViewRowCount() {
return delegate.getViewRowCount();
}
#Override
public int getModelRowCount() {
return delegate.getModelRowCount();
}
#Override
public void modelStructureChanged() {
// do nothing, all work done by delegate
}
#Override
public void allRowsChanged() {
// do nothing, all work done by delegate
}
#Override
public void rowsInserted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
#Override
public void rowsDeleted(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
#Override
public void rowsUpdated(int firstRow, int endRow) {
// do nothing, all work done by delegate
}
#Override
public void rowsUpdated(int firstRow, int endRow, int column) {
// do nothing, all work done by delegate
}
}
I have a Cell Table of which the last column is a checkbox. I would like to add a Check-All-Box as a footer that when clicked selects every checkbox for every row. Somehow it won't work here is what I got so far:
Column<Object, Boolean> select = new Column<Object, Boolean>(new CheckboxCell()) {
#Override
public Boolean getValue(Object object) {
return msm.isSelected(object);
}
};
select.setFieldUpdater(new FieldUpdater<Object, Boolean>() {
public void update(int index, Object object, Boolean value) {
msm.setSelected(object, value);
}
});
final Header selectAllHeader = new Header(new CheckboxCell()) {
#Override
public Boolean getValue(){
return msm.getSelectedSet().size() == getRowCount();
}
};
selectAllHeader.setUpdater(new ValueUpdater<Boolean>() {
#Override
public void update(Boolean value) {
for (Object o : getVisibleItems) {
msm.setSelected(o, value);
}
}
});
//works
addColumn(select, selectAllHeader);
//does not work
//addColumn(select, HEADER, selectAllHeader);
I used a solution proposed here:
http://code.google.com/p/google-web-toolkit/issues/detail?id=7014
It works nicely. You can use it in your footer.
At first I used the Grid.
After creating a new version of the GWT, I want to replace the Grid on the CellTable.
Check out the javadoc for details. My example is like the one you'll find there (just a little extended):
public void onModuleLoad() {
final CellTable<Row> table = new CellTable<Row>();
TextColumn<Row> firstColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.firstColumn;
}
};
table.addColumn(firstColumn, "header one");
TextColumn<Row> secondColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.secondColumn;
}
};
table.addColumn(secondColumn, "header two");
TextColumn<Row> thirdColumn = new TextColumn<Starter.Row>() {
#Override
public String getValue(Row object) {
return object.thirdColumn;
}
};
table.addColumn(thirdColumn, "header three");
table.setRowCount(getList().size());
final ListDataProvider<Row> dataProvider = new ListDataProvider<Starter.Row>(getList());
dataProvider.addDataDisplay(table);
final SingleSelectionModel<Row> selectionModel = new SingleSelectionModel<Starter.Row>();
table.setSelectionModel(selectionModel);
Button btn = new Button("delete entry");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Row selected = selectionModel.getSelectedObject();
if (selected != null) {
dataProvider.getList().remove(selected);
}
}
});
RootPanel.get().add(table);
RootPanel.get().add(btn);
}
private class Row {
private String firstColumn;
private String secondColumn;
private String thirdColumn;
public Row(String firstColumn, String secondColumn, String thirdColumn) {
this.firstColumn = firstColumn;
this.secondColumn = secondColumn;
this.thirdColumn = thirdColumn;
}
}
private LinkedList<Row> getList() {
LinkedList<Row> list = new LinkedList<Row>();
list.add(new Row("first", "entry", "foo"));
list.add(new Row("second", "entry", "foo"));
list.add(new Row("third", "entry", "foo"));
list.add(new Row("fourth", "entry", "foo"));
return list;
}
Or you can just run the cycle like that
#UiHandler("combo")
public void onChange(ChangeEvent e) {
textBoxes.clear();
searchFields.clear();
while(resultsTable.getColumnCount()!=0) {
resultsTable.removeColumn(0);
}
resultsTable.redraw();
Where resultsTable is a CellTable
CellTable as part of new DataPresentationWidgets used just to display data. So you should delete according member from list of data which CellTable using to display.