Sorting Cell Table column in GWT not working - java

I am trying to sort a column in a Cell table of GWT 2.6.0, but it is not working.
Here is my sample Code.
patientsTable.addColumn(NameColumn, messages.surname());
patientsTable.setColumnWidth(0, "100px");
patientsTable.getColumn(0).setSortable(true);
ListHandler<PatientDTO> columnSortHandler = new ListHandler<PatientDTO>(
dataProvider.getList());
columnSortHandler.setComparator(NameColumn,
new Comparator<PatientDTO>() {
#Override
public int compare(PatientDTO o1, PatientDTO o2) {
if (o1 == o2) {
return 0;
}
if (o1 != null) {
return (o2 != null) ? o1.getLastName().compareTo(o2.getLastName()) : 1;
}
return -1;
}
});
patientsTable.addColumnSortHandler(columnSortHandler);
patientsTable.getColumnSortList().push(NameColumn);

Try like this, i have given working example,
NameColumn.setSortable(true);
patientsTable.addColumnSortHandler(new ColumnSortEvent.Handler() {
#Override
public void onColumnSort(ColumnSortEvent event) {
final Column a = event.getColumn();
List<PatientDTO> newData = new ArrayList(patientsTable.getVisibleItems());
Collections.sort(newData, new Comparator<PatientDTO>() {
public int compare(PatientDTO o1, PatientDTO o2) {
// code here to sort asc or desc order
}
});
Range range = patientsTable.getVisibleRange();
int start = range.getStart();
patientsTable.setRowData(start, newData);
}
});

Try to use the same List<PatientDTO> instance which you are using while setting your data in the patientsTable. It seems that the sortHandler is not being called because of the difference in both of the list.
ListHandler<PatientDTO> columnSortHandler = new ListHandler<PatientDTO>(patientList);

Try
NameColumn.setSortable(true);

Related

How to sort values as numbers in NatTable?

My problem is, that data values are sorted as strings, although I used DefaultDoubleDisplayConverter. I registered converter to cell labels, not to column header label. My code:
public class NatTableFactory {
private NatTable createTable(Composite parent, List<TableLine> tLines, String[][] propertyNames,
PropertyToLabels[] propToLabels, TableParams params, TextMatcherEditor<TableLine>editor, boolean openableParts) {
BodyLayerStack bodyLayerStack =
new BodyLayerStack(
tLines,
tLines.get(0).getLength(),
params.getColumnIndicesForRowHeaders());
...
SortHeaderLayer<TableLine> sortHeaderLayer =
new SortHeaderLayer<TableLine>(
columnHeaderLayer,
new GlazedListsSortModel<TableLine>(
bodyLayerStack.getSortedList(),
getSortingColumnPropAccessor(propertyNames[0]),
configRegistry,
columnHeaderDataLayer));
...
composite.addConfiguration(NatTableLayerConfigurations.getCompoositeLayerConfiguration());
NatTable natTable = new NatTable(parent, composite, false);
if( params.getAutoFitColWidthIndices().size() > 0 )
registerAutoResizeColCmdHandler(natTable, composite, bodyLayerStack, params.getAutoFitColWidthIndices());
setNatTableContentTooltip(natTable);
natTable.setConfigRegistry(configRegistry);
natTable.addConfiguration(new SingleClickSortConfiguration());
natTable.addConfiguration(new DefaultNatTableStyleConfiguration());
setNatTableContextMenu(natTable, openableParts);
natTable.addConfiguration(NatTableLayerConfigurations.getNatTableConfiguration());
//natTable.addConfiguration(NatTableLayerConfigurations.getCustomConvertConfiguration(bodyDataLayer));
natTable.configure();
...
NatTableContentProvider.addNatTableData(natTable, bodyLayerStack.getSelectionLayer(), bodyLayerStack.getBodyDataProvider());
return natTable;
}
}
then:
public class NatTableLayerConfigurations
{
...
public static AbstractRegistryConfiguration getNatTableConfiguration()
{
return new AbstractRegistryConfiguration()
{
#Override
public void configureRegistry(IConfigRegistry configRegistry)
{
...
Style cellAlignStyle = new Style();
cellAlignStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignmentEnum.RIGHT);
configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellAlignStyle, DisplayMode.NORMAL, NatTableFactory.DataTypeNumberLabel);
//
configRegistry.registerConfigAttribute(
CellConfigAttributes.DISPLAY_CONVERTER,
new DefaultDoubleDisplayConverter(), DisplayMode.NORMAL,
NatTableFactory.DataTypeNumberLabel);
System.out.println("configRegistry.registerConfigAttribute CellConfigAttributes.DISPLAY_CONVERTER");
...
}
};
}
}
and:
public class BodyLayerStack extends AbstractLayerTransform
{
...
public BodyLayerStack(List<TableLine> values, int columnCount, Integer[] columnIndicesForRowHeaders)
{
EventList<TableLine> eventList = GlazedLists.eventList(values);
TransformedList<TableLine, TableLine> rowObjectsGlazedList = GlazedLists.threadSafeList(eventList);
sortedList = new SortedList<>(rowObjectsGlazedList, null);
// wrap the SortedList with the FilterList
filterList = new FilterList<>(sortedList);
bodyDataProvider = new ListDataProvider<TableLine>(filterList, getColumnAccessor(columnCount));
bodyDataLayer = new DataLayer(bodyDataProvider);
IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
#Override
public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {
int columnIndex = bodyDataLayer.getColumnIndexByPosition(columnPosition);
int rowIndex = bodyDataLayer.getRowIndexByPosition(rowPosition);
if( isRowHeader(columnIndicesForRowHeaders, columnIndex) ) {
configLabels.addLabel(NatTableFactory.RowHeaderLabel);
} else {
configLabels.addLabel(filterList.get(rowIndex).getObjectTypeByColumn(columnIndex));
// NatTableLayerConfigurations.getNatTableConfiguration();
}
}
};
bodyDataLayer.setConfigLabelAccumulator(cellLabelAccumulator);
GlazedListsEventLayer<TableLine> glazedListsEventLayer = new GlazedListsEventLayer<>(bodyDataLayer, filterList);
...
}
}
I checked various examples, but I can not see, what do I miss. And how can I check, if data in cells were converted correctly? Thanks for some hint.
I suppose you are missing the configuration of the sort comparator.
This is explained in our documentation: https://www.eclipse.org/nattable/documentation.php?page=sorting
The following examples show the usage:
SortableGridExample
GroupByCustomTypesExample

