Auto Adjust Label Bounds in Template Canvas

I have a template canvas in which I add multiple instances of a sub-template to form a grid, much like a table (see my previous post, here: Dynamic UI Layout ), however, I want the label within the sub-template to demand that the sub-template use more visual space within the template canvas based on the amount of text in the label. Is there any way to do this, or am I stuck trying to predict how much space I'll need? I ask as there is one field in that table that is basically a description which can be as short as 1 word, or as long as a paragraph, and the longer ones simply cut off the text that exceeds the visual bounds given, currently.

Worst comes to worst, I can just make it so clicking it opens a popup with the full text, but would prefer the former, if possible.

Manipulations like this are what make the canvas so useful. A couple of clarification questions:
• Is this an initialization thing, or does the text periodically change in a way that requires adjustment?
• What is meant by sub-template?

Labels will never wrap text, so miglayout will try to honor the component's preferred size within the overall bounds.
If you want multi line text, you have to use a text area, but text areas have an internal scroll pane so their preferred size calculations get weird.

Are you able to post any of your project, as self contained as possible? It would be a lot easier to offer specific advice if we were able to see exactly what you've got.

That's not entirely correct. In Vision, labels will automatically wrap the text if the text is prefaced with an html tag:
image

Result:
image

Currently, it's programmatically inserted via a button using this code:

canvas.templates = system.dataset.toDataSet(header,rows)

with the "rows" being a basic data-set, an array of arrays as it could be called, meant to fit the static template canvas dataset columns shown in the header:

header = ["name","template","layout","x","y","width","height","parameters"]

This part I knew from JLabels in Java, and am currently using it. The issue I'm running into is that I'd like to control the label width, while allowing the height to adapt to fit the text within, though even without controlling width, I can't seem to get it to adjust the way I'd like.

An example "rows" dataset converted via the canvas.templates = system.dataset.toDataSet(header,rows) line above:

rows.append(["TID" + str(num),"LabelTemplate","grow,cell 0 0 1 1,w " + str(system.tag.read("[Client]ColumnWidths/Col0Width").value) + "px",0,0,None,None,'{"labelText":"<html>' + str(CSVReader.rowData[0])+ '</html>"}'])
#"Plain-text" version below:
rows.append(["TID1","LabelTemplate","grow,cell 0 0 1 1,w 50px",0,0,None,None,'{"labelText":"<html>Some random amount of text here!</html>"} ]

Side Note: I'm still playing around with Span vs Cell to lay things out, but had something else inhibiting my progress that I just found and corrected.

To build this, I currently use a basic template with a template canvas in it stretched to fill the working area (this is what's placed in the window, directly), then the "sub-template" is just a template with a label inside of it, stretched to fill the working area of the sub-template and the background filled with a line border applied (multiple instances of this are added when the dataset is applied to the canvas). When I load it into the template canvas, I want to restrict its width (so as not to have a horizontal scrollbar on a half-screen, but also not fill the entire width when maximized), but have its height expand automatically whenever there is a line-break (vertical scroll is allowable). If I make the working area of the template, say, h 50px, I can fit about 3-4 lines of text, any more just "disappear" outside the visual area and a single line has a bunch of empty space below it. As you can see below, it doesn't auto-adjust the height as desired:
image
As a side question... is there a way to add internal component padding? So the text isn't right up against the border?

Yeah, that's true, but as @Devin_Golberg is discovering, I think that breaks the preferredSize calculation(s) a bit.

If you don't want to use a text area, you could maybe hack something together to display a JIDE StyledLabel (available on the classpath automatically); see the JIDE Common Layer developer guide. Actually instantiating one as via a Vision component is a bit of a complex problem.

The generic Swing way is by adding an empty border (or constructing a compound border with whatever border you want, plus an empty border for padding).

In Mig, you can do it with the gap keyword on a component.

1 Like

IIRC, I achieved this in Java by overriding the preferred size method to inject my own custom width while leaving the height to be handled by the default code. That said, I vaguely remember also having to use a JTextArea with scrolling disabled to get it to resize (since text area has wrap capability without html tags, it can figure space needed automatically when scrolling is turned off, I believe).

Since it's rare for there to be more than 1-2 lines, I might be OK with using a text area with a vertical scrollbar, in this case; especially if it will auto-hide if it's not needed. Will give this a shot!

Think I had tried gap, but the gap was on the outside of the line border, not inside of it, which is the same in Java, hence the compound border BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(Color.black), BorderFactory.createEmptyBorder(5,5,5,5)) for a 5px internal padding. That said, I might know a way to get the same effect, now that you reminded me of compound border... Will try it and post my findings.

So, I was unable to find a way to make a pseudo compound border that wasn't excessively bloated, resource-wise. The thought was to use a container to produce the border and background with a label within it, but there's no option to put any form of insets (aka gap) on either a label nor a container, that I can find, and trying to statically offset the label using size and position creates non-uniform spacing when the template is stretch more or less based on the MigLayout settings of the template canvas, which just ends up looking weird.

In regards to the TextArea, though, with line-wrap enabled and then setting the rows and columns to 0, only the vertical scrollbar will show up, and only when it is needed to see all of the text (I also made it uneditable with a line border). That said, I'm still unable to get either the label or the text area to size dynamically the way I want when scrolling is enabled on the underlying template canvas. I'm used to Java's preferred size that tries to compact the component into as little space as possible while still showing everything within it. Unless I'm missing something, Ignition seems to only be capable of maintaining a given height/width/aspect ratio, a set size, or growing to as large as is possible while staying within the confines of the container (while accounting for other objects in said container); which can get to be an indefinitely large size when scrollable containers are used (though this usually means you're doing something wrong in how you're building your UI).