Right aligned Text

Dunno if anyone else needs this, but I did. Would be great if we could get this in or some similar functionality in case I didn't do it in the most efficient manner since I did it very quick and dirty. Anyway, here's what I did:




/*
 * Copyright (c) 2003-2005 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
 *   may be used to endorse or promote products derived from this software
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.jme.scene;

import com.jme.intersection.CollisionResults;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.system.DisplaySystem;

/**
 *
 * <code>Text</code> allows text to be displayed on the screen. The
 * renderstate of this Geometry must be a valid font texture.
 *
 * @author Mark Powell
 * @version $Id: Text.java,v 1.22 2005/10/15 13:22:51 irrisor Exp $
 */
public class Text extends Geometry {

    private static final long serialVersionUID = 1L;

    private StringBuffer text;

    private ColorRGBA textColor = new ColorRGBA();
   
    protected boolean isAlignedRight = false;

    /**
     * Creates a texture object that starts with the given text.
     *
     * @see com.jme.util.TextureManager
     * @param name
     *            the name of the scene element. This is required for
     *            identification and comparision purposes.
     * @param text
     *            The text to show.
     */
    public Text(String name, String text) {
        super(name);
        setCullMode(Spatial.CULL_NEVER);
        this.text = new StringBuffer(text);
        setRenderQueueMode(Renderer.QUEUE_ORTHO);
    }
   
    public Text(String name, String text, boolean isAlignedRight){
       this(name, text);
       this.isAlignedRight = isAlignedRight;
       print(text);
    }
   
    public void setIsAlignedRight(boolean isAlignedRight){
       this.isAlignedRight = isAlignedRight;
    }
   
    public boolean getIsAlignedRight(){
       return isAlignedRight;
    }

    /**
     *
     * <code>print</code> sets the text to be rendered on the next render
     * pass.
     *
     * @param text
     *            the text to display.
     */
    public void print(String text) {
       if (isAlignedRight == true){
          this.setLocalTranslation( new Vector3f( this.getLocalTranslation().x + getWidth(), this.getLocalTranslation().y, 0.0f));
            this.text.replace(0, this.text.length(), text);
           this.setLocalTranslation( new Vector3f( this.getLocalTranslation().x - getWidth(), this.getLocalTranslation().y, 0.0f));
        } else {
           this.text.replace(0, this.text.length(), text);
        }
    }

    /**
     * Sets the text to be rendered on the next render. This function is a more
     * efficient version of print(String).
     *
     * @param text
     *            The text to display.
     */
    public void print(StringBuffer text) {
        this.text.setLength(0);
        this.text.append(text);
    }

    /**
     *
     * <code>getText</code> retrieves the text string of this
     * <code>Text</code> object.
     *
     * @return the text string of this object.
     */
    public StringBuffer getText() {
        return text;
    }

    /**
     * <code>draw</code> calls super to set the render state then calls the
     * renderer to display the text string.
     *
     * @param r
     *            the renderer used to display the text.
     */
    public void draw(Renderer r) {
        if (!r.isProcessingQueue()) {
            if (r.checkAndAdd(this)) return;
        }
        super.draw(r);
        r.draw(this);
    }

    /**
     * Sets the color of the text.
     *
     * @param color
     *            Color to set.
     */
    public void setTextColor(ColorRGBA color) {
        textColor.set(color);
    }

    /**
     * Returns the current text color.
     *
     * @return Current text color.
     */
    public ColorRGBA getTextColor() {
        return textColor;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.jme.scene.Spatial#hasCollision(com.jme.scene.Spatial,
     *      com.jme.intersection.CollisionResults)
     */
    public void findCollisions(Spatial scene, CollisionResults results) {
        //Do nothing.
    }

    public boolean hasCollision(Spatial scene, boolean checkTriangles) {
        return false;
    }

    public float getWidth() {
        float rVal = 10f * text.length() * worldScale.x;
        return rVal;
    }

    public float getHeight() {
        float rVal = 16f * worldScale.y;
        return rVal;
    }

    /**
     * @return a Text with {@link #DEFAULT_FONT} and correct alpha state
     * @param name name of the spatial
     */
    public static Text createDefaultTextLabel( String name ) {
        return createDefaultTextLabel( name, "" );
    }
   
    public static Text createDefaultTextLabel( String name, boolean isAlignedRight ) {
        return createDefaultTextLabel( name, "", isAlignedRight);
       
    }

    /**
     * @return a Text with {@link #DEFAULT_FONT} and correct alpha state
     * @param name name of the spatial
     */
    public static Text createDefaultTextLabel( String name, String initialText ) {
        return createDefaultTextLabel(name, initialText, false);
    }
   
    public static Text createDefaultTextLabel( String name, String initialText, boolean isAlignedRight ) {
        Text text = new Text( name, initialText, isAlignedRight );
        text.setCullMode( Spatial.CULL_NEVER );
        text.setRenderState( getDefaultFontTextureState() );
        text.setRenderState( getFontAlpha() );
        return text;
    }

    /*
    * @return an alpha states for allowing 'black' to be transparent
    */
    private static AlphaState getFontAlpha() {
        AlphaState as1 = DisplaySystem.getDisplaySystem().getRenderer().createAlphaState();
        as1.setBlendEnabled( true );
        as1.setSrcFunction( AlphaState.SB_SRC_ALPHA );
        as1.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );
        as1.setTestEnabled( true );
        as1.setTestFunction( AlphaState.TF_GREATER );
        return as1;
    }

    /**
     * texture state for the default font.
     */
    private static TextureState defaultFontTextureState;

    /**
     * A default font cantained in the jME library.
     */
    public static final String DEFAULT_FONT = "com/jme/app/defaultfont.tga";

    /**
     * Creates the texture state if not created before.
     * @return texture state for the default font
     */
    private static TextureState getDefaultFontTextureState() {
        if ( defaultFontTextureState == null ) {
            defaultFontTextureState = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
            defaultFontTextureState.setTexture( TextureManager.loadTexture( SimpleGame.class
                    .getClassLoader().getResource( DEFAULT_FONT ), Texture.MM_LINEAR,
                    Texture.FM_LINEAR ) );
            defaultFontTextureState.setEnabled( true );
        }
        return defaultFontTextureState;
    }
}