GXT 3.x : Dynamic freeze/lock columns. Autosize the grids

狂风中的少年 提交于 2020-01-16 02:22:11

问题


I took the sample code from here How to implement freeze column in GXT 3.x? and I came up with the code below. I've managed to make the columns dynamically move from locked grid to unlocked grid and vice versa. My problem is with the sizing of the grids. The original code used a fixed width. I can't have that. I need the grids (locked and unlocked) to fill as much space as the children columns need. The columns have a fixed width (let's say 50px;).

The part that interests me is here

HorizontalLayoutContainer gridWrapper = new HorizontalLayoutContainer();
root.setWidget(gridWrapper);

// add locked column, only 300px wide (in this example, use layouts
// to change how this works
HorizontalLayoutData lockedColumnLayoutData = new HorizontalLayoutData(300, 1.0);

// this is optional - without this, you get a little offset issue at
// the very bottom of the non-locked grid
lockedColumnLayoutData.setMargins(new Margins(0, 0, XDOM.getScrollBarWidth(), 0));

gridWrapper.add(lockedGrid, lockedColumnLayoutData);

// add non-locked section, taking up all remaining width
gridWrapper.add(mainGrid, new HorizontalLayoutData(1.0, 1.0));

and maybe here

final Grid<Stock> lockedGrid = new Grid<Stock>(store, lockedCm) {
    @Override
    protected Size adjustSize(Size size) {
        // this is a tricky part - convince the grid to draw just
        // slightly too wide
        // and so push the scrollbar out of sight
        Window.alert("" + (size.getWidth() + XDOM.getScrollBarWidth() - 1));
        return new Size(size.getWidth() + XDOM.getScrollBarWidth() - 1, size.getHeight());
    }
};

I am a newbie in GXT and in GWT in general so I used the same components as the original answer. If what I need to accomplish can be solved easier with something other than HorizontalLayoutContainer, then feel free to change it.


package com.test.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.google.gwt.cell.client.DateCell;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.core.client.Style.ScrollDirection;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.dom.XDOM;
import com.sencha.gxt.core.client.util.Margins;
import com.sencha.gxt.core.client.util.Size;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.Resizable;
import com.sencha.gxt.widget.core.client.Resizable.Dir;
import com.sencha.gxt.widget.core.client.container.HorizontalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.HorizontalLayoutContainer.HorizontalLayoutData;
import com.sencha.gxt.widget.core.client.event.BodyScrollEvent;
import com.sencha.gxt.widget.core.client.event.BodyScrollEvent.BodyScrollHandler;
import com.sencha.gxt.widget.core.client.event.CollapseEvent;
import com.sencha.gxt.widget.core.client.event.CollapseEvent.CollapseHandler;
import com.sencha.gxt.widget.core.client.event.ExpandEvent;
import com.sencha.gxt.widget.core.client.event.ExpandEvent.ExpandHandler;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.grid.GridView;
import com.sencha.gxt.widget.core.client.grid.GridViewConfig;
import com.sencha.gxt.widget.core.client.grid.GroupSummaryView;
import com.sencha.gxt.widget.core.client.grid.SummaryColumnConfig;
import com.sencha.gxt.widget.core.client.grid.filters.GridFilters;
import com.sencha.gxt.widget.core.client.grid.filters.StringFilter;
import com.sencha.gxt.widget.core.client.menu.Item;
import com.sencha.gxt.widget.core.client.menu.Menu;
import com.sencha.gxt.widget.core.client.menu.MenuItem;

public class GridExample implements IsWidget, EntryPoint {
    private static final StockProperties props = GWT.create(StockProperties.class);

    private ContentPanel root;

    private void rootInit() {
        root = new ContentPanel();
        root.setHeadingText("Locked Grid Sample");
        root.setPixelSize(600, 300);

        final Resizable resizable = new Resizable(root, Dir.E, Dir.SE, Dir.S);
        root.addExpandHandler(new ExpandHandler() {
            @Override
            public void onExpand(ExpandEvent event) {
                resizable.setEnabled(true);
            }
        });
        root.addCollapseHandler(new CollapseHandler() {
            @Override
            public void onCollapse(CollapseEvent event) {
                resizable.setEnabled(false);
            }
        });
    }

    @Override
    public Widget asWidget() {

        if (root == null) {

            rootInit();

            ColumnConfig<Stock, String> nameCol = new SummaryColumnConfig<Stock, String>(props.name(), 50, SafeHtmlUtils.fromTrustedString("<b>Company</b>"));
            ColumnConfig<Stock, String> symbolCol = new SummaryColumnConfig<Stock, String>(props.symbol(), 100, "Symbol");
            ColumnConfig<Stock, Double> lastCol = new SummaryColumnConfig<Stock, Double>(props.last(), 75, "Last");
            ColumnConfig<Stock, Double> changeCol = new SummaryColumnConfig<Stock, Double>(props.change(), 100, "Change");

            ColumnConfig<Stock, Date> lastTransCol = new SummaryColumnConfig<Stock, Date>(props.lastTrans(), 100, "Last Updated");
            lastTransCol.setCell(new DateCell(DateTimeFormat.getFormat("MM/dd/yyyy")));

            List<ColumnConfig<Stock, ?>> l = new ArrayList<ColumnConfig<Stock, ?>>();
            //l.add(nameCol);
            l.add(symbolCol);
            l.add(lastCol);
            l.add(changeCol);
            l.add(lastTransCol); 

            // create two column models, one for the locked section
            ColumnModel<Stock> lockedCm = new ColumnModel<Stock>(Collections.<ColumnConfig<Stock, ?>> singletonList(nameCol));
            ColumnModel<Stock> cm = new ColumnModel<Stock>(l);

            ListStore<Stock> store = new ListStore<Stock>(props.key());

            for (int i = 0; i < 30; i++)
                store.add(new Stock("Stackoverflow" + i, "StackoverflowPosts"+i, 0, 2, new Date()));

            // locked grid
            final Grid<Stock> mainGrid = new Grid<Stock>(store, cm);
            final Grid<Stock> lockedGrid = new Grid<Stock>(store, lockedCm) {
                @Override
                protected Size adjustSize(Size size) {
                    // this is a tricky part - convince the grid to draw just
                    // slightly too wide
                    // and so push the scrollbar out of sight
                    return new Size(size.getWidth() + XDOM.getScrollBarWidth() - 1, size.getHeight());
                }
            };

            GridFilters<Stock> filters = new GridFilters<Stock>();
            filters.setLocal(true);

            filters.initPlugin(mainGrid);
            filters.initPlugin(lockedGrid);

            StringFilter<Stock> nameFilter = new StringFilter<Stock>(props.name());
            filters.addFilter(nameFilter);


            lockedGrid.setView(createGridView(mainGrid, "Unfreeze", true));
            mainGrid.setView(createGridView(lockedGrid, "Freeze", false));

            // link scrolling
            lockedGrid.addBodyScrollHandler(new BodyScrollHandler() {
                @Override
                public void onBodyScroll(BodyScrollEvent event) {
                    mainGrid.getView()
                            .getScroller()
                            .scrollTo(ScrollDirection.TOP, event.getScrollTop());
                }
            });
            mainGrid.addBodyScrollHandler(new BodyScrollHandler() {
                @Override
                public void onBodyScroll(BodyScrollEvent event) {
                    lockedGrid
                            .getView()
                            .getScroller()
                            .scrollTo(ScrollDirection.TOP, event.getScrollTop());
                }
            });

            HorizontalLayoutContainer gridWrapper = new HorizontalLayoutContainer();
            root.setWidget(gridWrapper);

            // add locked column, only 300px wide (in this example, use layouts
            // to change how this works
            HorizontalLayoutData lockedColumnLayoutData = new HorizontalLayoutData();

            // this is optional - without this, you get a little offset issue at
            // the very bottom of the non-locked grid
            lockedColumnLayoutData.setMargins(new Margins(0, 0, XDOM.getScrollBarWidth(), 0));

            gridWrapper.add(lockedGrid, lockedColumnLayoutData);

            // add non-locked section, taking up all remaining width
            gridWrapper.add(mainGrid, new HorizontalLayoutData(1.0, 1.0));
        }

        return root;
    }

    @Override
    public void onModuleLoad() {
        RootPanel.get().add(asWidget());
    }

    private GridView<Stock> createGridView(final Grid<Stock> targetGrid, final String menuText, final boolean isLocked) 
    {   
        final GroupSummaryView<Stock> view = new GroupSummaryView<Stock>()
        {
            {
                if(isLocked)
                    scrollOffset = 0;
            }

            protected Menu createContextMenu(final int colIndex)
            {   
                final Menu createContextMenu = super.createContextMenu(colIndex);

                MenuItem lockItem = new MenuItem();
                lockItem.setText(menuText);
                lockItem.addSelectionHandler(new SelectionHandler<Item>() 
                {
                    @Override
                    public void onSelection(SelectionEvent<Item> event) {
                        //I'm making new column models since getColumns() can't be modified
                        ColumnConfig<Stock, ?> column = grid.getColumnModel().getColumn(colIndex);

                        List<ColumnConfig<Stock, ?>> newCm = new ArrayList<>(cm.getColumns());
                        newCm.remove(colIndex);
                        grid.reconfigure(grid.getStore(), new ColumnModel<>(newCm));

                        List<ColumnConfig<Stock, ?>> newTargetCm = new ArrayList<>(targetGrid.getColumnModel().getColumns());
                        newTargetCm.add(column);
                        targetGrid.reconfigure(targetGrid.getStore(), new ColumnModel<>(newTargetCm));

                        grid.getView().refresh(true);
                        targetGrid.getView().refresh(true);
                    }
                });

                createContextMenu.add(lockItem);

                return createContextMenu;
            }
        };

        view.setShowGroupedColumn(false);
        view.setForceFit(false);
        view.setStripeRows(true);
        view.setColumnLines(true);

        view.setViewConfig(new GridViewConfig<Stock>()
        {
            @Override
            public String getRowStyle(Stock model, int rowIndex)
            {
                return "";
            }

            @Override
            public String getColStyle(Stock model, ValueProvider<? super Stock, ?> valueProvider, int rowIndex, int colIndex)
            {           
                return "";
            }
        });

        return view;
    }
}

回答1:


I think you should do something along these lines: Calculate the width of the locked table according the columns, then set it to lockedColumnLayoutData and force gridWrapper to layout.

    @Override
    public void onSelection(SelectionEvent<Item> event) 
    {
           ....

           double lockedTableWidth = 0;//calculate

           lockedColumnLayoutData.setWidth(lockedTableWidth);   

           gridWrapper.forceLayout();
     }


来源:https://stackoverflow.com/questions/27376506/gxt-3-x-dynamic-freeze-lock-columns-autosize-the-grids

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!