Bizarre text issue - hyphens disappear

I’ve been noticing for a while that hyphens (and I think underscores, but I can’t reproduce it on demand) don’t always display in my elements. I looked into this more tonight, and I was able to reproduce it in a panel just by resizing it:

[java]
package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.math.Vector2f;
import tonegod.gui.controls.windows.Panel;
import tonegod.gui.core.Screen;

public class Main extends SimpleApplication {

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}

@Override
public void simpleInitApp() {
    Screen screen = new Screen(this);
    guiNode.addControl(screen);

    flyCam.setEnabled(false);
    
    Panel backPanel = new Panel(screen, new Vector2f(300,500), new Vector2f(500,100));
    screen.addElement(backPanel);
    backPanel.setFontSize(28);
    backPanel.setText("The slightly red orange was distinctly reddish-orange.");
}

}
[/java]

If you size the panel up and down, you should see the hyphen sometimes appear and sometimes not.

Is there something else I need to be doing?

To be more clear since it seems I can’t edit - this occurs when scaling the panel horizontally (X axis) causes the text wrapping to change. Some wrap layouts display the hyphen (e.g. all on one line), and some don’t (e.g. broken after “distinctly”).

@Mentalepsy said: To be more clear since it seems I can't edit - this occurs when scaling the panel horizontally (X axis) causes the text wrapping to change. Some wrap layouts display the hyphen (e.g. all on one line), and some don't (e.g. broken after "distinctly").

The library uses BitmapText currently for it’s text elements. Unless it’s a font issue (which I doubt if you can see it originally), I’m not sure if there is anything I can do about this.

The other option you have, is to start playing around with TextElement… which doesn’t use BitmapText. Though, this is still a work in progress… works pretty good already… but still in process. It supports some very basic html tags, etc.

Are there any examples around on how to use TextElement? I found this thread, but it’s not much help. I can get one line of text to show up, but that’s about it. I assume I’ve just gone about it completely wrong.

@Mentalepsy said: Are there any examples around on how to use TextElement? I found this thread, but it's not much help. I can get one line of text to show up, but that's about it. I assume I've just gone about it completely wrong.

There isn’t… until. now. One sec. I just wrote it a little while ago.

Try this out… it’ll give you an idea of what it can do now and what it will be in the future:

[java]
TextElement el = new TextElement(screen, UIDUtil.getUID(), Vector2f.ZERO, new Vector2f(300,200),
screen.getStyle(“Button”).getVector4f(“resizeBorders”),
screen.getStyle(“Button”).getString(“defaultImg”),
assetManager.loadFont(screen.getStyle(“Font”).getString(“testFont”))) {
@Override
public void onUpdate(float tpf) {
rollText(tpf, this);
}
@Override
public void onEffectStart() { }
@Override
public void onEffectStop() {
resetRoll(this);
}
};
el.setTileImage(true);
el.setIgnoreMouse(false);
el.setIsResizable(true);
el.setIsMovable(true);
el.setFontSize(32);
el.setTextVAlign(VAlign.Top);
el.setTextAlign(Align.Left);
el.setTextWrap(LineWrapMode.Word);
el.setUseTextClipping(true);
el.setFontColor(ColorRGBA.Green);

	el.setText("This <i>is <u>a test</u></i>.<p align=Center>This <i>is</i> a good test.</p>This is also a decently composed test.  This is a test.</br></br>This is a good test.  This is <u>also a decently</u> composed test.  This is a test.<p align=Right>This is a good test.  This is also a decently composed test.  This is a test.  This is a good test.  This is also a decently composed test.</p>");
	screen.addElement(el);
	el.centerToParent();
	el.addEffect(
		new Effect(
			Effect.EffectType.FadeIn,
			Effect.EffectEvent.Show,
			2
		)
	);
	el.addEffect(
		new Effect(
			Effect.EffectType.FadeOut,
			Effect.EffectEvent.Hide,
			2
		)
	);

// And here is a generic handler for animating text... it's not well thought out... but... you'll get the idea
float rollTime = .025f;
float rotTime = .125f;

