Word wrap in Labels etc

Have had a look at Lemur Gems and Javadoc but can’t see anything related to word wrap in labels or other components. Is this feature available?
Thanks.

1 Like

Not currently… and it’s a pretty big oversight on my part. I will add it to my short term to-do list and maybe get it in this weekend.

Sorry… keep bugging me about it, please. :slight_smile: I need to push out a new release anyway… long overdue.

1 Like

Thank you. It will allow me to make some reasonable progress on my project as it currently stands. Looking forward to it.

:+1:

1 Like

Curious… do you build Lemur from source or do you use the release jars that I upload?

I’ll be adding the word wrap mode support today but I’m trying to prioritize cutting a release. It’s not as trivial as it sounds because I’m straddling the line between two JME releases (3.0 and the future 3.1). I need to branch to accommodate but I’d love to push that off a bit. :slight_smile:

1 Like

Also, if you can describe your particular use case then that would help me make sure that I’m hitting the right spots.

So, to spam my own thread…

This turns out to be a little trickier than one might think. I mean, I can pretty easily support it in the ‘dumb’ way that BitmapText does (‘dumb’ not casting aspersions in this case just saying that there are almost no ‘smarts’ involved in the logic) but I feel like it might not be what most users would want when they think about word wrapping.

The tricky part is how wrapping interacts with the auto layout.

BitmapText does word wrapping in a very simple way. If you specify a ‘box’ for the text then it will wrap to try to stay in that box… potentially pushing out the bottom.

Lemur lays out GUI elements by first asking them their preferred size. In the case of BitmapText, this preferred size would be without word wrap because it is specifically bypassed in order to get a proper size. Thus one long string will just appear to the layout code as a really wide component.

Now, the layout may then smack it back down to a reasonable size and then word wrapping could wrap… but then the layout didn’t have a chance to know about the new vertical size and thus things might be squished with other GUI elements.

The use case that can sort of be handled is where the developer has specified a specific size for some outer component and there are few other children to compete with. Otherwise, if there are lots of other children then the layout could still be strange.

So, when in doubt, I do what I always do and remind myself what Swing does in this particular case. Swing doesn’t. At all. I always thought that was sort of strange but a) never encountered a use-case when I needed it, and b) hadn’t thought through the implications I’ve just discovered above. They have a completely separate GUI element if you want to have wrapped text in a ‘label’ style component (JTextArea).

Now, things like edit panels could have some notion of a “width” that is separate from their layout size. I think any proper wrapping policy would have to incorporate a concept of ‘text width’ to play nice with layouts. Lemur’s multiline edit support doesn’t have this yet but presumably it could if the issues are solved.

With all of that, I’m really tempted to create a separate ‘wrapped text model’ concept and have a separate text GUI element for when you want something like a Label but with word wrapping support. Incorporating word wrapping into all of the Label-based GUI elements will be problematic, I think. Furthermore, I think it makes less sense for Buttons and other classic Label use-cases.

In this spit-balled design, I’d add a TextWrapPolicy class that could split text based on customized split patterns. (Maybe you want to split on only some kinds of white space or characters or whatever.) I’d add support for TextWrapPolicy to DocumentModel (which would need it for navigation anyway). I’d also perhaps create something similar to Swing’s JTextArea for displaying read-only text with word wrap (or just make TextField support read-only views or something).

These GUI elements would internally keep two versions of the string. One that is the original and one that has been wrap-split and recomposed with line feeds in it (the existing GUI elements already support multiline text with line feeds.) Then these new GUI elements would just use the existing internal TextComponent with the recomposed text.

Would having to use a separate TextArea type of GUI element meet your use cases?

I really am curious because I will meet this issue in my own game in the next month or so and the above would work for me… because the word-wrapped fields are very specific (description text, etc.) and can be trivially bound by some logical text width. I just don’t know if it meets all cases.

1 Like

Hi … and thanks for looking into this. It sounds quite cool, although it seems to be more involved than I had imagined.

Personally, I include a downloaded pre-compiled jar into my projects. I think I got it from jME3 user contributions. I’m not sure if it is current or out of date, but I have had no problems thus far, so I’m fairly happy with doing it that way.

As for my use case. Well, it’s fairly simple really. Just left-justified text that wraps on spaces. If it could handle carriage returns, that would be cool, since I could add large amounts of text that contains carriage returns without needing to create cascading labels.

You mentioned a read-only jTextArea … yeah … that is the kind of thing I’m looking for.

For me, the word-wrapping label would be used to contain prose for a story telling feature, where the user can read info relating to the project’s theme or story. I guess others could use it for help screens, intro narratives or whatever.

I hope these few comments are helpful. And thank you for the effort put into jME3, Lemur and Zay-ES, plus docs and examples. Much appreciated.

I ran into this problem a while back and solved it the “dumb” way for now.

One different use case I ran into was with table columns where wrapping was not an option. Setting the BitMapText line wrap mode to clip was what I needed. However the results were still not exactly what I wanted. For example using a spring grid layout like the below only the last column would clip the text.

new SpringGridLayout(Axis.Y, Axis.X, FillMode.Even, FillMode.Last);

It would be cool if there was a optional minimum width for text fields and anything after that could be clipped or wrapped if the parents size or layout requires.

1 Like

It seems like you might have been hitting the exact chicken and egg problems I described… but maybe I also misunderstood.

