mgarin / weblaf

WebLaF is a fully open-source Look & Feel and component library written in pure Java for cross-platform desktop Swing applications.
http://weblookandfeel.com
GNU General Public License v3.0
1.14k stars 235 forks source link

Line spacing in WebStyledLabel #640

Closed husker-dev closed 4 years ago

husker-dev commented 4 years ago

Is it possible to change the line spacing in the WebStyledLabel?

mgarin commented 4 years ago

You can, not exactly in WebStyledLabel but in any style that contains text which visual implementation is extending AbstractStyledTextContent. For those styles you can provide a rowGap setting.

In case of WebStyledLabel specifically you'd need a separate style like this:

    <style type="styledlabel" id="large-row-gap">
        <painter>
            <decorations>
                <decoration>
                    <LabelLayout>
                        <StyledLabelText constraints="text" rowGap="15" />
                    </LabelLayout>
                </decoration>
            </decorations>
        </painter>
    </style>

StyledLabelText extends AbstractStyledTextContent so it does have that setting, but you can also replace the text content implementation in the style for any other component - like normal JLabel - to be able to configure that.

mgarin commented 4 years ago

Regarding rowGap itself - it's not exactly my implementation and I haven't tried it myself, but looking by the source code - it does seem to be properly used for the lines positioning.

Code does prevent negative value from being used though, so you can't exactly reduce the gap. Whatever you see currently is the default gap and is equal to zero rowGap value. I can potentially look into changing that part though as it might have been an unnecessary limitation.

mgarin commented 4 years ago

Also, I guess it might be a good idea to expose that setting in WebStyledLabel, it's a pretty small and easy improvement since it has it's own StyledLabelText implementation.

husker-dev commented 4 years ago

(The question is not entirely related to the original, but related to the WebStyledLabel, and I'm not sure if it applies at all to WebLaF)

Is it possible to make the WebStyledLabel height automatically increase, based on content?

It is possible to do using setPreferredHeight, but it hardcodes the size without regard to content.

image

In theory, this code should work, but something is stopping it.

new WebPanel(){{
    setLayout(new BorderLayout());

    WebStyledLabel label = new WebStyledLabel("Lots of text....");
    label.setMaximumRows(6);
    label.setMaximumHeight(80);
    label.setMinimumHeight(35);
    label.setPreferredHeight(SizeMethods.UNDEFINED);
    add(label, BorderLayout.SOUTH);
}};
mgarin commented 4 years ago

In theory, this code should work, but something is stopping it.

Unfortunately minimum/maximum methods are barely used anywhere because they don't exactly function in the way you would expect them to. Size methods were mostly designed to propose component's minimum/preferred/maximum component sizes to the underlying layout, but most components only provide preferred size and minimum/maximum are either the same or 0 and Integer.MAX_VALUE on both axis. And even when you forcefully set them - it is up to layout to use or ignore them.

In case with the WebStyledLabel - it has to provide all those sizes without actually knowing how much space it will have within the layout. Like, will there be 200px for each line? Or 400px? Without knowing that beforehand - there is no realistic way for it to properly wrap the lines and calculated width and height. So default preferred size is when all text fits into 1 long line.

That being said, there is a workaround available in WebStyledLabel for this specific case you are asking about:

public class StyledLabelExample
{
    public static void main ( final String[] args )
    {
        SwingTest.run ( new Runnable ()
        {
            @Override
            public void run ()
            {
                final WebStyledLabel label = new WebStyledLabel ( "Sample text content" );
                label.setMaximumTextWidth ( 50 );

                TestFrame.show ( label );
            }
        } );
    }
}

The setMaximumTextWidth ( int ) method will fixate maximum line width and allow WebStyledLabel to dynamically calculate the amount of rows it needs to have and the overall preferred height to fit them all in. Result:

image

I also checked the setMaximumRows ( int ) method, but it doesn't seem to play well with the previously mentioned setting (and overall it still has some issues), so I wouldn't recommend using that one.

Overall - there still are some problems with text layouting when maximum text width is specified, will see if we can find it quickly with my colleague - I have a few ideas about what might be causing it.

mgarin commented 4 years ago

We found a few different issues with various wrapping cases in AbstractStyledTextContent, @macstrace just pushed a fix for those issues - 0a39e8c - it will be available in v1.2.14 snapshot version in a few minutes.

This should fix all problems that might appear with wrapping whenever you use setMaximumTextWidth ( int ) and setMaximumRows ( int ) methods together or separately, as well as some other cases which were incorrectly wrapping or trimming text.

mgarin commented 4 years ago

So, with those fixes in mind, the way I would recommend approaching your specific case is using setMaximumTextWidth ( int ) to provide container width to the WebStyledLabel directly whenever container size changes - that is, if your container width is not static (can be changed by user or UI in runtime). Otherwise - you can simply set a fixed text width through the same method.

And in case you want to limit amount of text lines displayed - you can also use setMaximumRows ( int ) on top of the other solution. This will allow text to expand vertically until that maximum amount of rows (text lines) is reached.

mgarin commented 4 years ago

I'll close this as the question should be answered. But if you have any further related questions/issues - feel free to reopen this issue!