JDK-8091122 : Turning off updateItem rendering in TableCell once scrolled or data visited
  • Type: Enhancement
  • Component: javafx
  • Sub-Component: controls
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2013-02-18
  • Updated: 2018-09-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Blocks :  
Description
Hi,

I've a table with 2K records and using SWT table. However, while using the same data with TableView, I see performance issue while scrolling 2000 records in tableview. While debugging, it looks everytime a scroll is done - updateItem is called (may be generating runtime objects) and scroll is is not smooth and very sluggish. The same is not true with SWT, once data is loaded into SWT table scrolling is pretty smooth.
Please note this table updates at runtime. I want update to be called only when its underlying data changes.

Is there a way to make scroll smooth and avoid getting updateItem called everytime scroll is done ( as the data is alreay loaded once underlying data got changed)?I would prefer this to take more memory to hold state than making user feel tableview performance is poor. If you try the same with Excel  - no matter how many rows you scroll its very smooth..any ideas to improve this scroll performance?

Comments
Hi Jonathan, Is there a way i can attach my code as ZIP here?
27-02-2013

@Daya: using setStyle is not the recommended way of styling your user interface, as this requires the style text to be re-parsed at runtime, and if your tick is every one second and it is on potentially hundreds of nodes, that is a lot of parsing that needs to be done. A better solution is to move the style information to a CSS file and modify css styleclasses on the relevant nodes. This will remove the need to parse. If you want you can email me a small self-contained application based on your code and I will help improve it offline. @Martin: I think this bug really falls into my domain now, rather than yours. Are you happy for me to reassign or do you still feel it relates to your work too?
25-02-2013

Just a note, the tick is one per sec for every instrument and there could be 50-100 instrument updates every sec...although it works well with SWT..seemless.
22-02-2013

I tried to run with a test data with 50 trades and most of these trades are colored (based on market tick) and (color+its underlying data) in table changes with every tick. I found scrollbar almost hung and cant move if table is full screen although the screen updates at backend correctly... But it doesnt allow to select rows or scroll move. With small window showing 8-9 trades it works and allows to scroll with no issue. -i tried to remove setstyle and it looked good (but app is a real time app and cannot leave without it) -if table is static its all good ..no issues I am really disappointed with this TableView and so much of time spent and notw stuck..i thought it would be lovely next generation table supporting real time desktop apps.... i thought it would be *atleast" or better near in performance to ktable/nattable etc.
22-02-2013

I tried to run with a test data with 50 trades and most of these trades are colored (based on market tick) and (color+its underlying data) in table changes with every tick. I found scrollbar almost hung and cant move if table is full screen although the screen updates at backend correctly... But it doesnt allow to select rows or scroll move. With small window showing 8-9 trades it works and allows to scroll with no issue. -i tried to remove setstyle and it looked good (but app is a real time app and cannot leave without it) -if table is static its all good ..no issues I am really disappointed with this TableView and so much of time spent and notw stuck..i thought it would be lovely next generation table supporting real time desktop apps.... i thought it would be *atleast" or better near in performance to ktable/nattable etc.
22-02-2013

So there are two optimisations you should consider: 1) Can you please test whether performance returns to normal if you comment out the setStyle(...) line? 2) The instanceof check is not free and will have a performance penalty, and in the code above it seems unnecessary - can't you simply do setText(item.toString())? If so the entire if / else statement is redundant. At present you should update the items list from the FX thread using Platform. Your long running tasks should not run on the FX thread.
21-02-2013

Hi Jonathan, As soon as, the callback is removed it works good. Please find the code, the idea of this code is to color each row acting as a trade and highlight (background & foreground) based on market tick updates for each row ( approx updates are received 1 per sec). I was trying to do the same through row callback , but it looks it doesnt support row based text color setting(although background color works well) and hence am using below cell based - ccyCol.setCellFactory(new Callback<TableColumn<TableViewRow,Object>, TableCell<TableViewRow,Object>>(){ @Override public TableCell<TableViewRow, Object> call(TableColumn<TableViewRow, Object> arg0) { TableCell<TableViewRow, Object> cell = new TableCell<TableViewRow, Object>(){ public void updateItem(final Object item, boolean empty) { super.updateItem(item, empty); TableRow<TableViewRow> row =getTableRow(); if(row!=null) { TableViewRow tableViewRow = row.getItem(); if(tableViewRow!=null){ setStyle(tableViewRow.getStyle()); if(item!=null){ if(item instanceof String){ setText((String)item); } else{ setText(Double.toString((Double)item)); } } } } } }; return cell; } }); A question - I'm trying to update table's observableList from UI FX UI thread using Platform, cn confirm if this is correct or i can update table data from any thread?
21-02-2013

updateItem is called frequently as the cells are reused and must represent the correct values. Because updateItem is known to be called frequently it needs to be a very optimised method when you override it. I have users of TableView that have 100k + TableView rows in a single TableView without issue, so I am doubtful 2000 rows will be much of an issue (considering the vast bulk of them are not even being rendered anyway). The main advice I can give is to remove the custom cell factory - does it still scroll slowly? If it scrolls fast then it is your cell factory implementation. If you provide the cell factory code I can take a look and offer suggestions, but in general the suggestion is to not create new objects inside the updateItem method (rather create them in the constructor and reuse them wisely inside updateItem).
20-02-2013

From user perspective of this component, clearly its "non-linear scrolling". I think it has to be smooth or the sensitivity of scroll to has to be taken care with data with 2k records.
19-02-2013

As far as I know, these cells are being reused when scrolling the TableView, so not every table item has it's own TableCell, only those who are visible have. updateItem on TableCell is expected to be called when scrolling. Added Jonathan to the watch list if he wants to comment.
19-02-2013

We register a setCellFactory with table columns. Everytime a scroll updateItem gets called - column.setCellFactory(new Callback<TableColumn<TableViewRow,String>, TableCell<TableViewRow,String>>(){ @Override public TableCell<TableViewRow, String> call(TableColumn<TableViewRow, String> arg0) { TableCell<TableViewRow, String> cell = new TableCell<TableViewRow, String>(){ public void updateItem(final String item, boolean empty) {} I think this is making the glitch in scroll to update screen and casuing non-linear scroll movement?
19-02-2013

I'm not sure what do you mean. Is there some callback on the TableView that gets called on scrolling, but it shouldn't? I don't see any updateItems there, isn't it called differently?
19-02-2013

Thanks Martin for looking into this. The basic idea am looking for is to not to call updateItems onces its data is updated and not on every scoll. For e.g SWT KTABLE or excel sheet(with thousands of rows colored..) - its scrolling is just so smooth and we dont see any glitch in traversal. Is there a way I can block this from calling because the underlying data is already updated.
19-02-2013

The optimization was actually done only for scrollPane (see RT-22424). The problem with ListView, TableView, etc. is that it's not just the scrolling that's happening, there are also changes to the children in the skin. it's quite complicated to correctly detect such changes as TableView/ListView scrolling. We might try to extend this optimization to TableView and ListView, but I think it would require some special markers in the API to mark the node as scrolling node. Otherwise, it would require deep analysis on how the children changed and move + how the clip / group was translated, which might consume significant amount of processing power if done on the whole tree, on each pulse.
19-02-2013

Hi, I'm currently using JDk 1.6 with JavaFX 2.2. Is there anyway to get a fix for this in JavaFX current release support for JDK 1.6 upgrading to JDk 8 is long way ..? Any other way to manually handled it in the current code?
19-02-2013

What version of JDK / JavaFX are you using? An optimization was done in this area in FX 8 which is included in JDK 8 early access builds. You might want to try that.
18-02-2013