简体   繁体   中英

How to adjust the size of a TableViewer inside a GridLayout

I have a TableViewer inside a GridLayout . Everything works nice and the Table Viewer shows up as a white area with some data in it. The problem is that the white area is very high but has nearly no width. I havn't found any possibility to set the size of this viewer.

Do I need to adjust the Layout somehow? I could not find out how! The TableViewer doesn't seem to fill its cell either...

any ideas?

I wound up using a class to automatically adjust the TableViewer width based on the data.

Here's how I use the class:

    activeViewer = new TableViewer(parent,
            SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
    final Table activeTable = activeViewer.getTable();

    AutoResizeTableLayout layout = new AutoResizeTableLayout(activeTable);
    activeTable.setLayout(layout);

    layout.addColumnData(new ColumnWeightData(400));
    layout.addColumnData(new ColumnPixelData(70));

Here's the class:

public class AutoResizeTableLayout extends TableLayout implements
    ControlListener {

private final Table table;

private List<ColumnLayoutData> columns = 
    new ArrayList<ColumnLayoutData>();

private boolean autosizing = false;

public AutoResizeTableLayout(Table table) {
    this.table = table;
    table.addControlListener(this);
}

public void addColumnData(ColumnLayoutData data) {
    columns.add(data);
    super.addColumnData(data);
}

public void controlMoved(ControlEvent e) {
}

public void controlResized(ControlEvent e) {
    if (autosizing)
        return;
    autosizing = true;
    try {
        autoSizeColumns();
    } finally {
        autosizing = false;
    }
}

private void autoSizeColumns() {
    int width = table.getClientArea().width;

    // Layout is being called with an invalid value
    // the first time it is being called on Linux.
    // This method resets the layout to null,
    // so we run it only when the value is OK.
    if (width <= 1)
        return;

    TableColumn[] tableColumns = table.getColumns();
    int size = Math.min(columns.size(), tableColumns.length);
    int[] widths = new int[size];
    int fixedWidth = 0;
    int numberOfWeightColumns = 0;
    int totalWeight = 0;

    // First calc space occupied by fixed columns.
    for (int i = 0; i < size; i++) {
        ColumnLayoutData col = columns.get(i);
        if (col instanceof ColumnPixelData) {
            int pixels = ((ColumnPixelData) col).width;
            widths[i] = pixels;
            fixedWidth += pixels;
        } else if (col instanceof ColumnWeightData) {
            ColumnWeightData cw = (ColumnWeightData) col;
            numberOfWeightColumns++;
            int weight = cw.weight;
            totalWeight += weight;
        } else {
            throw new IllegalStateException
            ("Unknown column layout data");
        }
    }

    // Do we have columns that have a weight?
    if (numberOfWeightColumns > 0) {
        // Now, distribute the rest to the columns with weight.
        // Make sure there's enough room, even if we have to scroll.
        if (width < fixedWidth + totalWeight)
            width = fixedWidth + totalWeight;
        int rest = width - fixedWidth;
        int totalDistributed = 0;
        for (int i = 0; i < size; i++) {
            ColumnLayoutData col = columns.get(i);
            if (col instanceof ColumnWeightData) {
                ColumnWeightData cw = (ColumnWeightData) col;
                int weight = cw.weight;
                int pixels = totalWeight == 0 ? 0 : weight * rest
                        / totalWeight;
                if (pixels < cw.minimumWidth)
                    pixels = cw.minimumWidth;
                totalDistributed += pixels;
                widths[i] = pixels;
            }
        }

        // Distribute any remaining pixels
        // to columns with weight.
        int diff = rest - totalDistributed;
        for (int i = 0; diff > 0; i++) {
            if (i == size)
                i = 0;
            ColumnLayoutData col = columns.get(i);
            if (col instanceof ColumnWeightData) {
                ++widths[i];
                --diff;
            }
        }
    }

    for (int i = 0; i < size; i++) {
        if (tableColumns[i].getWidth() != widths[i])
            tableColumns[i].setWidth(widths[i]);
    }
}
}

just as an example, if you have the table inside a container that uses a layout, you may use the layout data to set the size:

final GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
layoutData.minimumWidth = 300;

I prefer TableColumnLayout or TreeColumnLayout. The trick is to set it as layout of the parent composite and not the table or the tree itself.

The size of columns will be automatically updated when resizing the parent container.

    TreeColumnLayout layout = new TreeColumnLayout();
    client.setLayout(layout); 

    viewer = new CheckboxTreeViewer(client, SWT.V_SCROLL | SWT.H_SCROLL);
    viewer.getTree().setLinesVisible(true);

    TreeViewerColumn firstColumn = new TreeViewerColumn(viewer, SWT.NONE);
    layout.setColumnData(firstColumn.getColumn(), new ColumnWeightData(100, 10, true));

    TreeViewerColumn secondColumn = new TreeViewerColumn(resourcesViewer, SWT.NONE);
    layout.setColumnData(secondColumn.getColumn(), new ColumnPixelData(20, false, true));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM