Event when CSS is applied

Tomas Mikula tomas.mikula at gmail.com
Wed Feb 18 07:34:53 UTC 2015

OK, so the major problem I see is that a lot of layout is done outside
layoutChildren, using code like this:

needlePane = new Pane();
needlePane.widthProperty().addListener( (observable) -> {

What I think should be done is, instead of trying to hack around Pane,
create class NeedlePane that extends Region and overrides
layoutChildren. It would create its children in the constructor (or
take them as constructor parameters), add them to its children list
right in the constructor and never clear them, and position them on
the layout pass (i.e. in layoutChildren).

The problem you have (or one of the problems) is that in the layout
pass, when lStackPane sets the size of needlePane, drawNeedlePane() is
triggered which clears needlePane's children (this is shortly after
the CSS was applied to them, just before the layout pass that is
currently in progress), then adds them quickly back, but without CSS

Another problem is that in Skin's layoutChilren, you are trying to
layout grand-grand-children. You should only be laying out direct
children. The code reads

protected void layoutChildren(double arg0, double arg1, double arg2,
double arg3) {
    super.layoutChildren(arg0, arg1, arg2, arg3);

This is what it does:

super.layoutChildren() resizes and positions lStackPane. It does not
call layout() on it yet.

The rest of the methods are positioning grand-children of that lStackPane.

When the layoutChildren call returns, layout() will be called on all
children, i.e. on lStackPane. Within lStackPane.layout(),
lStackPane.layoutChildren() is called, which sets the width and height
of needlePane, which triggers drawNeedlePane() (if size changed),
which clears the children and adds them back. When
lStackPane.layoutChildren() returns, needlePane.layout() is called,
within which needlePane.layoutChildren() is called. This is where you
should do the layout for valueText.

Hope this helps.

On Wed, Feb 18, 2015 at 1:46 AM, Tom Eugelink <tbee at tbee.org> wrote:
> Sure! I'm very curious what can be done better.
> https://github.com/JFXtras/jfxtras-labs/blob/8.0/src/main/java/jfxtras/labs/internal/scene/control/skin/gauge/linear/SimpleMetroArcGaugeSkin.java
> You can also checkout the sources, you should be able to run
> SimpleMetroArcGaugeTrial1.java without any other dependencies. Some of the
> other classes will have compilation errors, but the gauge should run.
> Tom
> On 17-2-2015 23:15, Tomas Mikula wrote:
>> Maybe if you can post the relevant part of your layoutChildren method
>> so that others can look if they can suggest an improvement.
>> Tomas
>> On Tue, Feb 17, 2015 at 5:05 PM, Tom Eugelink <tbee at tbee.org> wrote:
>>> On 17-2-2015 20:01, David Grieve wrote:
>>>> On 2/17/15 1:30 PM, Tom Eugelink wrote:
>>>>> The control is a codewise polish up one of Gerrit's gauges (with
>>>>> permission!) and pulled into JFXtras (with tests and all). For an idea
>>>>> on
>>>>> what we are talking about:
>>>>> https://www.youtube.com/watch?v=RH5X1uBu1d8
>>>>> The process of centering the Text in that circle is a bit more complex.
>>>>> 1. The value may vary between a min and max value.
>>>>> 2. I want the Text to automatically utilize the maximum available
>>>>> space,
>>>>> but not change size when a longer or shorter text is shown.
>>>>> To do this I have two additional Text nodes that have the same styling
>>>>> as
>>>>> the Text node (so these are on the scene, but not visible, otherwise
>>>>> CSS is
>>>>> not applied). These two text nodes get the maximum and minimum possible
>>>>> value set. Then on these two some pythagoras is applied and in that way
>>>>> one
>>>>> can determine the scale factor so that the value will never be rendered
>>>>> outside of the circle. Then the actual to-be-rendered value can be
>>>>> placed
>>>>> into the Text node and positioned in the centre of the circle.
>>>>> The problem is that a lot of these calculations depend on the CSS
>>>>> styling. What font is set? Bold or not? So I can only do these
>>>>> calculcation
>>>>> after the CSS has been applied. This unfortunately is not yet the case
>>>>> when
>>>>> the skin is instantiated. This means that if I do not used the
>>>>> layoutChildren, the initial presentation is totally off, untill the
>>>>> first
>>>>> min/max/value is set.
>>>> Have you looked at the javadoc for Node#applyCss()?
>>> I did just now and tried calling that and layout when the skin is being
>>> instantiated, but apparently things are not setup right yet.
>>> Maybe layoutChildren with bound checking is the way to go.

More information about the openjfx-dev mailing list