问题
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