For the table columns, you did or did not want word wrap? The text edit fields set the wrap mode to Clip (in fact, I feel like I added the clip option myself for exactly that use-case but I could be misremembering)… I should probably do the same for labels and such because auto-wrapping is a bad idea in 99% of the cases I can think of.

Sorry I was unclear.

I meant that in my particular case I didn’t want my table rows spanning over multiple lines. Having said that I also didn’t want to have cell B2 with a really long name causing the B column to expand to fit all text and leaving column D with nothing.

To expand a little more…
The table/grid I created acts as an overview from which a user interacts with different entities. To that end each cell is actually a button. With a parent window of a fixed size Ideally each column/cell should have a minimum size with the option to expand to fit content if the space is available. If any cell cannot fit its content then the text should be clipped.

You can kind of achieve this atm with a spring grid layout with fill mode even however it resizes all cells evenly which can result in undesired outcomes. (If you have a cell with a single digit as its contents it will be resized by the layout and clipped making it unreadable for example), It would be good to force a minimum size before resizing can occur so that small cells remain readable and cells containing longer strings can be resized and clipped more heavily to compensate.

Anyway you look at it though I guess my particular use case won’t come up very often

1 Like

I think it kind of does but it’s also not an easy one to solve reliably. Even Swing doesn’t do this right as the minimum size essentially just tells the component when to collapse completely. :smile:

In the end, no matter what the child GUI element wants, what the layout tells it will be law because there may not be enough room for all of the children, minimum size or not.

I’ve always planned to make it easier to customize how the spring layout chooses to allocate it’s sizes with the current FillMode being an indicator of default behavior. I know in my own usage, I’ve had at least a few cases where I subclassed the layout to implement weighted() or distribute() differently for a particular GUI element.

In your use-case, I wonder if proportional might be a little better than even… simply because at least then the adjustments will be made based on the relative size of the children. Your tiny columns may end up being too tiny, though.

I fully agree with you about text clipping. It was an oversight on my part that label (and by extension button) are not clipping their text.

Someday, maybe JME will support clip rectangles which would at least solve some of the by-character issues in 2D GUIs. (3D GUIs must deal with things as now.)

You are right proportional does give a bit better result but it is still not ideal.

Originally I took a look at the layouts to see if I could customize them to my needs. Then I realised I could spend the time optimizing this one small thing or I could actually write the rest of the game to display in that overview panel so it just became another //TODO

:slight_smile: That’s very wise. Besides, I will provide an easier way to fix that in the future. I just have to know about the issues in order to fix them… so this thread has been good. I should probably see about having a place to track these things.

Any progress regarding text wrapping in text-area-style labels? :smile:

1 Like

Not yet but thanks for reminding me.

1 Like

Hello! :slight_smile: How is it going for text clipping? Can’t find any mention in https://github.com/jMonkeyEngine-Contributions/Lemur/blob/master/release/Lemur-changelog.txt and it’s been some years, so thought I’d ask.

Which text clipping issue? The one where JME can’t easily solve the problem or the one where BitmapText is broken?

Edit: I don’t mean to sound flip… but I don’t remember which issue exactly. There have been several I think.

Ah, I appologize for not being clear, it was some deep night by then :slight_smile: My approach to this question was about the wrapping modes, as they come in most of other software:

  • No wrap – the text is printed as it is
  • Word wrap – the text is wrapped by a word
  • Clip – the text is simply clipped to not extend beyond the container, any side

I am interested in both modes 2 and 3. However, now I’m thinking more and realizing that:

  • The mode “word wrap” is already implemented (and it’s there in the changes doc, version 1.7.1), so maybe there’s nothing to add
  • And the mode “clip” is probably not relevant to this topic, because technically it would be a totally different thing, especially in OpenGL.

So I guess, that answer to the “word wrap” one is “yes, try it out, and ask if there are any particular questions”, and the conversation on the “clip” mode is a whole different topic and what should be done – is to better have it in its own thread or one of the existing ones? :slight_smile:

I don’t think the existing wrapping support exposes the wrap modes that BitmapText supports yet. I suspect it may always ‘clip’ on character.

Probably Lemur needs to expose a wrap mode…

Actually, it looks like the default is whatever BitmapText’s default wrap mode is.

I spend some time on this (very close) issue during the last 3 days.
I have a Listbox with a fixed width (so I called setPreferredSize()) somewhere). And I need to check the textlenght because each time the text is to long it is clipping. Without setting a size the text wont clip, but the element is stretched.

I hope I dont write something wrong:

Lemur textfields use a Textentrycomponent
In TextentryComponent the clipmode is set to

Buttons are extended Labels and both use a Textcomponent. In Textcomponents a

 this.bitmapText = new BitmapText(font);

is called during creation. And BitMapText has a setLineWrapMode method.

@noncom I believe if you dont have set a size for an element, the text is not cliped but the element is stretched.
If you have set a size the text is wrapped, not by word but by character.
If you work with labels you might need to

  1. find a size (e.g. use getVisibleWidth() from TextEntryComponent as a inspiration)
  2. and then you set your text. The text will clip, once it extends the element size.

Textfields work a bit differently. Yes they do stretch an element if the text is to big (see the single line examples in lemur library and write a longer text) but the multiline textfields is having linebreaks and scrolling available.

1 Like