TableView column resize very slow - javafx-8

I have a simple 5 column table
public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
...
filename.setCellValueFactory( new PropertyValueFactory<Filedata,String>("filename") );
path.setCellValueFactory( new PropertyValueFactory<Filedata,String>("path") );
size.setCellValueFactory( new PropertyValueFactory<Filedata,String>("size") );
md5.setCellValueFactory( new PropertyValueFactory<Filedata,String>("md5") );
sha256.setCellValueFactory( new PropertyValueFactory<Filedata,String>("sha256") );
table.setItems(eeModel.data);
}
which I populate with some 220,000 records.
I'm finding that resizing the column width (by double-clicking the column divider) takes a very long time, some 10 seconds or so. Is that expected or is there something I can do to speed it up?
Monitoring with Process Explorer I see the following whilst resizing 3 columns. As this is a quad core machine its looking like the UI thread is 100% busy during those periods.
http://i57.tinypic.com/ienl3a.jpg

Related

GWT CellTable rebuilding rows unnecessarily

I have found an interesting issue, and I am wondering if I am misusing or overlooking something. I have a large CellTable that is vertically scrollable. I want to show all the rows at once instead of traditional pagination. So at the bottom of my table I have a row that the user can click to load 50 more rows. I have provided the table with a custom table builder (setTableBuilder(new Builder());). When the user clicks "load more" I query the data, add to the ListDataProvider and call table.setVisibleRange(0, dataProvider.getList().size());.
I put a log statement in the
#Override
public void buildRowImpl(Object rowValue, int absRowIndex) {
}
method to see when it was building rows. I notice that it would build 0-dataProvider.getList().size() (all the rows), then it would build oldLength-dataProvider.getList().size() (the new rows). For instance, if I have 100 rows and then load 50 more it would build 0-150, and then rebuild 100-50. What I want is for it to only build the new rows, obviously.
So I start debugging to see why it is rebuilding the whole table each time. What I found was in com.google.gwt.user.cellview.client.HasDataPresenter it would set the "redrawRequired" flag to true at line 1325:
else if (range1 == null && range0 != null && range0.getStart() == pageStart
&& (replaceDiff >= oldRowDataCount || replaceDiff > oldPageSize)) {
// Redraw if the new data completely overlaps the old data.
redrawRequired = true;
}
So my question is why does it think that the new data completely overlaps the old data?
Am I using something incorrectly, is there a better way? This gets to be quite a slow down when it has to redraw thousands of rows that don't need to be redrawn.
Thanks,
Will
I think that, in this situation, the only way a CellTable can react to the call of the setVisibleRange() method is to redraw all rows.
You have just informed a CellTable that now it has to display new range (0-150 rows) instead of last (0-100 rows). There is no information that rows 0-100 remain unchanged and there is no need to redraw them.
The interesting thing is that you found the new rows are updated (rebuild) twice:
For instance, if I have 100 rows and then load 50 more it would build 0-150, and then rebuild 100-50
I've tried to reproduce this behavior in the smallest example:
public class ListDataProviderTest implements EntryPoint {
private static final int ADD_COUNT = 10;
private int nextVal = 0;
public void onModuleLoad() {
final CellTable<Integer> cellTable = new CellTable<Integer>();
cellTable.addColumn(new TextColumn<Integer>() {
#Override
public String getValue(Integer object) {
return object.toString();
}});
final ListDataProvider<Integer> listDataProvider = new ListDataProvider<Integer>();
listDataProvider.addDataDisplay(cellTable);
RootPanel.get().add(cellTable);
RootPanel.get().add(new Button("Add more...", new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
List<Integer> list = listDataProvider.getList();
for(int i = 0; i < ADD_COUNT; i++)
list.add(nextVal++);
cellTable.setVisibleRange(0, list.size());
}
}));
}
}
But I get all the rows updated once.
Can you confirm that this example reproduces the issue or provide one that is more accurate?
AFAIK a CellTable always redraws all cells.
This is how the renderer from the CellTable works. Although it always redraws all cells, it is in most times still faster than using a FlexTable and only updating a few cells.

