在显示时调整列的大小 - NatTable

Resize columns as they are displayed - NatTable

我有一个 VerticalTextPainter 用于列 header 和一个 TextPainter 用于行 header。

一些 columns/rows 有换行符,所以我想调整列宽和行高以适合内容。这应该只在首次显示 column/row 时发生一次,以便用户可以在之后更改 widths/heights。

快速滚动时,有时不会调整 column/row 的大小。

nattable.addOverlayPainter(new IOverlayPainter() {

    @Override
    public void paintOverlay(final GC gc, final ILayer layer) {

        for (int i = 0; i < nattable.getColumnCount(); i++) {

            final int indexByPosition = columnlayer.getColumnIndexByPosition(i);
            if (!resizedColumnsByPosition.contains(indexByPosition)) {

                resizedColumnsByPosition.add(indexByPosition);

                nattable.doCommand(new InitializeAutoResizeColumnsCommand(gridlayer, i, nattable.getConfigRegistry(), new GCFactory(nattable)));
            }
        }

        for (int i = 0; i < nattable.getRowCount(); i++) {

            final int indexByPosition = nattable.getRowIndexByPosition(i);
            if (!resizedRowsByPosition.contains(indexByPosition)) {

                resizedRowsByPosition.add(indexByPosition);

                nattable.doCommand(new InitializeAutoResizeRowsCommand(nattable, i, nattable.getConfigRegistry(), new GCFactory(nattable)));
            }
        }
    }
});

我创建了一个小示例来说明问题。列的高度 header 可以忽略,因为我只是想在此代码中设置宽度。

完整示例

import java.util.Collection;
import java.util.HashSet;

