Text formatting in jME-TTF is performed by the
StringContainer class. The
StringContainer class has a number of constructors with varying degrees of parameters, be sure to check the documentation to see the different options available. Here we will use a basic constructor which will instantiate a
StringContainer with a number of default values:
//Create a Rectangle to define the area to conform the text.
com.jme3.font.Rectangle textBox = new com.jme3.font.Rectangle(0, 480, 640, 480);
StringContainer sc = new StringContainer(ttf, "Hello\nWorld", 0, textBox);
This will instantiate a
StringContainer for the given text using the
TrueTypeFont stored in the
ttf variable, zero kerning, a default horizontal alignment of
Align.Left, vertical alignment of
VAlign.Top, wrap mode of
WrapMode.NoWrap and "..." ellipsis which will be appended to the end of a clipped line, although with
WrapMode.NoWrap no lines will be clipped.
A call to
TrueTypeFont.getFormattedText(StringContainer stringContainer, ColorRGBA color) will result in a
TrueTypeContainer aligned to the top left of the 640x480 display. The
TrueTypeContainer's
getLocalTranslation() will return x and y values equal to the supplied
Rectangle's x and y values, this will always be the case regardless of other formatting parameters.
Formatting information such as
StringContainer.getTextWidth() or
StringContainer.getLineCount() will not be available until the first call to
StringContainer.getLines(). Likewise changes to the formatting after calling
StringContainer.getLines() will not take effect until
StringContainer.getLines() is again called. Once that method is called all information relating to the formatted text, such as width and height, will become available. The
getLines() method is called automatically by the
TrueTypeContainer constructor when it is created and returned by the
TrueTypeFont.getFormattedText(StringContainer stringContainer, ColorRGBA color) method.
TrueTypeContainer extends
Node.
If you've already obtained a
TrueTypeContainer for your text you can just call the
TrueTypeContainer.updateGeometry() method after updating the
StringContainer to re-create the geometry reflecting any changes.
TrueTypeContainer ttc = ttf.getFormattedText(sc, ColorRGBA.Blue);
guiNode.attachChild(ttc);
sc.setVerticalAlignment(VAlign.Center);
sc.setAlignment(Align.Center);
ttc.updateGeometry();
Now the text will be centered both horizontally and vertically on our 640x480 display. The
getLocalTranslation() method of the
TrueTypeContainer returned by
TrueTypeFont.getFormattedText(StringContainer stringContainer, ColorRGBA color) will still return an x value of zero and y value of 480 as defined by our
Rectangle.
Now let's change a few parameters:
sc.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut id erat cursus libero faucibus tempor id ut odio. Donec ullamcorper orci risus, sit amet posuere risus venenatis in. Maecenas lectus quam, vulputate vitae dui non, malesuada aliquam massa. Vivamus bibendum quam in libero elementum, sed tristique nunc rhoncus. Vestibulum ornare eros sit amet justo vulputate, quis sagittis leo sagittis. Donec odio ipsum, scelerisque eget pellentesque et, dignissim vitae lectus. Aenean at nisi convallis, commodo erat et, commodo ipsum. Nullam ullamcorper ante quis ipsum placerat, eget fermentum magna aliquet. Ut ac mattis sapien. Praesent eu ex lectus. Vivamus vestibulum laoreet hendrerit. Maecenas non rhoncus orci.");
sc.setWrapMode(WrapMode.WordClip);
sc.setVerticalAlignment(VAlign.Top);
sc.setAlignment(Align.Left);
sc.setTextBox(new Rectangle(160, 360, 320, 240));
ttc.updateGeometry();
//The texture atlas may have been updated here so you'll need to update the texture on the material to reflect the changes. Consider adding a AtlasListener to the TrueTypeFont so you are notified when the atlas is modified. This is only necessary for bitmap texts, this step can be omitted for mesh texts.
ttc.getMaterial().setTexture("Texture", ((TrueTypeBMP)ttf).getAtlas());
//The Geometry's translation will not be updated to reflect the Rectangle's new x and y values, do this yourself.
ttc.setLocalTranslation(160, 360, 0);
The
WordClip wrap mode will constrain the supplied text to the width of the supplied
Rectangle by wrapping text to the next line when it reaches the edge of our
Rectangle. The
WordClip mode will attempt to wrap the text between words, if a word is too long to fit on one line it will be broken and wrapped. The
WordClip and
CharClip wrap modes also constrain text to the height of our
Rectangle. If the next line will not fit inside the
Rectangle it will be removed and an ellipsis appended to the last visible line.
Char and
Word wrap modes also exist which will wrap the text while ignoring the
Rectangle's height. The
Clip mode will constrain the text to a single line appending an ellipsis where the text is clipped.