Java SWT - Create a pure SWT Table with different color on even and odd rows

I am very new to the SWT and I am trying to create a Java SWT table with different color on even and odd rows (ex: 1st row is red, second row is blue, third row is res, fourth row is blue ... ).
Since the rows on table can be deleted, inserted so if I manually set color by using a for loop I will have to run that loop again and again to set color every time there's something change in the table. And I don't want to use JFace, just pure Java SWT
Do you have some better solutions for this problems?
You can use custom drawn table items .
By adding a listener for the SWT.EraseItem you can just draw the background and let the rest do the default implementation. Use the item field of the event to decide whether an even or odd row is to be drawn.
For example:
table.addListener( SWT.EraseItem, new Listener() {
#Override
public void handleEvent( Event event ) {
int index = table.indexOf( ( TableItem )event.item );
if( index % 2 == 0 ) {
Color oldBackground = event.gc.getBackground();
event.gc.setBackground( event.display.getSystemColor( SWT.COLOR_DARK_YELLOW ) );
event.gc.fillRectangle( 0, event.y, table.getClientArea().width, event.height );
event.gc.setBackground( oldBackground );
}
}
} );

How to force cellTable to show all data (GWT)?

Here I have itemDetailTable
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>();
ListDataProvider<List<String>> dataProvider = new ListDataProvider<List<String>>();
dataProvider.addDataDisplay(itemDetailTable);
final ScrollPanel itemDetailScrollPanel=new ScrollPanel();
FlowPanel itemDetailFlowPanel=new FlowPanel();
itemDetailFlowPanel.add(itemDetailTable);
itemDetailScrollPanel.add(itemDetailFlowPanel);
Now my List<List<String>> has 16 rows, however, after ran it showed the table with 15 rows only. If I want to see the row 16 then need to click on the last cell of the table (the cell in the bottom right handside of the table) & enter arrow-down key then it will show the record 16.
If i use Simplepager
SimplePager itemDetailPager = new SimplePager();
itemDetailPager.setDisplay(itemDetailTable);
then it will have 2 page, the 1st page has 15 records and the 2nd page has 1 record.
That is not OK as I want the table to show all the records at once and won't hide any records.
Someone said that maybe cos I use List<String> & that is causing the problem, but I am not sure if that is the main cause.
But If I only has 14 records, then it showed all 14 records without any problem.
SO How to fix it?
Try any one
Just pass page size while constructing CellTable that constructs a table with the given page size.
int pageSize=16;
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>(pageSize);
use CellTable#setPageSize() to set the number of rows per page and refresh the view.
CellTable<List<String>> itemDetailTable = new CellTable<List<String>>();
itemDetailTable.setPageSize(16);
Note: use GWT.create() to construct the SimplePager.Resources object with as shown below:
SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
// pass the parameters as per your requirement
SimplePager pager = new SimplePager(TextLocation.CENTER, pagerResources, false, 0, true);

Smart GWT listgrid, how to expand and row span at the same time