How to cache search results retrieved from auto-complete API

I've been working on a searching auto-complete feature with Bootstrap-3-Typeahead ,GWT and data comes from http://dawa.aws.dk/dok/api by JsonP request..
The Typahead creation method is below
private Typeahead<Location> createTypeAhead() {
typeAhead = new Typeahead<>(new Dataset<Location>() {
#Override
public void findMatches(final String query, final SuggestionCallback<Location> callback) {
requestCounter--;
startSendingRequest = true;
clear.setIcon(IconType.SPINNER);
clear.setIconSpin(true);
final Set<Suggestion<Location>> suggestions = new HashSet<>();
queryLower = query.toLowerCase();
JsonpRequestBuilder jsonpRequestBuilder;
if (!streetSelected) {
jsonpRequestBuilder = new JsonpRequestBuilder();
jsonpRequestBuilder.requestObject("https://dawa.aws.dk/vejnavne/autocomplete?side=1&per_side=500&noformat=1&q=" + queryLower + "*", new AsyncCallback<MyJsArray<VejAutocomplete>>() {
#Override
public void onFailure(Throwable caught) {
Notify.notify("suggestion matches failed");
}
#Override
public void onSuccess(MyJsArray<VejAutocomplete> result) {
Set<Location> locationSet = new LinkedHashSet<>();
for (VejAutocomplete item : result.getAsList()) {
String lowerCase = item.getTekst().toLowerCase();
if (lowerCase.startsWith(queryLower)) {
locationSet.add(new Location(Location.LocationType.STREET, item.getTekst(), item));
locationArrayList.clear();
locationArrayList.addAll(locationSet);
}
}
}
});
}
for (Location address : locationArrayList) {
String value = address.getValue();
Suggestion<Location> s = Suggestion.create(value, address, this);
if (address.getValue().toLowerCase().startsWith(queryLower)) {
suggestions.add(s);
}
}
callback.execute(suggestions);
if (typeAhead.getValue().length() != 0 && queryLower.length() <= 5 && requestCounter < 5 && requestCounter > 0) {
new Timer() {
#Override
public void run() {
findMatches(queryLower, callback);
}
}.schedule(500);
} else {
clear.setIconSpin(false);
clear.setIcon(IconType.CLOSE);
requestCounter = 5;
}
}
});
return typeAhead;
}
The result is like below:
I used recursion to send 4-5 times of request because it's not showing the suggestion list with the keyword of single letter. And It still won't work with some single letters like "s" or "e". Data successfully retrieved from the API but doesn't show in the suggestion list like below:
I assume that I should cache all search results then recreate the auto-complete from scratch, it becomes complicated in that case.
Any good idea to solve this problem?

