-
Notifications
You must be signed in to change notification settings - Fork 457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] 8277785: ListView scrollTo jumps to wrong location when CellHeight is changed #712
Conversation
👋 Welcome back jvos! A progress list of the required criteria for merging this PR into |
Webrevs
|
…ns would lead to empty cells at the end of the view, while there are available cells before the beginning of the view.
… case there are enough leading cells available.
There was a problem in ListView, in which cells are shifted down in case there are empty cells being rendered while there are leading cells available. |
It looks like there are some failing unit tests now. |
I fixed them. |
I've added another testbutton to the testclass. The cell #2 should be at the top, but isnt. |
I don't believe that it is possible to position the content and scrollbar exactly, if the VirtualFlow estimates the size of the cells. I thought of something like this. The existing estimation logic can then be implemented as a default cell size provider. interface CellSizeProvider {
/**
* Returns the size of all cells.
* IMPORTANT: Be carefully by implementing this method. It can drastically degrade the performance of a component.
*/
double getTotalSize();
/**
* Returns the size of the cell for an item given by its index.
* IMPORTANT: Be carefully by implementing this method. It can drastically degrade the performance of a component.
*/
double getCellSize(int);
/**
* The callback which is set by the VirtualFlow. It allows to calculate the cell size for an item given by its index.
* IMPORTANT: This callback returns the exact value, but it may be slow.
*/
void setCellSizeCalculator(Function<Integer, Double> cellSizeCalculator);
} |
I agree with that observation. The mathematical perfect situation would be to pre-calculate the height of all items, so that the scrolbar position can be exact, and the content placing can be exact as well. That would be at the price of a major performance overhead for large lists. For small lists, this overhead is more acceptable. I agree that this is something that could be rather application-defined instead of having heuristics in the ListView. As a historical note, before https://bugs.openjdk.java.net/browse/JDK-8089589 was fixed, all items were considered of equali height for the position of the scrollbar. In the current case, if that precondition holds, the estimated size will be the real size, so in that case there is no need to calculate the height of every item before getting the correct total size. |
@johanvos Btw, adding the cells incrementally seems to make a difference - which is why the new test class tests both cases. It accepts various inputs of cell sizes - and should work with any inputs. It basically only works well, when the sizes are only 20s - in most other cases it fails. |
I noticed this bug as well, but in my case even when the
Click the button until there is a scroll bar, it always seems to scroll down to the second last element in the list, instead of the last. Interestingly, changing the line from Just thought I would share this in case this would help find the issue. |
There are a number of paths possible that first calculate an offset/position, and later do a layoutChildren pass. The offset/position calculations (e.g. in scrollTo calls) assume a specific estimatedSize. If that size is changed between the first call and the layoutChildren logic, the result will not look as intended. Hence, we should avoid updating the estimated size at the start of the layout phase. We can do it safely at the end. Thanks to Zeiss and Florian Kirmaier for providing additional tests.
The later reported issues were due to the fact that the estimatedSize got updated during the layoutChildren call. That makes things much more complicated and leads to discrepancies. I disabled the updates to the estimated size during the layoutChildren call, so that all operations that are happening in that call are using a consistent value of the estimated size. We now pass all the tests added by @FlorianKirmaier on the JBS issue . Those tests are great regression tests. |
@johanvos So there must be something the tests are missing. I haven't found out yet what. |
Hi @johanvos, I've updated the TestClass once more. You can find it on the ticket. There are 2 cases that seem to not work properly yet. 1.) If the elements are very big, the tests seem to fail - but it only happens if the scene is layouted again. 2.) On Click, the element gets selected and the VirtualFlow "jumps around". Both cases were also reproducible with the original test application. Btw, can I somehow become an official reviewer for this PR? |
…he estimate. This reduces annoying effects when re-layouting cells without relevant changes. This should not be done when we don't have a valid estimate yet/anymore, or when the absoluteOffset is set to infinity (which may happen if the position is set to infinity, which is the case in some calls in Skin classes).
To give some background: the reason for this PR is to fix (real or perceived) regression after https://bugs.openjdk.java.net/browse/JDK-8089589 was fixed. The approach taken in JDK-8089589 is to gradually improve the information about the different sizes of the cells, and it fixes the weird jumps (at the very least, it avoids jumping upwards when scrolling down and vice versa). However, this gradual improvements can cause other visual disturbances. Initially, we improved the parameters whenever a layoutChildren was invoked. However, this leads to undesired effects in case layoutChildren is invoked again after a specific goal is asked (e.g. scroll to a cell with a specific index). A consequence of the gradual improvement is that the algorithm realizes the first cell need to move upwards or downwards a bit, but that will destroy the state where a cell should be positioned exactly at a given position. I'm moving this PR to draft until I have more confirmation about the (perceived) stability. |
Thank you for the update! We've tested it, and we made good progress. 1.) Not jumping to the last cell.
2.) Jumps on height changes 3.) Jumps on click after height changes For 2 and 3, I have some test-code, which can be added to the end of the method "verifyListViewScrollTo":
|
…ing. This avoid resizing cells after their position has been laid out, leading to misalignments. Relaxed some tests that check on the number of invocations on updateItem. We heavily use the accumcell for calculating sizes, and that cell is released every time, leading to a call to updateItem as well (but this call should not do any CPU intensive work)
Hi Johan, thanks for the update of the PR. From the "scrollTo" perspective, everything seems to work now. Big thanks. Hope you find the last remaining glitches. Thanks list-view-scrolling.mp4 |
I guess this should be closed in favor of #808 ? |
Closed in favor of #808 |
When the size of a ListCell is changed and a scrollTo method is invoked without having a layout calculation in between, the old (wrong) size is used to calculcate the total estimate. This happens e.g. when the size is changed in the
updateItem
method.This PR will immediately resize the cell and sets the new value in the cache containing the cellsizes.
Progress
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx pull/712/head:pull/712
$ git checkout pull/712
Update a local copy of the PR:
$ git checkout pull/712
$ git pull https://git.openjdk.org/jfx pull/712/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 712
View PR using the GUI difftool:
$ git pr show -t 712
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/712.diff