import org.eclipse.nebula.widgets.nattable.NatTable;
import org.eclipse.nebula.widgets.nattable.config.AbstractRegistryConfiguration;
import org.eclipse.nebula.widgets.nattable.config.CellConfigAttributes;
import org.eclipse.nebula.widgets.nattable.config.ConfigRegistry;
import org.eclipse.nebula.widgets.nattable.config.IConfigRegistry;
import org.eclipse.nebula.widgets.nattable.data.IDataProvider;
import org.eclipse.nebula.widgets.nattable.data.convert.DefaultDisplayConverter;
import org.eclipse.nebula.widgets.nattable.grid.GridRegion;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultColumnHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultCornerDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DefaultRowHeaderDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.data.DummyBodyDataProvider;
import org.eclipse.nebula.widgets.nattable.grid.layer.ColumnHeaderLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.CornerLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.GridLayer;
import org.eclipse.nebula.widgets.nattable.grid.layer.RowHeaderLayer;
import org.eclipse.nebula.widgets.nattable.hideshow.ColumnHideShowLayer;
import org.eclipse.nebula.widgets.nattable.layer.AbstractLayerTransform;
import org.eclipse.nebula.widgets.nattable.layer.CompositeLayer;
import org.eclipse.nebula.widgets.nattable.layer.DataLayer;
import org.eclipse.nebula.widgets.nattable.layer.ILayer;
import org.eclipse.nebula.widgets.nattable.layer.LabelStack;
import org.eclipse.nebula.widgets.nattable.layer.cell.IConfigLabelAccumulator;
import org.eclipse.nebula.widgets.nattable.painter.IOverlayPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.CellPainterWrapper;
import org.eclipse.nebula.widgets.nattable.painter.cell.ICellPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.TextPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.VerticalTextPainter;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.CustomLineBorderDecorator;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.LineBorderDecorator;
import org.eclipse.nebula.widgets.nattable.painter.cell.decorator.PaddingDecorator;
import org.eclipse.nebula.widgets.nattable.reorder.ColumnReorderLayer;
import org.eclipse.nebula.widgets.nattable.resize.command.InitializeAutoResizeColumnsCommand;
import org.eclipse.nebula.widgets.nattable.resize.command.InitializeAutoResizeRowsCommand;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.style.BorderStyle;
import org.eclipse.nebula.widgets.nattable.style.CellStyleAttributes;
import org.eclipse.nebula.widgets.nattable.style.DisplayMode;
import org.eclipse.nebula.widgets.nattable.style.HorizontalAlignmentEnum;
import org.eclipse.nebula.widgets.nattable.style.Style;
import org.eclipse.nebula.widgets.nattable.style.VerticalAlignmentEnum;
import org.eclipse.nebula.widgets.nattable.util.GCFactory;
import org.eclipse.nebula.widgets.nattable.util.GUIHelper;
import org.eclipse.nebula.widgets.nattable.viewport.ViewportLayer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class ExampleNatTable {

    private BodyLayerStack bodyLayer;
    private int statusColumn;
    private int statusRejected;
    private int statusInProgress;
    private boolean check = false;
    private NatTable nattable;
    private String[] summaryProperties;
    private String[] properties;
    private static final String FOO_LABEL = "FOO";
    private static final String CELL_LABEL = "Cell_LABEL";

    private final Collection < Integer > resizedColumnsByPosition = new HashSet < >();
    private final Collection < Integer > resizedRowsByPosition = new HashSet < >();

    public static void main(String[] args) {
        new ExampleNatTable();
    }

    public ExampleNatTable() {

        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());

        summaryProperties = new String[100];

        for (int i = 0; i < summaryProperties.length; i++) {

            summaryProperties[i] = "s" + i;
        }

        properties = new String[100];

        for (int i = 0; i < properties.length; i++) {

            properties[i] = "Column" + i;
        }

        // Setting the data layout layer
        GridData gridData = new GridData();
        gridData.heightHint = 1;
        gridData.widthHint = 1;

        IConfigRegistry configRegistry = new ConfigRegistry();

        // Body Data Provider
        IDataProvider dataProvider = new DataProvider(properties.length, 55);
        bodyLayer = new BodyLayerStack(dataProvider);
        // datalayer.addConfiguration(new

        // Column Data Provider
        DefaultColumnHeaderDataProvider columnSummaryData = new DefaultColumnHeaderDataProvider(summaryProperties);
        DefaultColumnHeaderDataProvider columnData = new DefaultColumnHeaderDataProvider(properties);
        ColumnHeaderLayerStack columnSummaryLayer = new ColumnHeaderLayerStack(columnSummaryData);
        ColumnHeaderLayerStack columnlayer = new ColumnHeaderLayerStack(columnData);

        /**
     * Composite layer
     */
        final CompositeLayer columnCompositeLayer = new CompositeLayer(1, 2);
        columnCompositeLayer.setChildLayer("SUMMARY_REGION", columnSummaryLayer, 0, 0);
        columnCompositeLayer.setChildLayer("COLUMNS", columnlayer, 0, 1);

        // Row Data Provider
        DefaultRowHeaderDataProvider rowdata = new DefaultRowHeaderDataProvider(dataProvider);
        RowHeaderLayerStack rowlayer = new RowHeaderLayerStack(rowdata);

        // Corner Data Provider
        DefaultCornerDataProvider cornerdata = new DefaultCornerDataProvider(columnData, rowdata);
        DataLayer cornerDataLayer = new DataLayer(cornerdata);
        CornerLayer cornerLayer = new CornerLayer(cornerDataLayer, rowlayer, columnCompositeLayer);

        GridLayer gridlayer = new GridLayer(bodyLayer, columnCompositeLayer, rowlayer, cornerLayer);
        nattable = new NatTable(shell, gridlayer, false);

        // Change for paint
        IConfigLabelAccumulator cellLabelAccumulator = new IConfigLabelAccumulator() {
            // @Override
            @Override
            public void accumulateConfigLabels(LabelStack configLabels, int columnPosition, int rowPosition) {

                int columnIndex = bodyLayer.getColumnIndexByPosition(columnPosition);
                int rowIndex = bodyLayer.getRowIndexByPosition(rowPosition);
                if (columnIndex == 2 && rowIndex == 45) {
                    configLabels.addLabel(FOO_LABEL);
                } else if ((columnIndex == statusColumn) && (rowIndex == statusRejected) && (check == true)) {
                    configLabels.addLabel(CELL_LABEL);
                }
            }
        };
        bodyLayer.setConfigLabelAccumulator(cellLabelAccumulator);

        // nattable.addConfiguration(new DefaultNatTableStyleConfiguration());
        nattable.addConfiguration(new AbstractRegistryConfiguration() {
            // @Override
            @Override
            public void configureRegistry(IConfigRegistry configRegistry) {

                /**
         * Column Header
         */
                final Style columnHeaderStyle = new Style();

                columnHeaderStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, VerticalAlignmentEnum.BOTTOM);

                columnHeaderStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, HorizontalAlignmentEnum.CENTER);

                configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, columnHeaderStyle, DisplayMode.NORMAL, GridRegion.COLUMN_HEADER);

                final VerticalTextPainter columnHeaderPainter = new VerticalTextPainter(false, true, false);

                Display display = Display.getCurrent();
                Color blue = display.getSystemColor(SWT.COLOR_BLUE);

                final CellPainterWrapper columnHeaderDecorator = new CustomLineBorderDecorator(
                new PaddingDecorator(columnHeaderPainter, 3, 0, 3, 0), new BorderStyle(1, blue, BorderStyle.LineStyleEnum.SOLID));

                configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, columnHeaderDecorator, DisplayMode.NORMAL, GridRegion.COLUMN_HEADER);

                /**
         * Cells
         */
                final Color bgColor = GUIHelper.COLOR_WHITE;
                final Color fgColor = GUIHelper.COLOR_BLACK;
                final Color gradientBgColor = GUIHelper.COLOR_WHITE;
                final Color gradientFgColor = GUIHelper.getColor(136, 212, 215);
                final Font font = GUIHelper.DEFAULT_FONT;
                final HorizontalAlignmentEnum hAlign = HorizontalAlignmentEnum.CENTER;
                final VerticalAlignmentEnum vAlign = VerticalAlignmentEnum.MIDDLE;
                final BorderStyle borderStyle = null;
                final ICellPainter cellPainter = new LineBorderDecorator(new TextPainter(false, true, 5, true));

                configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_PAINTER, cellPainter);

                Style cellStyle = new Style();
                cellStyle.setAttributeValue(CellStyleAttributes.BACKGROUND_COLOR, bgColor);
                cellStyle.setAttributeValue(CellStyleAttributes.FOREGROUND_COLOR, fgColor);
                cellStyle.setAttributeValue(CellStyleAttributes.GRADIENT_BACKGROUND_COLOR, gradientBgColor);
                cellStyle.setAttributeValue(CellStyleAttributes.GRADIENT_FOREGROUND_COLOR, gradientFgColor);
                cellStyle.setAttributeValue(CellStyleAttributes.FONT, font);
                cellStyle.setAttributeValue(CellStyleAttributes.HORIZONTAL_ALIGNMENT, hAlign);
                cellStyle.setAttributeValue(CellStyleAttributes.VERTICAL_ALIGNMENT, vAlign);
                cellStyle.setAttributeValue(CellStyleAttributes.BORDER_STYLE, borderStyle);

                configRegistry.registerConfigAttribute(CellConfigAttributes.CELL_STYLE, cellStyle);

                configRegistry.registerConfigAttribute(CellConfigAttributes.DISPLAY_CONVERTER, new DefaultDisplayConverter());
            }
        });

        nattable.setLayoutData(gridData);
        nattable.setConfigRegistry(configRegistry);
        nattable.configure();

        nattable.addOverlayPainter(new IOverlayPainter() {

            @Override
            public void paintOverlay(final GC gc, final ILayer layer) {

                for (int i = 0; i < nattable.getColumnCount(); i++) {

                    final int indexByPosition = columnlayer.getColumnIndexByPosition(i);
                    if (!resizedColumnsByPosition.contains(indexByPosition)) {

                        resizedColumnsByPosition.add(indexByPosition);

                        System.out.println(indexByPosition + " : " + i);

                        nattable.doCommand(new InitializeAutoResizeColumnsCommand(gridlayer, i, nattable.getConfigRegistry(), new GCFactory(nattable)));
                    }
                }

                for (int i = 0; i < nattable.getRowCount(); i++) {

                    final int indexByPosition = nattable.getRowIndexByPosition(i);
                    if (!resizedRowsByPosition.contains(indexByPosition)) {

                        resizedRowsByPosition.add(indexByPosition);

                        nattable.doCommand(new InitializeAutoResizeRowsCommand(nattable, i, nattable.getConfigRegistry(), new GCFactory(nattable)));
                    }
                }
            }
        });

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

    }

    public class DataProvider extends DummyBodyDataProvider {

        public DataProvider(int columnCount, int rowCount) {
            super(columnCount, rowCount);
        }

        @Override
        public int getColumnCount() {
            return properties.length;
        }

        @Override
        public Object getDataValue(int columnIndex, int rowIndex) {

            return new String("" + columnIndex + ":" + rowIndex);

        }

        @Override
        public int getRowCount() {
            return 55;
        }

        @Override
        public void setDataValue(int arg0, int arg1, Object arg2) {

}
    }

    public class BodyLayerStack extends AbstractLayerTransform {

        private SelectionLayer selectionLayer;

        public BodyLayerStack(IDataProvider dataProvider) {
            DataLayer bodyDataLayer = new DataLayer(dataProvider);
            ColumnReorderLayer columnReorderLayer = new ColumnReorderLayer(bodyDataLayer);
            ColumnHideShowLayer columnHideShowLayer = new ColumnHideShowLayer(columnReorderLayer);
            this.selectionLayer = new SelectionLayer(columnHideShowLayer);
            ViewportLayer viewportLayer = new ViewportLayer(this.selectionLayer);
            setUnderlyingLayer(viewportLayer);
        }

        public SelectionLayer getSelectionLayer() {
            return this.selectionLayer;
        }
    }

    public class ColumnHeaderLayerStack extends AbstractLayerTransform {

        public ColumnHeaderLayerStack(IDataProvider dataProvider) {
            DataLayer dataLayer = new DataLayer(dataProvider);
            ColumnHeaderLayer colHeaderLayer = new ColumnHeaderLayer(dataLayer, ExampleNatTable.this.bodyLayer, ExampleNatTable.this.bodyLayer.getSelectionLayer());
            setUnderlyingLayer(colHeaderLayer);
        }
    }

    public class RowHeaderLayerStack extends AbstractLayerTransform {

        public RowHeaderLayerStack(IDataProvider dataProvider) {
            DataLayer dataLayer = new DataLayer(dataProvider, 50, 20);
            RowHeaderLayer rowHeaderLayer = new RowHeaderLayer(dataLayer, ExampleNatTable.this.bodyLayer, ExampleNatTable.this.bodyLayer.getSelectionLayer());
            setUnderlyingLayer(rowHeaderLayer);
        }
    }
}

我试过使用不同的层来获取列数和索引,但无法正常工作。

实现这一目标的正确方法是什么?

快速滚动时,执行的命令无法匹配滚动中的更新状态。可能是运行时问题,因为正在使用的命令并非真正用于滚动。

我 运行 没有想法来支持您在自动调整大小方面的所有要求。您可以查看 AutoResizeHelper 的 1.6 版本并尝试调整列的自动行大小调整方法。