A simple TextLabel

I made a TextLabel that extends Quad, for when you want to put text in your scene.



You supply a string, an AWT font, foreground and background color.

The string will be drawn onto the Quad (can handle new line breaks).

The Quads shape and size will adjust to the string.



import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.StringTokenizer;
/**
 *
 * @author Rik
 */
public class TextLabel extends Quad{

Nice one, I was looking for something like that!



I found it helpful to change the BufferedImage.TYPE_INT_RGB to BufferedImage.TYPE_INT_ARGB so that the image supports alpha for transparent backgrounds.

I was looking for something like this too!

I'm just wondering: Is this method fast enough to modify/replace string dynamically (eg setString, append)? Without generating too many garbage collectible objects?

I'm glad you found use for it :slight_smile:


lex said:

I'm just wondering: Is this method fast enough to modify/replace string dynamically (eg setString, append)? Without generating too many garbage collectible objects?


I dont know. How many is too many? Currently I'm using it dynamically, creating a new TextLabel for every update.

You could also use JMEDesktop and attach a JTextpane or something but I don't know which method would be the most efficient.

I'm finding that when I create new TextLabels I get a noticeable pause in updates (~500ms). I think there's also some jagginess issues - OpenGL always wants to scale the textures to a power of 2, and I'm not sure it does it very well  :?



But, it's working!  :smiley:

Thanks for pointing out the jagginess issue. In this version it's taken care of:



I create the BufferedImage with a power of two-size from the start so that the texture doesn't get rescaled. Then I adjust the texture coordinates so that the text fits the quad like before.



Also, you do not need to call the constructor to update the TextLabel anymore. Just call setTextString(String textString), or setTextString(String textString, Font font);



import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.geom.BufferUtils;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.nio.FloatBuffer;
import java.util.StringTokenizer;
/**
 *
 * @author Rik
 */
public class TextLabel extends Quad{

That's much better! Performance seems better too (although I still have a small lag on creation).



I have a slightly modified version, where I ask for a label with a specifed height and or width, which I'll post once I've folded it back into your version.



Also, setting 



graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);



Helps with the smoothness of text no end.

Good work!

I just came across this discussion:

http://www.jmonkeyengine.com/jmeforum/index.php?topic=3413.0



The approach seems to work much quicker, but the code in there doesn't quite work for me. Seems like a direction worth exploring, though!

Has anyone used this successfully in jME2?