3
votes

I want to position three text labels at an exact specific point on the screen (in this case on top to illustrate the problem easier). So I have:

LabelStyle labelStyle = new LabelStyle(new BitmapFont(), new Color(1,1,1,1));

Label textFullSize = new Label("Line 1 of 4\nLine 2 of 4\nLine 3 of 4\nLine 4 of 4", labelStyle);
textFullSize.setFontScale(1);
textFullSize.setPosition(0, Gdx.graphics.getHeight()-textFullSize.getPrefHeight());
stage.addActor(textFullSize);

Label textHalfSize = new Label("Line small 1 of 4\nLine small 2 of 4\nLine small 3 of 4\nLine small 4 of 4", labelStyle);
textHalfSize.setFontScale(0.5f);
textHalfSize.setPosition(Gdx.graphics.getWidth()*0.15f, Gdx.graphics.getHeight()-textHalfSize.getPrefHeight());
stage.addActor(textHalfSize);       

Label textDoubleSize = new Label("Line large 1 of 4\nLine large 2 of 4\nLine large 3 of 4\nLine large 4 of 4", labelStyle);
textDoubleSize.setFontScale(2);
textDoubleSize.setPosition(Gdx.graphics.getWidth()*0.25f, Gdx.graphics.getHeight()-textDoubleSize.getPrefHeight());
stage.addActor(textDoubleSize);

But here is what I'm getting: wrong label positioning

Why is this happening? Why can't getPrefHeight() return the correct height of the label? How can I position labels without that?

1

1 Answers

0
votes

When you change a label's scale, its new size is not automatically called until stage.act() is called. This is to avoid wasting a lot of computation recalculating the size of everything if you make multiple changes that will affect size.

But you can force it to update its size by calling layout() on the label. Then you'll get the proper value when you call getPrefHeight(). For example:

Label textHalfSize = new Label("Line small 1 of 4\nLine small 2 of 4\nLine small 3 of 4\nLine small 4 of 4", labelStyle);
textHalfSize.setFontScale(0.5f);
textHalfSize.layout();
textHalfSize.setPosition(Gdx.graphics.getWidth()*0.15f, Gdx.graphics.getHeight()-textHalfSize.getPrefHeight());
stage.addActor(textHalfSize);  

In general, this is not wasteful, because it will internally mark its layout as updated, so in most cases it won't have to recalculate this stuff in stage.act().