You may be right. Aligning a wrapped, vertically-aligned label to a baseline doesn't seem like a very common requirement, but the baseline of a FlowPane, for example, could easily change as its width constraint changes: different components may comprise the first row, which would ultimately define the flow pane's baseline for that width. Since FlowPanes are likely to be used as fields in a form (which may have the "fill" style set to true), this could happen fairly often.

The problem is that calculating a baseline in these cases will be computationally intensive. It will require the component to basically perform the same math twice - once to calculate its preferred size, and again to determine the baseline given a size. The logic will need to be applied again during layout.

If we do go ahead and include both width and height arguments to getBaseline(), we'll probably want to cache the values in Component like we do for preferred size. We can probably hook into the existing mechanism pretty easily.

One alternative would be to drop the width argument for now, and introduce both width and height arguments in a later update. The existing signature could then potentially delegate to the two-argument signature, passing -1 for each to indicate an unconstrained value. This way, we wouldn't break backwards compatibility.


On Nov 5, 2009, at 4:14 PM, Todd Volkert wrote:

I thought of a case where both the width & height would come into play in a baseline calculation. Let's imagine a Label with a vertical alignment of CENTER and wrapText set to true. Here are some baselines that it should
report:

1. If it's asked for its baseline given its preferred size, it doesn't need to wrap, and the vertical alignment isn't in play. It reports the
  baseline of its single line if text.
2. If it's asked for its baseline given its preferred width and more than its preferred height, it doesn't wrap, but it does need to center itself vertically. It reports the baseline of its single line of text, plus its
  vertical offset due to the vertical alignment.
3. If it's asked for its baseline given less than its preferred width and more than its preferred height, it needs to both wrap its text and center itself vertically. It reports the baseline of its first line of text, plus the vertical offset due to the vertical alignment. In this case, the vertical offset will be less than in #2 because there are more lines of
  text.

If we dropped the width argument and went with just the height argument, we
wouldn't satisfy #3 above.

Thus, I think the correct thing to do is to pass both a width and height
argument to getBaseline().

-T

On Wed, Nov 4, 2009 at 3:49 PM, Greg Brown <[email protected]> wrote:

I can't think of one. I think a height argument would be sufficient (even if we don't update the FlowPane and Form skins to take it into account right
away).

On Wednesday, November 04, 2009, at 03:42PM, "Todd Volkert" <
[email protected]> wrote:
It's certainly more comprehensive that having getBaseline() take no
arguments. We don't really want to suffer from a design flaw years down
the
road, so better to cover our bases now. In this aspect, I agree. The
only
question is what value a width argument could possibly provide...

-T

On Wed, Nov 4, 2009 at 2:16 PM, Greg Brown <[email protected]> wrote:

Apparently, the AWT Component#getBaseline() method takes a width and a
height. I don't think both are necessary, but it might be good to
include
the height argument, because this will allow a container to determine
its
preferred size based on the baselines of its children.

Take FlowPane, for example - FlowPaneSkin#getPreferredSize() might ask
each
subcomponent for its preferred size and then determine its own preferred
height using the size/position of the subcomponents relative to the
baseline
(it doesn't currently do this, but it probably should). It would call
getBaseline(preferredHeight) on each subcomponent to determine the
baseline
value, then calculate its preferred height as the difference between the
components whose top and bottom are farthest apart.

TerraFormSkin might do something similar. Rather than assuming that a
field
row is simply the max. value of the label and field heights, it could
take
the baselines into account and determine the row height based on their
relative positions.

Thoughts?


On Wednesday, November 04, 2009, at 01:11PM, "Greg Brown" <
[email protected]>
wrote:
After some additional thought, it does seem as though eliminating the
width argument to getBaseline() might be a good idea. Baselines are
primarily a layout construct - they don't generally have any bearing on preferred size calculations (and, after thinking about it a bit, I'm not even sure that they can). As a result, getBaseline() probably doesn't
need a
width constraint.

G

On Wednesday, November 04, 2009, at 10:22AM, "Todd Volkert" <
[email protected]> wrote:
Actually, I'm starting to think your original assertion may be
correct.
I
looked deeper into the problem with push button's baseline calculation
as
it
pertains to PIVOT-338, and the buttons in the component explorer that
don't
report their baselines correctly aren't even given an aspect ratio --
*they're
given an explicit preferred size*.  The design of the existing
baseline
calculation method implicitly assumes that you'll be given your
preferred
size.

Example: <PushButton wtkx:id="button" buttonData="foo"
preferredHeight="100"
/>

button.getBaseline(-1) will return something like 10, when in fact the
baseline will end up being something like 55.

Perhaps my assertion that a component's baseline may affect the
preferred
size of its parent caters to an edge case condition that we really
shouldn't
worry about. I think I'm leaning towards re-defining the method to be
getBaseline(), and having it pertain to the existing size of the
component.

Thoughts?
-T

On Tue, Nov 3, 2009 at 8:06 AM, Greg Brown <[email protected]> wrote:

Ah, yes, I think that may be true. Containers must calculate their preferred size before they are actually given a size and called to
lay
out.
It stands to reason that baseline alignment may factor into that
calculation, so you are right that we can't simplify it in this way.


On Nov 3, 2009, at 7:56 AM, Todd Volkert wrote:

Containers that can align to baseline may need to know the
baselines
of
their child components when calculating preferred size (where it's
going
to
place the children may affect the preferred size of the container).
Since
the container has may have a width constraint in mind when it asks
its
children for their preferred size, it stands to reason that the
same
width
constraint will apply when it asks the children for their
baselines.
Thus,
I think the baseline calculation has to take a width constraint.

From a high level, it seems like this should be OK, since baseline
alignment

isn't so much about setting size as it is aligning things after
their
sizes
have been set.


I think what I'm saying above is that this assumption may not be
correct.
Is it possible that a child's baseline will need to be calculated
during
the
preferred size calculation of its parent (and would affect the
preferred
size of the parent)? I want to say we have to assume yes, but I'm
not
100%
sure.

-T












Reply via email to