JavaFX Content Rendering & Resizing and Font Bugs In Linux
Ty Young
youngty1997 at gmail.com
Sun Jan 6 19:15:15 UTC 2019
On 1/6/19 5:06 AM, Siddhesh Rane wrote:
> (An earlier version of this email turned out completely empty when delivered on the mailing list)
>
> I have used JavaFX on Linux since 8.0 and have never faced any serious issues.
>
> January 3, 2019 4:29 AM, "Ty Young" <youngty1997 at gmail.com> wrote:
>
>> In my attempt to write a more proper responsive JavaFX UI, I've created
>> a new JavaFX project which extensively uses DoubleBindings to force the
>> min/max width/height of various components to their parent containing
>> objects(HBox and VBox mainly) so that 1440p and 4k displays could be
>> more easily supported.
> This is not how layout is supposed to be done. The parent container calculates its computed size based on its children which takes into account min/pref/max size of children. Min/pref/max are intrinsic properties of the child irrespective of the container it is in.
> You are introducing a chicken and egg situation here by having both dimensions depend on each other. You'll get undefined behaviour.
>
> If you want children to occupy full width and height of parent, set VBox to "fill width" with Vgrow ALWAYS on children and Hbox to "fill height" and hgrow always in scene builder.
I'm well aware of how the parents size is calculated. However, the more
level top level UI components are percentage based of the entire window
so that, for example, the left button is 15% of the total window width
and the ScrollPane is 85% of the total window width. Content within the
ScrollPane is also reduced to 85% of the ScrollPane's width.
This percentage based UI scaling has been done in website for years.
There isn't anything particularly different here. Content should
theoretically be resized in a top down fashion on any resize event after
first creation. If this causes unnecessary resizing events then why
exactly does the DoubleBinding API even exist to begin with? This is
always going to be an issue when you use it.
>
>> While it does allow for easier 1440p and 4k
>> scaling, JavaFX itself seems to have /extremely/ horrible content
>> rendering & resizing bugs to the point where the application becomes
>> usable.
> If you are taking about buttons being extremely small on high definition screens on Linux, you can set root font size in your css to >1.0em. Alternatively you can set default font size with - Dcom.sun.javafx.fontSize=18 where default is 12. You can try it for any javafx application by setting _JAVA_OPTIONS=-Dcom.sun.javafx.fontSize=18 on the command line.
As far as I'm aware JavaFX uses the system default font size unless told
otherwise. As such, font should scale perfectly on native displays.
Problem is, this is not true when using xrandr to scale the viewport nor
does it affect padding or spacing between UI elements so while it'll
supposedly look fine using a more responsive application design like
i've been doing it will be less 1:1 scaling. Extra handling is required
for above 1080p scaling sadly.
Default font size is 13 according to Font.getDefault().getSize().
According to Gnome Tweaks it's supposed to be 11. Which one is right?
Who knows. Maybe using Font.getDefault().getSize() isn't a reliable way
of getting system font size but I can't immediately think of a better
way to get the actual system font size.
>
>> Multiple of the bugs can be observed by simply resizing the JavaFX
>> window. When doing so, content will seemingly struggle to keep up with
>> resizing events. As a result, white(or sometimes black) glitching can be
>> seen wherever the window is being expanded and UI components will "jump"
>> around.
> White or black bars on window expansion are not specific to javafx. I've seen that on Windows file explorer and Chrome with Gmail tab. It seems to me that the window resizing happens asynchronously so it doesn't wait for the application to have calculated layout and painted the new area. For any complex UI, the layout computation cannot keep up with window resize.
In complete honestly I've never really payed much attention to window
resizing behavior until now as I usually just keep applications
maximized. Opening various applications and resizing them shows that
while there are far more applications with glitchy and low FPS resizing,
there are also examples of applications that have no trouble resizing UI
components.
Non glitchy:
Gnome Settings(My app design is roughly based on this. It too uses
percentage based UI sizing without issue.)
Gnome Disks
QT5 Settings
GNU Octage
Only Office
Vid Cutter
Glitchy:
JavaFX apps
Netbeans
WPS Office
Steam(game client)
Given that some applications with fairly complex UI work fine I don't
really buy the "UI is just too complex!" theory/defense/excuse. Not only
does the app use bog standard JavaFX UI components but there aren't that
many on the screen at any given time. Going by behavior of ScrollPane's
glitchy horizontal bar, JavaFX doesn't even resize UI content that isn't
in a user's view anyway so the amount of UI components that needs to be
resized is fairly small(maybe 40 including TableView's subcomponents?).
>
>> Thinking that this might be problems caused by extensive use of
>> DoubleBinding, I launched SceneBuilder 10 which uses Oracle JDK 10. It
>> has all of the same UI glitching that I've encountered in my JavaFX
>> application at a lesser scale besides TableView since it doesn't use
>> TableView.
> Scene Builder is a complex application. Above point applies.
SceneBuilder's complexity is always a constant so it would stand to
reason that the glitchy resizing would also be a constant. It isn't.
Again, the glitchy behavior is seemingly dependent on the 3 things that
I mentioned.
>> Another problem is a font bug revolving around making text bold. When
>> attempting to make a label bold, the boldness is seemingly not being
>> applied to some Label text. It might work on a few Labels in a certain
>> part of the UI but completely refuse in other parts. Making things
>> weirder is the disappearing boldness of Labels after setting a new Pane
>> in the ScrollPane and switching back to a that specific pane.
> Without relevant code, we cannot comment.
<Label>.setFont(Font.font(Font.getDefault().getFamily(),
FontWeight.EXTRA_BOLD, Font.getDefault().getSize());
Just a typical setFont() call.
>
> Regards
> Siddhesh Rane
More information about the openjfx-dev
mailing list