public void resetRoll(TextElement te) {
	te.setUserData("qdIndex", (Integer)0);
	te.setUserData("rollCounter", (Float)0.0f);
	for (QuadData dq : te.getAnimText().getQuads().values()) {
		dq.actions.clear();
		dq.setScale(1, 1);
		dq.setRotation(0);
	}
}

private void rollText(float tpf, TextElement te) {
	int qdIndex = 0;
	Object test = te.getUserData("qdIndex");
	if (test != null)
		qdIndex = (Integer)test;
	float rollCounter = 0;
	test = te.getUserData("rollCounter");
	if (test != null)
		rollCounter = (Float)test;
	rollCounter += tpf;
	if (rollCounter >= rollTime) {
		if (te.getAnimText().getQuadDataAt(qdIndex).actions.isEmpty()) {
			float mX = te.getAnimText().getWidth()/2;
			mX *= 3;
			mX = -mX;
			float mY = 0;
			ScaleByAction sRoll = new ScaleByAction();
			if (te == el || te == el2)	sRoll.setAmount(.6f, .85f);
			else						sRoll.setAmount(.5f, .65f);
			sRoll.setDuration(.25f);
			sRoll.setAutoReverse(true);
			te.getAnimText().getQuadDataAt(qdIndex).addAction(sRoll);
			if (te == el || te == el2) {
				RotateByAction mRoll = new RotateByAction();
				mRoll.setAmount(360);
				mRoll.setDuration(.25f);
				mRoll.setAutoReverse(false);
				te.getAnimText().getQuadDataAt(qdIndex).addAction(mRoll);
			} else {
				RotateByAction mRoll = new RotateByAction();
				mRoll.setAmount(0);
				mRoll.setDuration(.5f);
				mRoll.setAutoReverse(false);
				te.getAnimText().getQuadDataAt(qdIndex).addAction(mRoll);
			}
			qdIndex++;
			if (qdIndex == te.getAnimText().getQuads().size())
				qdIndex = 0;
			te.setUserData("qdIndex", (Integer)qdIndex);
			rollCounter = 0;
		}
	}
	te.setUserData("rollCounter", (Float)rollCounter);
}

[/java]

I think WrapMode.Character isn’t working atm. I just left it be for now, since I really can’t imagine a need for it. I’ll fix it soon if I haven’t already.

You’ll notice if you update the TextElement’s Align mode that anything inside a paragraph tag that has an inline alignment set will not be effected and continue to align according to it’s inline def.

EDIT: Also note… don’t use quotes when setting align= and make sure the value is spelled as it is in BitmapFont.Align enum. i.e. Center for center (Capital letter and all). I haven’t really spent any time with the parsing yet, so it’s particular in that sense.

EDIT 2: Eh… you can get rid of the setTileImage(true) line above… and the style info. I needed a visual reference for where the resize borders were while I was working on it.

Hah… I guess I have more to say.

In the rollText crap above, there is absolutely no need to create a new temporal action each time… you can either: a) set up a template and clone it. b) create a specific action for a specific animelement/quaddata/whatever and just call reset() on it. I was being ultra lazy, as it had nothing to do with what I was working on.

That’s terrific, thank you. I was able to get this running, so I’ll study it tonight (no time right now). I still have two questions:

  1. What is el2? It’s not defined anywhere. I had to comment this out since I don’t know what to do with it.
  2. Your sample text works fine, but when I replace it with different text, I get an array index out of bounds exception. The exception points to el.setText but seems to be caused by setting LineWrapMode.Word. I was having this same problem last night. Using a different line wrap mode works fine.

Here’s the exception:

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main] java.lang.ArrayIndexOutOfBoundsException: 0 at tonegod.gui.framework.core.AnimText.placeWord(AnimText.java:534) at tonegod.gui.framework.core.AnimText.wrapTextToWord(AnimText.java:482) at tonegod.gui.controls.text.TextElement.setTextWrap(TextElement.java:197) at tonegod.gui.controls.text.TextElement.setText(TextElement.java:154)

