jME-TTF - Formatting Text
Latest
jME-TTF-v2.2.2.zip: Download
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.

Designed by Adam T. Ryder