-1

I am trying to create a vertically scrolled box with text in multiple label widgets but I can seem to get the label text to wrap at all.

enter image description here

I've narrowed it down to this minimal example to replicate the issue.

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class Main {
    public static void main(String[] args) {
        // Create window.
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText("Test");
        shell.setSize(320, 240);
        shell.setLayout(new FillLayout());

        // Create scroll container.
        final ScrolledComposite scrollContainer = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.BORDER);

        // Create scroll area.
        final Composite scrollArea = new Composite(scrollContainer, SWT.NONE);
        scrollArea.setLayout(new RowLayout(SWT.VERTICAL));

        // Setup scrolling.
        scrollContainer.setExpandHorizontal(true);
        scrollContainer.setExpandVertical(true);
        scrollContainer.addListener(SWT.Resize, (event) -> {
            int width = scrollContainer.getClientArea().width;
            Point size = scrollArea.computeSize(width, SWT.DEFAULT);
            scrollContainer.setMinSize(size);
            System.out.println("Size: " + size.x + "x" + size.y);
        });
        scrollContainer.setContent(scrollArea);

        // Create paragraph.
        Label paragraph = new Label(scrollArea, SWT.WRAP);
        paragraph.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");

        // Display window.
        //shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }
}

When I run this, the size logged will be 316x23 so the width looks correct but the height is only calculated to fit one line. If I throw in a shell.pack() before the shell.open(), the size logged is 2648x23 and the window reflects that size. However, when I shrink it the text still doesn't wrap. How do you properly setup a ScrolledComposite to vertically scroll and wrap text? I suspect that the width of the scrollArea is not being propagated to its child paragraph.

Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144

2 Answers2

2

I think the RowLayout you are using is not dealing with wrapping the label. Using GridLayout with a width hint for the Label seems to work:

// Create scroll area.
final Composite scrollArea = new Composite(scrollContainer, SWT.NONE);
scrollArea.setLayout(new GridLayout());

// Setup scrolling.
scrollContainer.setExpandHorizontal(true);
scrollContainer.setExpandVertical(true);

// Create paragraph.
final Label paragraph = new Label(scrollArea, SWT.WRAP);
paragraph.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");

// Layout data for label, width a bit smaller than the shell
final GridData data = new GridData(SWT.LEAD, SWT.TOP, false, false);
data.widthHint = shell.getSize().x - 10;
paragraph.setLayoutData(data);

// Can do compute size immediately
final Point size = scrollArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
scrollContainer.setMinSize(size);
System.out.println("Size: " + size.x + "x" + size.y);

scrollContainer.setContent(scrollArea);

An alternative would be to use a read-only Text control with scroll bars specified - this does not need to be in a ScrolledComposite. All the above would be replaced with:

final Text paragraph = new Text(shell, SWT.WRAP | SWT.V_SCROLL | SWT.H_SCROLL);
paragraph.setEditable(false);
paragraph.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
greg-449
  • 109,219
  • 232
  • 102
  • 145
0

To support text wrapping on window resize, I had update the width hint inside of the resize listener.

enter image description here

// Create scroll container.
final ScrolledComposite scrollContainer = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.BORDER);
scrollContainer.setExpandHorizontal(true);
scrollContainer.setExpandVertical(true);

// Create scroll area.
final Composite scrollArea = new Composite(scrollContainer, SWT.NONE);
final GridLayout scrollLayout = new GridLayout();
scrollArea.setLayout(scrollLayout);

// Create paragraph.
Label paragraph = new Label(scrollArea, SWT.WRAP);
paragraph.setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.");
final GridData paragraphData = new GridData(SWT.LEAD, SWT.TOP, false, false);
paragraph.setLayoutData(paragraphData);

// Setup scrolling.
scrollContainer.addListener(SWT.Resize, (event) -> {
  int width = scrollContainer.getClientArea().width;
  paragraphData.widthHint = width - scrollLayout.marginWidth; // Add padding to right.
  Point size = scrollArea.computeSize(SWT.DEFAULT, SWT.DEFAULT);
  scrollContainer.setMinSize(size);
});

scrollContainer.setContent(scrollArea);
Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144