Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constant Width SashForm

Tags:

java

swt

My application has a SashForm with two children. I want the left child to stay the same size when the window is resized. I want the same thing Eclipse does with the Package Explorer and the main editor. When you resize the window only the text editor changes size. However, the Package Explorer is still resizeable by the sash.

I tried using the following

sashForm.addControlListener(new ControlAdapter() {
    @Override
    public void controlResized(ControlEvent e) {
        int width = sashForm.getClientArea().width;
        int[] weights = sashForm.getWeights();
        weights[1] = width - weights[0];
        sashForm.setWeights(weights);
    }
});

The problem is the width of the left size either shrinks to 0 or expands too much. It looks like the weights are updated before this is called or something.

If I set weights[0] equal to some constant it does what I want.

like image 671
EmbMicro Avatar asked May 03 '26 14:05

EmbMicro


1 Answers

I managed to get an example running that should give you an idea how to solve your problem. The thing is, that the SashForm uses weights rather than pixels. So you have to compute the percentage the left child has to occupy based on the parent size and assign the rest to the right child.

In my code example, you can specify the width of the left child and set a minimal size for the right child, such that the SashForm will always show both.

private static final int MIN_WIDTH_LEFT = 100;
private static final int MIN_WIDTH_RIGHT = 50;

public static void main(String[] args)
{
    Display display = new Display();
    final Shell shell = new Shell(display);
    shell.setText("StackOverflow");
    shell.setLayout(new FillLayout());

    final SashForm form = new SashForm(shell, SWT.HORIZONTAL);

    Button button = new Button(form, SWT.PUSH);
    button.setText("Left");

    Button buttonR = new Button(form, SWT.PUSH);
    buttonR.setText("Right");

    form.setWeights(new int[] {1, 2});

    shell.addListener(SWT.Resize, new Listener()
    {
        @Override
        public void handleEvent(Event arg0)
        {
            int width = shell.getClientArea().width;
            int[] weights = form.getWeights();

            if(width >= MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT)
            {
                weights[0] = 1000000 * MIN_WIDTH_LEFT / width;
                weights[1] = 1000000 - weights[0];
            }
            else
            {
                weights[0] = 1000000 * MIN_WIDTH_LEFT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
                weights[1] = 1000000 * MIN_WIDTH_RIGHT / (MIN_WIDTH_LEFT + MIN_WIDTH_RIGHT);
            }

            System.out.println(width + " " + Arrays.toString(weights));

            form.setWeights(weights);
        }
    });

    shell.pack();

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

This is what it looks like:

Startup:

enter image description here

After resizing:

enter image description here

When decreasing the window size until it is too small to show both minimal sizes:

enter image description here

As you can see in this case, the minimal size for the left child is ignored to still be able to show both childs.

like image 91
Baz Avatar answered May 06 '26 03:05

Baz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!