Campa
Campa

Reputation: 4495

Re-align ragged-left SWT TableEditor after content updated

I injected a TableEditor inside a SWT Table, with ragged-left alignment (SWT.RIGHT). Something like:

final TableEditor editor = new TableEditor(table);
editor.horizontalAlignment = SWT.RIGHT;
editor.setEditor(toDisplay, item, 1);

toDisplay is a 2x1 GridLayout composite with two children:

My issue is: when the dynamic label updates (gets wider), the toDisplay wrapper composite shifts outside of the table column instead of realigning as a good ragged-left boy [a screenshot of this behaviour is attached: the label has no text, but rather includes an icon].

Layout data for both children is set via:

GridDataFactory.fillDefaults().create()

The button has a SelectionListener which updates the text then lays-out the parent composite.

It seems all combinations of .pack() and .layout() do not affect the editor's new position.

Any idea of what might help?


package com.stackoverflow.swt.snippets;

import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;

/**
 * Updates the width of a <code>Composite<code> inside <code>TableEditor</code>:
 * alignment of the editor is not proper after update,
 * the position of the composite shifts out on the right.
 *
 * @see https://stackoverflow.com/questions/32645683/re-align-ragged-left-swt-tableeditor-after-content-updated
 */
public class SWTDynamicRaggedLeftTableEditorSnippet {

    public static void main(String[] args) {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText(SWTDynamicRaggedLeftTableEditorSnippet.class.getSimpleName());

        // create table
        Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
        table.setLayout(new GridLayout(1, true));
        table.setLinesVisible(true);
        table.addListener(SWT.MeasureItem, new Listener() {
            @Override
            public void handleEvent(Event event) {
                event.height = 40;
            }
        });

        new TableItem(table, SWT.NONE).setText("Tizio");
        new TableItem(table, SWT.NONE).setText("Caio");
        new TableItem(table, SWT.NONE).setText("Sempronio");

        // add editor
        for (TableItem item : table.getItems()) {
+++         final TableEditor editor = new TableEditor(table);

            /*
             * Parent Composite:
             * +----------------------------+
             * |+-------+ +----------------+|
             * || Label | |    Button      ||
             * |+-------+ +----------------+|
             * +----------------------------+
             */
            final Composite composite = new Composite(table, SWT.NONE);
            composite.setLayout(new GridLayout(2, false));
            composite.setLayoutData(GridDataFactory.fillDefaults().create());

            // 1st child: Label (empty now)
            final Label label = new Label(composite, SWT.NONE);
            label.setLayoutData(GridDataFactory.fillDefaults().create());

            // 2nd child: the Button
            Button button = new Button(composite, SWT.PUSH);
            button.setText(ButtonText.OFF.name());
            button.setLayoutData(GridDataFactory.fillDefaults().create());
            button.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    // update Button
                    label.setText("And suddenly pops out this wonderful sentence");
                    button.setText(((ButtonText) ButtonText.valueOf(button.getText()).toggle()).name());
                    // uncover the Label:
---                 composite.layout();
+++                 editor.minimumWidth = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+++                 editor.layout();
                }
            });
            composite.pack();

            /*
             * The ragged-left Table Editor
             */
---         final TableEditor editor = new TableEditor(table);
            editor.minimumWidth = button.getSize().x;
            editor.horizontalAlignment = SWT.RIGHT;
            editor.grabVertical = true;
            editor.grabHorizontal = false;
            editor.setEditor(composite, item, 0);
            editor.layout();
        }

        // size
        Rectangle clientArea = shell.getClientArea();
        table.setBounds(clientArea.x, clientArea.y, 500, 300);

        // read & dispatch
        shell.pack();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
    }
    //  (support stuff) :

    interface Toggleable {
        Toggleable toggle();
    }

    static enum ButtonText implements Toggleable {
        ON {
            @Override
            public ButtonText toggle() {
                return OFF;
            }
        },
        OFF {
            @Override
            public ButtonText toggle() {
                return ON;
            }
        }
    };
}

Upvotes: 1

Views: 318

Answers (1)

Baz
Baz

Reputation: 36894

You need to update the TableEditor's width and then re-layout it:

editor.minimumWidth = composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; 
editor.layout();

This will compute the required width, set it and the invoke a .layout() on the parent.

Upvotes: 1

Related Questions