parasietje
parasietje

Reputation: 1539

Compute the minimum size of a Composite

I need to calculate the minimum or default size of a Composite where it can display all components without clipping.

I only seem to find methods to calculate the preferred size of the Composite. This means that a Table or other scrolled composite will have a preferred size which displays the full contents without scrolling. The ScrolledComposite will immediately go into scroll mode, which is not what I want.

GridLayout manages to do this by treating the GridData hints as minimum width/height, allowing grabbing any extra space available.

The problem is related to this one: SWT - computingSize for Multi-line textfield inside ScrolledComposite

Upvotes: 1

Views: 3152

Answers (2)

Baz
Baz

Reputation: 36894

Control#computeSize(int, int) should be what you are searching for:

Point size = comp.computeSize(SWT.DEFAULT, SWT.DEFAULT);
System.out.println(size.x + " " + size.y);

Upvotes: 3

parasietje
parasietje

Reputation: 1539

I've managed to find the solution.

The key was two different things:

  1. Make sure to set the resize listener on both the content (if CHILDREN are added and layout() is called) and the ScrolledComposite (if it is resized from outside its children)
  2. Make sure to set both GridData.grab and GridData.hint. The hint will make sure the composite assumes this size when you do computeSize(), while grab makes sure it will grab any extra space that is available.

Code sample is below:

public static void main (String [] args) {
  Display display = new Display ();
  Shell shell = new Shell(display);
  ScrolledComposite sc = new ScrolledComposite(shell, SWT.NONE);
  Composite foo = new Composite(sc, SWT.NONE);
  foo.setLayout(new GridLayout(1, false));
  StyledText text = new StyledText(foo, SWT.NONE);
  text.setText("Ipsum dolor etc... \n etc... \n etc....");
  GridDataFactory.fillDefaults().grab(true, true).hint(40, 40).applyTo(text);

  Listener l = new Listener() {
     public void handleEvent(Event e) {
         Point size = sc.getSize();
         Point cUnrestrainedSize = content.computeSize(SWT.DEFAULT, SWT.DEFAULT);
         if(size.y >= cUnrestrainedSize.y && size.x >= cUnrestrainedSize.x) {
           content.setSize(size);
           return;
         }
         // does not fit
         Rectangle hostRect = getBounds();
         int border = getBorderWidth();
         hostRect.width -= 2*border;
         hostRect.width -= getVerticalBar().getSize().x;
         hostRect.height -= 2*border;
         hostRect.height -= getHorizontalBar().getSize().y;
         c.setSize(
           Math.max(cUnrestrainedSize.x, hostRect.width),
           Math.max(cUnrestrainedSize.y, hostRect.height)
         );
     }
  }
  sc.addListener(SWT.Resize, l);
  foo.addListener(SWT.Resize, l);

  shell.open ();
  while (!shell.isDisposed ()) {
    if (!display.readAndDispatch ()) display.sleep ();
  }
  display.dispose ();
}

Upvotes: 1

Related Questions