ParseObject as a data to the table/chart

I'm new in coding and I have a problem to understand something. I follow the example form Parse.com Doc and wrote this.
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
int object_value = Integer.parseInt(obiect);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
I understand this like:
I send query to server
get obiect with "lxFzCTeOcl" id
if there is no exception I create String object which takes string
form "value" column.
convert String to int
My question is: How can I use object_value for example to make a chart or put it into a table?
Here we will add the array list to your code and start to store an object inside the array every time we call the getData method in your class.
private ArrayList<Integer> dataArray;
public void getData() {
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseClass");
query.getInBackground("lxFzCTeOcl", new GetCallback<ParseObject>() {
public void done(ParseObject parseObject, ParseException e) {
if (e == null) {
String object = parseObject.getString("value");
Integer objectValue = Integer.parseInt(obiect);
if(dataArray==null)
dataArray = new ArrayList<Integer>();
dataArray.add(objectValue);
} else {
Log.d("score", "Error: " + e.getMessage());
}
}
});
}
And here I'm just adding a simple example of how to create a simple pie chart using our array list (note that I used the lib AChartEngine http://www.achartengine.org/):
private static int[] COLORS = new int[] { Color.GREEN, Color.BLUE,Color.MAGENTA, Color.CYAN };
private GraphicalView createPieChart(ArrayList<Integer> data){
GraphicalView chartView;
CategorySeries series = new CategorySeries("PIE");
for (int i = 0; i < VALUES.length; i++) {
series.add(i, data.get(i));
SimpleSeriesRenderer renderer = new SimpleSeriesRenderer();
renderer.setColor(COLORS[(series.getItemCount() - 1) % COLORS.length]);
mRenderer.addSeriesRenderer(renderer);
}
chartView = ChartFactory.getPieChartView(this, series, new DefaultRenderer());
chartView.repaint();
return chartView;
}
Now you can add this GraphicalView to your view.
The returned object is much like a map, with key/value pairs. In your example, the key is "value", which makes it a little confusing, but it would be like this if you wanted all fields:
for (Field field : myInstance.getClass().getDeclaredFields()) {
String name = field.getName();
value = field.get(myInstance).toString();
map.put(name, value);
}

Definition TableModel removeRow() method [duplicate]

This question already has an answer here:
TableModel removeRow() definition [closed]
(1 answer)
Closed 9 years ago.
This is my tableModel:
public class d9 extends AbstractTableModel {
ArrayList<String> cols = new ArrayList<>();
ArrayList<ArrayList<String>> data = new ArrayList<>();
public d9() {
...
int c = resultSet.getMetaData().getColumnCount();
while (resultSet.next()) {
ArrayList<String> eachRow = new ArrayList<>();
for (int i = 1; i <= c; i++) {
eachRow.add(resultSet.getString(i));
}
data.add(eachRow);
}
...
}
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return cols.size();
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
ArrayList<String> selectedRow = data.get(rowIndex);
return selectedRow.get(columnIndex);
}
#Override
public String getColumnName(int column) {
return cols.get(column);
}
public void removeRow(int rowNumber) {
data.remove(rowNumber);
fireTableRowsDeleted(rowNumber, rowNumber);
}
}
Now, after passing a convertRowIndexToModel line number to removeRow method
Row remove from table, But after re-run program, It come back!
When you call removeRow you need to try and remove the row from the database.
Now because I have no idea what the structure of your database is, you will need to fill in the details, but this a simple outline of what you need to do
public void removeRow(int rowNumber) throws SQLException {
Connection con = ...;
PreparedStatement ps = null;
String keyValue = ...; // Get key value from the ArrayList
try {
ps = con.prepareStatement("DELETE from youDatabaseTabe where key=?");
ps.setObject(1, keyValue);
if (ps.executeUpdate() == 1) {
data.remove(rowNumber);
fireTableRowsDeleted(rowNumber, rowNumber);
} else {
throw new SQLException("Failed to remove row from database");
}
} finally {
try {
ps.close();
} catch (Exception e) {
}
}
}
You may want to spend some time having a read through JDBC Database Access