And here’s how I set the text:
[java]
el.setText(“The reddish orange is distinctly reddish-orange. The reddish orange is distinctly reddish-orange. The reddish orange is distinctly reddish-orange. The reddish orange is distinctly reddish-orange.”);
[/java]

Alright, I figured out a lot of what was causing me trouble last night.

First, the array index exception with word wrap - apparently it gets thrown when I don’t have any <u> tags in my text. Ya rly! The presence or absence of other tags seems to make no difference. As far as I can tell, there just has to be an underline in there somewhere.

Second, it seems that <br> and <p> are only applied when using LineWrapMode.Word. Is this intended?

Third, apparently italics don’t register if the </i> is at the very end of the string. You need another character after it. For example, this works:

[java]
el.setText("<i>italics</i> ");
[/java]

But this does not:

[java]
el.setText("<i>italics</i>");
[/java]

Underline seems fine, though.

EDIT: Would it be better if I post these issues in the original TextElement thread?

1 Like

Here is just fine.

  1. Thanks for pointing this out! This definitely should not be the case…
  2. Only because it’s not quite finished and I was using WrapMode.Word as a default starting point =) It won’t be this way in the final.
  3. This one I was aware of… and eventually, this won’t be the case.

Keep em coming. This is a big help!

Another issue I found: if you end a string with <br>, the preceding character is tabbed way over. For example, this:

[java]
el.setText("<u>The reddish orange</u> is distinctly reddish-orange!!!<br>");
[/java]

produces this:

link

Another thing: is it possible to size a TextElement to the height of the text? I’m trying to put a TextElement inside a ScrollAreaAdapter, which works fine except that I can’t predict how much text there will be. This means that the scroller is either too long or not long enough for the contained text. I’ve tried a few solutions here but haven’t found one that works.

One more comment: it looks like using TextElement doesn’t solve my problem with the hyphens. It seems to work better, but the issue seems to be that the hyphen varies in brightness depending on its position, and sometimes it blends into the background. I can see this happening as I scroll this text box up and down. I tried this with another font and saw the same issue, though it wasn’t as bad.

EDIT: I tried a few more fonts. Some worked well, others didn’t. With Courier standard face, every character seemed to flicker a bit. The trick seems to be to pick a robust font that doesn’t have super-thin characters. That’s my layman’s observation anyway.

@Mentalepsy said: One more comment: it looks like using TextElement doesn't solve my problem with the hyphens. It seems to work better, but the issue seems to be that the hyphen varies in brightness depending on its position, and sometimes it blends into the background. I can see this happening as I scroll this text box up and down. I tried this with another font and saw the same issue, though it wasn't as bad.

EDIT: I tried a few more fonts. Some worked well, others didn’t. With Courier standard face, every character seemed to flicker a bit. The trick seems to be to pick a robust font that doesn’t have super-thin characters. That’s my layman’s observation anyway.

You could always alter the material for the Element.getTextElement() (probably the texture min/mag filters) until you get the desired results. However, there might not be a way around this without increasing the font size, as I believe mip mapping is not being used.

Other option is to create another bitmap font with a larger default render size. This may also stop the issue.

EDIT: Ooops… missed the edit. Yes, you are correct. This is the nature of the beast with Bitmap Font’s, unfortunately.

Thanks for the confirmation, I’ll consider it resolved.

As far as my problems with the text element inside a scroller, the best I’ve been able to do is set the same text in the scroller itself using a zero alpha font, so that it resizes itself as needed. It’s not perfect, though, since it takes up more vertical space. It looks like the vertical padding is larger in the scroller than the text element, though neither seems to be using the values I set on the font itself. For now I just reduced the font size in the scroller and it works well enough, but this will give me trouble in my scrolling text logs if I try to use TextElement there.

Is there a central place I should post any issues or requests? I see one thread for it, but it’s pretty old. My original issue here is resolved, so I’m kind of dragging it off track, plus I still have some other things to post as well.