So I have a Smart GWT ListGrid and I want to be able to make the rows expandable and at the same time do a row span on them. Expanding rows which are not merged (by doing row span) works fine, however if I have several rows that are merged the expand icon disappears. My code for expanding and row spanning is this:
lisgrid = new LisGrid()
{
#Override
protected Canvas getExpansionComponent(final ListGridRecord record)
{
// Add a nested grid to display the remaining requests for the tag
// (after the first N being shown be default).
VLayout layout = new VLayout(5);
layout.setPadding(1);
final ExtendedListGrid requestGrid = new ExtendedListGrid();
requestGrid.setWidth(500);
requestGrid.setHeight(224);
requestGrid.setCellHeight(22);
requestGrid.setDataSource(datasource);
requestGrid.fetchData();
layout.addMember(requestGrid);
return layout;
}
};
listGrid.setAllowRowSpanning(true);
listGrid.setCanExpandRecords(true);
listGrid.setMergeCols(new String[] { "requestSummaryTagId", "gca" });
I have overridden the getRowSpan method of the ListGrid to span a cell until the cell right under (same column index and next row index) it has the same value, and I also have a method, setMergeCols, that tells the grid which cells to span across rows. Here is what it looks like. As you can see, the first 2 cells at the bottom span 4 rows, but the expand symbol is missing, while for the rows above (which don't have any row span) the expand symbol is there. Any idea why?

GWT SimplePager LastButton issue

I am facing problem with lastButton of SimplePager.
I have 3 pages in celltable, Page size=11 (1 empty record + 10 records(with value)), Total record=26.
I used CustomerPager by extending SimplePager.
In 1st attempt 1+10 records display in celltable : Next & Last page button is enabled (First & Prev button disabled) which is correct.
But LastPage button not working... :( Dont know whats the issue... (event not fires)
Strange behavior:
#1 Last page button is working only when I visit to last page(3 page in my case).
#2 Assume I am on 1st page n I moved to 2nd page(Total 3 pages in celltable). that time all buttons are enabled which is correct.
In this case Last button is working but behave like Next Button
My GWT application integrated into one of our product so cant debug it from client side.
May be index value is improper in setPage(int index) method from AbstractPager
Code flow is as follows for Last button
//From SimplePager
lastPage.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
lastPage();
}
});
#Override
public void lastPage() {
super.lastPage();
}
// From AbstractPager
/**
* Go to the last page.
*/
protected void lastPage() {
setPage(getPageCount() - 1);
}
protected void setPage(int index) {
if (display != null && (!isRangeLimited || !display.isRowCountExact() || hasPage(index))) {
// We don't use the local version of setPageStart because it would
// constrain the index, but the user probably wants to use absolute page
// indexes.
int pageSize = getPageSize();
display.setVisibleRange(pageSize * index, pageSize);
}
}
or may be some conditions false from above code(from setPage())
actual record = 26 and 3 Empty record (1st Empty record/page)
May b problem with dataSize :|
How I can check number of pages based on the data size?
?
How can I solve this problem?
edit: I found out that the default constructor of the pager doesn't give you a "last" button, but a "fast forward 1000 lines" button instead (horrible, right?) .
call the following constructor like so, and see your problem solved:
SimplePager.Resources resources = GWT.create(SimplePager.Resources.class);
SimplePager simplePager = new SimplePager(TextLocation.CENTER, resources , false, 1000, true);
the first "false" flag turns off the "fastforward button" and the last "true" flag turns on the "last" button.
also the last button will work only if the pager knows the total amount of records you have.
you can call the table's setRowCount function to update the total like so:
int totalRecordsSize = 26; //the total amount of records you have
boolean isTotalExact = true; //is it an estimate or an exact match
table.setRowCount(totalRecordsSize , isTotalExact); //sets the table's total and updates the pager (assuming you called pager.setDisplay(table) before)
if you are working with an attached DataProvider, than all it's updateRowCount method instead (same usage).
Without seeing more of your code, this is a hard question to answer as there could be multiple places where things are going wrong.
I would make sure you call setDisplay(...) on your SimplePager so it has the data it needs calculate its ranges.
If you can't run in devmode, I recommend setting up some GWT logging in the browser (write the logs to a popup panel or something, see this discussion for an example).
I think the problem is related with condition in the setPage(). Try putting SOP before if condition or debug the code
Only added cellTable.setRowCount(int size, boolean isExact) in OnRange change method AsyncDataProvider. My problem is solved :)
protected void onRangeChanged(HasData<RecordVO> display) {
//----- Some code --------
cellTable.setRowCount(searchRecordCount, false);
//----- Some code --------
}