[SWT] Form Field view update takes too long [message #1710660] |
Thu, 08 October 2015 09:14 |
Jannik Malken Messages: 44 Registered: October 2015 |
Member |
|
|
Hi,
I'm having a problem with my application data visualization application. It is roughly based on the template "Outline and Table Form" but is pretty much tweaked to fit my needs.
I'm working with one form which for now manages the table paging of my results. It consists of some basic fields and a table (screenshot).
I implemented an Observer pattern on my own to have more control whats happening when the form values are changed. So the current values are stored in an Observable object which updates the form (Observer) when values are changed.
My form's update method looks like this:
@Override
public void update(Observable o, Object arg) {
logger.debug("FORM UPDATE BEGIN");
pagingHelper = (PagingHelper) o;
try {
getTableField().reloadTableData();
}
catch (ProcessingException e) {
logger.error("Table reload failed!\n" + e);
// reset to the last state
pagingHelper = pagingHelper.getLastState();
update(pagingHelper, null);
}
getPagingDisplayedPageInputField().setValue(pagingHelper.getDisplayedPage());
getPagingTotalPagesField().setValue(pagingHelper.getPagesTotal() + "");
getPagingDisplayedQueryMatchesField().setValue(buildDisplayedQueryMatchesString());
logger.debug("FORM UPDATE END");
}
The problems occur whenever I change the displayed page. It doesn't matter if I set it directly through the input field or with the next button click event. Both changes the Observable object and in the end of the chain results in a call of the above update method in the form.
The strange thing is that the update method is run through as it should. All calculated values and server operations which should be the only things causing some noticeable delay, can be seen in the log output after milliseconds. The table is also updated in about the same time.
Then it takes a few seconds until you see the new values in the view. I think there must be some asychronous background processes which suspend the view update.
It could be also important to mention that the delay increases with the total number of pages / found query matches. For me, that doesn't really make sense, as all relevant values are already there before the delay, but maybe this could be a hint.
This problem only appears in the SWT client. RAP and Swing work perfectly fine.
[Updated on: Thu, 08 October 2015 09:16] Report message to a moderator
|
|
|
|
Re: [SWT] Form Field view update takes too long [message #1710993 is a reply to message #1710972] |
Mon, 12 October 2015 08:14 |
Jannik Malken Messages: 44 Registered: October 2015 |
Member |
|
|
First of all, thanks for your answer, Urs!
Because I guessed it could be a scout-internal bug I updated my runtime to the last Mars version last week already (Eclipse Scout 5.0.100.20150916-1224), but that didn't solve the problem.
Nevertheless, after some deeper debugging and testing I could localize the problem a bit better. It indeed has to do with the table update, though definately not with the data fetching itself.
As my table's columns are dynamically created at runtime, I no more suspect the total data sets to be the suspending factor, but the number of columns instead. It is just by chance that in my test data the tables with more data sets also have more columns.
So some part of my table/column creation construction must confuse the Scout SWT renderer to produce thread collisions or whatever.
With Java Visual VM I found out that there is actually a thread waiting during the delay (java.lang.Object.wait[native]()) until the view gets finally updated. By the way, changing the invocation order so that the label fields are set before the table reload, there is still the same amount of delay afterwards.
Also, when I trigger multiple reload events (e.g. clicking the next button three times), the delay adds together, but every call is performed correctly. Nothing gets lost when the UI hangs.
@Override
protected void execReloadTableData() throws ProcessingException {
logger.debug("execReloadTableData");
try {
// initialize tablepage with dynamic columns from database/elasticsearch
IElasticsearchService service = SERVICES.getService(IElasticsearchService.class);
Map<String, String> fieldTypeMappings = service.getFieldTypeMappings(connection, indexName, mappingName);
updateDynamicColumns(fieldTypeMappings, indexName, mappingName);
ResultData indexData = pagingHelper.getIndexData();
List<IColumn<?>> tableColumns = getTable().getColumns();
// The confusion happens somewhere between HERE:
for (Map<String, Object> result : indexData.getResults()) {
Object[] objectValueArray = new String[tableColumns.size()];
for (int i = 0; i < tableColumns.size(); i++) {
String tableColumnId = tableColumns.get(i).getColumnId();
String tableColumnName = tableColumnId.split("-")[2];
Object cellResult = result.get(tableColumnName );
objectValueArray[i] = "" + cellResult;
}
// ONLY FOR TEST PURPOSES
getTestField().setValue(pagingHelper.getDisplayedPage() + "");
// ---------------------------------------------------------------
getTable().addRowByArray(objectValueArray);
// and HERE ------------------------------------------------------------
}
}
catch (InterruptedException | ExecutionException | IOException e) {
e.printStackTrace();
throw new ProcessingException("Table reload failed");
}
}
Since I now roughly know where the problems start, I added a test field and set it with a value at different times in the processing order (getTestField().setValue(pagingHelper.getDisplayedPage() + ""); ). Setting it at the position you see in the code above, the field is set directly with very little delay, so likely adding the row by array causes the problems. But as I wrote before, the strange thing is that the new table values are already visible during the delay.
I hope, someone with more profound background knowledge of the scout rendering could help me to understand whats happening here.
[Updated on: Fri, 16 October 2015 13:55] Report message to a moderator
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03261 seconds