-
Notifications
You must be signed in to change notification settings - Fork 543
8276671: Iterative layout algorithm #433
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
Conversation
|
👋 Welcome back mstr2! A progress list of the required criteria for merging this PR into |
|
Since this enhancement represents a behavioral change, and adds new API, it will need to be discussed on the openjfx-dev mailing list prior to review. A Draft PR can be helpful to illustrate what you are proposing, but the focus should be first on the problem, and then on the API changes and behavior changes you propose to address that problem. If as a result of that discussion, there is general agreement about the problem and the approach, then next step would be to focus on the API and specification changes, which will need a CSR. /reviewers 3 |
|
@kevinrushforth |
|
@kevinrushforth has indicated that a compatibility and specification (CSR) request is needed for this pull request. |
|
@mstr2 this pull request can not be integrated into git checkout feature/baselinelayout
git fetch https://git.openjdk.java.net/jfx master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push |
|
I've created a small playground app that shows a few scenarios in which a baseline-aligned layout now works as expected. Here's a screenshot of the current behavior on the left side, and the new behavior on the right side. |
726a791 to
20db216
Compare
c1d3ed5 to
f66f5d2
Compare
|
@mstr2 This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
|
@mstr2 This pull request has been inactive for more than 16 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the |
|
As mentioned in PR #1879 we should consider resurrecting this enhancement. |
This should already be available somewhere at Oracle. Anything we write up would therefore not only be repeating existing work, but be based on best guesses and reverse engineering. Also this would be mostly for developers, not specification, as the specification should not be going into details of the algorithm. Also, this has not caused a regression in my opinion. It's a fix for a bug that stopped controls from updating completely because the layout system got into a bad state (controls needing updating, but this not being propagated up the scene graph). This has however exposed a new bug, which was always there, but slightly harder to trigger (as the system would go into a bad state before it could happen, ie, a bug hiding another bug). That 2nd bug is that code in I already knew of that bug (as the |
True. I think every kind of documentation (but especially for us developers) would be good to have somewhere (not buried) for such a core functionality that is the inner workings of the layout.
I agree 100%! I just wanted to say here that we may need to rethink the current design, part of which is included in this PR.
Also agree, the code was questionable. IMO it is very good that this was found and we have a good fix and understanding (I already checked the PR), which should also improve performance while making the layout (expectations) more stable - a very good thing! :) |

This PR fixes a long-standing issue with baseline layout computation in JavaFX as mentioned in JDK-8090261 and makes baseline layouts more consistent and dependable. There may be other filed bugs or enhancement requests that relate to the same fundamental issue.
How the baseline offset is computed
Generally, the value returned from
Node.getBaselineOffset()is one of the following:BASELINE_OFFSET_SAME_AS_HEIGHTThe reason for this is that there is a circular dependency between the height of a resizable control and its baseline: in order to know the baseline offset, one must know the size of the control; and in order to know the size of the control, one must know the baseline offset. The special constant
BASELINE_OFFSET_SAME_AS_HEIGHTbasically means: we don't know the baseline offset at this time, but when it comes to layouting the node, we just use whatever the height of the resizable node turns out to be.However, some resizable controls (
Labeledbeing the most prominent) must report an actual baseline value in order to work meaningfully, but this value can't be computed consistently for the reasons mentioned (this is the cause of JDK-809261).Step 1: solving
LabeledSince we can't know the actual baseline offset of a resizable

Labeledbefore the control is laid out, we schedule another layout pass when thelayoutYproperty of theTextnode was changed during layout. Repeatedly layouting and measuring the resulting baseline offset will quickly converge to the true baseline offset of theLabeledcontrol. This is the code sample taken from JDK-8090261 before and after the change:Step 2: making baseline layouts more consistent
Even with
Labeledsolved, the more general issue is that baseline layouts often yield inconsistent results depending on which layout containers are used to compose the scene graph. In order to fix this, we need to ensure that the baseline offset of any given layout container meaningfully reflects the baseline of the nodes placed within it.This is achieved by adding
Node.isTextBaseline(), which returnstrueif the node or any of its children contain text (and thus should be the primary source when determining a baseline). Currently,Labeled,TextandTextInputControlreturntrueby default.Additionally, a new boolean property
Node.prefBaselineProperty()is introduced. This flag can be used to override the baseline source selection.The default behavior of
Parent.getBaselineOffset()is changed such that the baseline is derived from the first managed child for whichNode.isPrefBaseline()returnstrue, or if there is no such child,Node.isTextBaseline()returnstrue, or if there is no such child,Parent.getBaselineOffset()returns a value other thanBASELINE_OFFSET_SAME_AS_HEIGHT.The difference can be seen when comparing the old layout behavior to the new layout behavior:

Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jfx pull/433/head:pull/433$ git checkout pull/433Update a local copy of the PR:
$ git checkout pull/433$ git pull https://git.openjdk.org/jfx pull/433/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 433View PR using the GUI difftool:
$ git pr show -t 433Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/433.diff