Danny Lo
Danny Lo

Reputation: 1583

SWT table with custom editors gets messed up on resizing

I use a table to display 5 columns. The 3rd and 5th contain custom widgets and the 4th is an editable one. Everything looks fine on the first appearance of the window:

enter image description here

However if I resize the window a little bit, the widgets inside of the table get moved to the wrong places.

enter image description here

To make the table look right again it's enough to set the focus into it.

Here's an MCVE which reproduces this problem:

import java.util.ArrayList;

import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

public class TableTest
    extends ApplicationWindow
{
    private Table table;
    ArrayList<TableDescription> tableDescriptions = new ArrayList<TableTest.TableDescription>();

    public class TableDescription
    {
        private String name;
        private String type;
        public TableDescription(String name, String type)
        {
            this.name = name;
            this.type = type;
        }
        public String getName()
        {
            return name;
        }
        public String getType()
        {
            return type;
        }
    }

    public TableTest()
    {
        super(null);

        // Test data
        tableDescriptions.add(new TableDescription("Rev_Id", "bigint"));
        tableDescriptions.add(new TableDescription("Entity_Name", "varchar"));
    }

    @Override
    protected Control createContents(Composite parent)
    {
        Composite container = new Composite(parent, SWT.NONE);
        container.setLayout(new FillLayout(SWT.HORIZONTAL));

        table = new Table(container, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        GridLayout layout = new GridLayout();
        table.setLayout(layout);

        String[] titles = {"Column name", "Column type", "Visbility", "GUI name", "GUI type"};
        for (int i = 0; i < titles.length; i++)
        {
            final TableColumn column = new TableColumn(table, SWT.NONE);
            column.setText(titles[i]);
        }

        int[] columnsWidths = new int[]{100, 100, 50, 100, 95};

        for (TableDescription tableDescription : tableDescriptions)
        {
            TableItem item = new TableItem(table, SWT.NONE);
            item.setText(0, tableDescription.getName());
            item.setText(1, tableDescription.getType());
            item.setText(3, tableDescription.getName().replaceAll("_", " "));
        }

        for (int i = 0; i < table.getColumnCount(); i++)
        {
            table.getColumn(i).setWidth(columnsWidths[i]);
        }

        // Listener which sets the row heights. It adds editors on the
        // second event, to place them accordingly to the new cell sizes.
        // Then it removes itself.
        table.addListener(SWT.MeasureItem, new Listener()
        {
            boolean rowHeightSet;

            public void handleEvent(Event event)
            {
                if (!rowHeightSet)
                {
                    rowHeightSet = true;
                    event.height = 25;
                }
                else
                {
                    addEditors(tableDescriptions);
                    table.removeListener(SWT.MeasureItem, this);
                }
            }
        });

        return container;
    }

    private void addEditors(ArrayList<TableDescription> tableDescriptions)
    {
        for (int i = 0; i < tableDescriptions.size(); i++)
        {
            TableItem item = table.getItem(i);
            TableEditor editor = new TableEditor(table);
            Button checkButton = new Button(table, SWT.CHECK);
            checkButton.setSelection(true);
            checkButton.pack();
            editor.minimumWidth = checkButton.getSize().x;
            editor.horizontalAlignment = SWT.CENTER;
            editor.setEditor(checkButton, item, 2);
            item.setData("checkButtonEditor", editor);
            editor = new TableEditor(table);
            Combo box = new Combo(table, SWT.READ_ONLY);
            box.pack();
            editor.minimumWidth = box.getSize().x;
            editor.horizontalAlignment = SWT.LEFT;
            editor.setEditor(box, item, 4);
            item.setData("comboBoxEditor", editor);
        }
    }

    public static void main(String args[])
    {
        try
        {
            TableTest window = new TableTest();
            window.setBlockOnOpen(true);
            window.open();
            Display.getCurrent().dispose();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Any thoughts on how that issue can be solved?

Upvotes: 1

Views: 1190

Answers (1)

Baz
Baz

Reputation: 36894

Heh, found the solution by accident :) I was looking at your code and thinking: "Why does he apply a GridLayout to the table?"

Removed it and tada! It works.

So just remove these two lines and you should be fine:

GridLayout layout = new GridLayout();
table.setLayout(layout);

Upvotes: 2

Related Questions