How to implement a custom ColumnSorter with ScrollTable (GWT-incubator)

I've implemented my custom column sorter which is used to sort the
elements in my table.
class FileColumnSorter extends SortableGrid.ColumnSorter
{
#Override
public void onSortColumn(SortableGrid sortableGrid, TableModelHelper.ColumnSortList columnSortList,
SortableGrid.ColumnSorterCallback columnSorterCallback)
....
}
When I initialize the FixedWidthGrid I do the following:
FixedWidthGrid dataTable = new FixedWidthGrid(rows, cols);
dataTable.setSelectionPolicy(SelectionGrid.SelectionPolicy.ONE_ROW);
dataTable.setColumnSorter(new FileColumnSorter());
The scrolltable is initialized the following way:
FixedWidthFlexTable headerTable = createHeaderTable();
// Calling the lines described above
FixedWidthGrid fileListGrid = createDataTable
(currentDescriptorList.size(), 6);
// Combine the components into a ScrollTable
scrollTable = new ScrollTable(fileListGrid, headerTable);
scrollTable.setSortPolicy(AbstractScrollTable.SortPolicy.SINGLE_CELL);
scrollTable.setColumnSortable(0, false);
scrollTable.setColumnSortable(1, true);
scrollTable.setColumnSortable(2, true);
scrollTable.setColumnSortable(3, true);
scrollTable.setColumnSortable(4, true);
scrollTable.setColumnSortable(5, false);
When I run the application, I get the built in sorting instead of my
custom sorting. I've also tried to do the following:
ColumnSorter sorter = new FileColumnSorter();
FixedWidthGrid dataTable = new FixedWidthGrid(rows, cols) {
#Override
public ColumnSorter getColumnSorter()
{
return sorter;
}
};
To ensure that my sorter get used, but I still get the same
experience.
Update: Added the FileColumnSorter
class FileColumnSorter extends SortableGrid.ColumnSorter
{
#Override
public void onSortColumn(SortableGrid sortableGrid,
TableModelHelper.ColumnSortList columnSortList,
SortableGrid.ColumnSorterCallback columnSorterCallback)
{
final int column = columnSortList.getPrimaryColumn();
final Integer[] originalOrder = new Integer[sortableGrid.getRowCount()];
for (int i = 0; i < originalOrder.length; i++)
{
originalOrder[i] = i;
}
Arrays.sort(originalOrder, new Comparator<Integer>() {
public int compare(Integer first, Integer second)
{
Descriptor firstDesc = share.getCurrentDescriptors().get(first);
Descriptor secondDesc = share.getCurrentDescriptors().get(second);
if (firstDesc.getType().equals(secondDesc.getType()))
{
switch (column)
{
case 0:
return firstDesc.compareTo(secondDesc);
case 1:
return firstDesc.getName().compareTo(secondDesc.getName());
case 2:
return ((Long) firstDesc.getSize()).compareTo(secondDesc.getSize());
case 3:
return firstDesc.getCreated().compareTo(secondDesc.getCreated());
case 4:
return firstDesc.getModified().compareTo(secondDesc.getModified());
default:
return firstDesc.compareTo(secondDesc);
}
}
else
{
return firstDesc.getType() == Descriptor.FileItemType.FOLDER ? 1 : -1;
}
}
});
int[] resultOrder = new int[originalOrder.length];
for (int i = 0; i < originalOrder.length; i++)
{
if (columnSortList.isPrimaryAscending())
{
resultOrder[i] = originalOrder[i];
}
else
{
resultOrder[resultOrder.length - i - 1] = originalOrder[i];
}
}
columnSorterCallback.onSortingComplete(resultOrder);
}
}
I found this great example on how to use a PagingScrollTable with GWT incubator. Maybe you can use this instead of implementing your own: http://zenoconsulting.wikidot.com/blog:17

Categories