GXT 3.x:动态冻结/锁定列。自动调整网格

时间:2014-12-09 10:19:50

标签: java gwt gxt

我从这里获取了示例代码How to implement freeze column in GXT 3.x?,我想出了下面的代码。我设法使列动态地从锁定网格移动到解锁网格,反之亦然。我的问题在于网格的大小。原始代码使用固定宽度。我不能那样。我需要网格(锁定和解锁)来填充子列所需的空间。列具有固定的宽度(比如50px;)。

我感兴趣的部分在这里

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));

也许在这里

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());
    }
};

我是GXT和GWT的新手,因此我使用了与原版相同的组件 回答。如果我需要完成的事情可以通过HorizontalLayoutContainer之外的其他内容更容易解决,那么请随时更改它。


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 个答案:

答案 0 :(得分:1)

我认为你应该按照这些方针做点什么: 根据列计算锁定表的宽度,然后将其设置为lockedColumnLayoutData 并强制gridWrapper进行布局。

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

           double lockedTableWidth = 0;//calculate

           lockedColumnLayoutData.setWidth(lockedTableWidth);   

           gridWrapper.forceLayout();
     }