PDA

View Full Version : TabItem/FitLayout/TreeGrid resize issue



Pandaman
14 Jul 2009, 11:09 AM
When the browser is resized, the following code resizes the first treegrid in Tab 1 but fails to resize the second treegrid in Tab 1 when it should (since the tabitem containing this treegrid is resized and is FitLayout).


public void onModuleLoad() {
final TabPanel tabPanel;

final TabItem tabItem1;
final TabItem tabItem2;

final TreeGrid<BaseModel> treeGrida;
final TreeGrid<BaseModel> treeGridb;
final TreeGrid<BaseModel> treeGridc;

final LayoutContainer container = new LayoutContainer();
container.setLayout(new FitLayout());

tabPanel = new TabPanel();

tabItem1 = new TabItem("Tab 1");
tabItem1.setLayout(new FitLayout());

final ArrayList<ColumnConfig> columnsa = new ArrayList<ColumnConfig>();
columnsa.add(new ColumnConfig("name","name", 150));
columnsa.add(new ColumnConfig("details","details", 150));
final ColumnModel cma = new ColumnModel(columnsa);

final ArrayList<ColumnConfig> columnsb = new ArrayList<ColumnConfig>();
columnsb.add(new ColumnConfig("name","name", 150));
columnsb.add(new ColumnConfig("details","details", 150));
final ColumnModel cmb = new ColumnModel(columnsb);

final TreeStore<BaseModel> treeStorea = new TreeStore<BaseModel>();
addDummyData(0, treeStorea);
addDummyData(1, treeStorea);
addDummyData(2, treeStorea);

final TreeStore<BaseModel> treeStoreb = new TreeStore<BaseModel>();
addDummyData(0, treeStoreb);
addDummyData(1, treeStoreb);
addDummyData(2, treeStoreb);

treeGrida = new TreeGrid<BaseModel>(treeStorea, cma);
treeGrida.setWidth(Window.getClientWidth());
treeGrida.setAutoHeight(true);
tabItem1.add(treeGrida);

treeGridb = new TreeGrid<BaseModel>(treeStoreb, cmb);
treeGridb.setWidth(Window.getClientWidth());
treeGridb.setAutoHeight(true);
tabItem1.add(treeGridb);

tabItem1.setWidth(Window.getClientWidth());
tabItem1.setHeight(400);
tabPanel.add(tabItem1);

tabItem2 = new TabItem("Tab 2");
tabItem2.setLayout(new FitLayout());

final ArrayList<ColumnConfig> columnsc = new ArrayList<ColumnConfig>();
columnsc.add(new ColumnConfig("name","name", 150));
columnsc.add(new ColumnConfig("details","details", 150));
final ColumnModel cmc = new ColumnModel(columnsc);

final TreeStore<BaseModel> treeStorec = new TreeStore<BaseModel>();
addDummyData(0, treeStorec);
addDummyData(1, treeStorec);
addDummyData(2, treeStorec);

treeGridc = new TreeGrid<BaseModel>(treeStorec, cmc);
treeGridc.setWidth(Window.getClientWidth());
treeGridc.setAutoHeight(true);
tabItem2.add(treeGridc);

tabItem2.setWidth(Window.getClientWidth());
tabItem2.setHeight(400);
tabPanel.add(tabItem2);

Window.addResizeHandler(new ResizeHandler() {

public void onResize(ResizeEvent event) {
tabPanel.setWidth(event.getWidth());
tabItem1.setWidth(event.getWidth());
tabItem2.setWidth(event.getWidth());
}
});

tabPanel.setAutoWidth(true);
tabPanel.setHeight(400);
container.add(tabPanel);

tabPanel.setDeferredRender(false);
tabItem1.setHideMode(HideMode.OFFSETS);
tabItem2.setHideMode(HideMode.OFFSETS);

treeGrida.getView().setForceFit(true);
treeGridb.getView().setForceFit(true);
treeGridc.getView().setForceFit(true);

RootPanel.get().add(container);
}

private static void addDummyData(final int i, final TreeStore<BaseModel> treeStore) {
final BaseModel data = new BaseModel();
data.set("name", "data " + i);
data.set("details", "details about " + i);

treeStore.add(data, false);
}

sven
14 Jul 2009, 11:13 AM
There are several issues in your code. Also your code is not working as you posted it. What you want to use is a viewport. Moving this to the help forum.

Pandaman
14 Jul 2009, 11:34 AM
Ok what are the issues? I ran the code as posted and it worked. Maybe your import statements are different? Here are mine:

import com.extjs.gxt.ui.client.Style.HideMode;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.Viewport;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;

sven
14 Jul 2009, 11:40 AM
Your treegrids are not specifying any TreeGridCellrenderr. One column has to define that.

Pandaman
14 Jul 2009, 12:31 PM
Ok I'm using a TreeCellGridRenderer for one of the columns for each treegrid.
Also I'm using a viewport for the container that holds the tab panel. The tab panel resized with the browser. But now the children of either tabItem do not resize properly when the browser is resized.



public void onModuleLoad() {
final Viewport viewport = new Viewport();
viewport.add(buildTestTabResizeFitLayout());
RootPanel.get().add(viewport);
}

private TabPanel buildTestTabResizeFitLayout() {
final TabPanel tabPanel = new TabPanel();

final TabItem tabItem2 = new TabItem("Tab 2");
tabItem2.setLayout(new FitLayout());
final TabItem tabItem1 = new TabItem("Tab 1");
tabItem1.setLayout(new FitLayout());

tabPanel.setDeferredRender(false);
tabItem1.setHideMode(HideMode.OFFSETS);
tabItem2.setHideMode(HideMode.OFFSETS);

final ArrayList<ColumnConfig> columnsa = new ArrayList<ColumnConfig>();
final ColumnConfig treeColumna = new ColumnConfig("name","name", 150);
treeColumna.setRenderer(new TreeGridCellRenderer<BaseModel>());
columnsa.add(treeColumna);
columnsa.add(new ColumnConfig("details","details", 150));
final ColumnModel cma = new ColumnModel(columnsa);

final ArrayList<ColumnConfig> columnsb = new ArrayList<ColumnConfig>();
final ColumnConfig treeColumnb = new ColumnConfig("name","name", 150);
treeColumnb.setRenderer(new TreeGridCellRenderer<BaseModel>());
columnsb.add(treeColumnb);
columnsb.add(new ColumnConfig("details","details", 150));
final ColumnModel cmb = new ColumnModel(columnsb);

final TreeStore<BaseModel> treeStorea = new TreeStore<BaseModel>();
addDummyData(0, treeStorea);
addDummyData(1, treeStorea);
addDummyData(2, treeStorea);

final TreeStore<BaseModel> treeStoreb = new TreeStore<BaseModel>();
addDummyData(0, treeStoreb);
addDummyData(1, treeStoreb);
addDummyData(2, treeStoreb);

final TreeGrid<BaseModel> treeGrida = new TreeGrid<BaseModel>(treeStorea, cma);
treeGrida.setAutoHeight(true);
tabItem1.add(treeGrida);

final TreeGrid<BaseModel> treeGridb = new TreeGrid<BaseModel>(treeStoreb, cmb);
treeGridb.setAutoHeight(true);
tabItem1.add(treeGridb);

tabPanel.add(tabItem1);

final ArrayList<ColumnConfig> columnsc = new ArrayList<ColumnConfig>();
final ColumnConfig treeColumnc = new ColumnConfig("name","name", 150);
treeColumnc.setRenderer(new TreeGridCellRenderer<BaseModel>());
columnsc.add(treeColumnc);
columnsc.add(new ColumnConfig("details","details", 150));
final ColumnModel cmc = new ColumnModel(columnsc);

final TreeStore<BaseModel> treeStorec = new TreeStore<BaseModel>();
addDummyData(0, treeStorec);
addDummyData(1, treeStorec);
addDummyData(2, treeStorec);

final TreeGrid<BaseModel> treeGridc = new TreeGrid<BaseModel>(treeStorec, cmc);
treeGridc.setAutoHeight(true);
tabItem2.add(treeGridc);

tabPanel.add(tabItem2);

treeGrida.getView().setForceFit(true);
treeGridb.getView().setForceFit(true);
treeGridc.getView().setForceFit(true);

tabItem1.setAutoHeight(true);
tabItem1.layout();
tabItem2.setAutoHeight(true);
tabItem2.layout();
tabPanel.setAutoHeight(true);
return tabPanel;
}

private void addDummyData(final int i, final TreeStore<BaseModel> treeStore) {
final BaseModel data = new BaseModel();
data.set("name", "data " + i);
data.set("details", "details about " + i);

treeStore.add(data, false);
}

Pandaman
15 Jul 2009, 1:02 PM
Any ideas for this problem?

The_Jackal
16 Jul 2009, 4:10 PM
FitLayout only fits once and doesn't resize automatically.

Some suggestions:
- Use RowLayout and add with a new RowData(1, 1) - that will make the contents 100% of the height and width of the parent container.
- Try FillLayout?

HTH - Carl

Pandaman
17 Jul 2009, 10:51 AM
Thank you for your help Carl.

What I'm trying to do is resize the width of these components based on browser. However, I would like to have the height of each component size automatically based on the child's height (hence the autoHeight(true) calls).

So what I have now is a ResizeHandler added to Window (com.google.gwt.user.client.Window) that manually resizes the width parent container of these widgets/subcontainers. The parent and subcontainers are set to RowLayout with things added to them using RowData as you have said. Everything is set to autoHeight(true).

Is this the best (a.k.a. fastest performing) approach?

The_Jackal
17 Jul 2009, 2:52 PM
I would say that if you are using GXT at all you may as well take advantage of the features it offers you.

If you get it right (and it's a little tricky) you shouldn't need to do any manual resizing (although I had some issues with portals and added some window listeners, but only to re-layout the portal).

You can do nearly everything with viewports, the right layouts and some judicious calls to layout(). Our app completely resizes as the browser window does. It also opens internal GXT windows which also are user resizable and scale / arrange their components respectively.

I don't explicitly use autoHeight(true) very often (mostly as I'm not clear on what it does! - Help anyone?).

I largely use
- Viewports and GXT windows
- BorderLayouts (with layoutContainer.setHeight("100%")),
- RowLayout with RowData 1 (100%) or -1 (fit to child)
- Call to layout() when I know I've done something that needs re-layout like collapsing a container
- FillLayout (rarely)

If you're stuck you can post or pm me a diagram of your layout and I can have a look :)
And if anyone has better suggestions or tips - let us know!

Pandaman
21 Jul 2009, 6:01 AM
Thank you, this has been very helpful. I wish that Ext-GWT documented exactly how to use layouts and what functions to use with them (or perhaps even restrict functionality at the class level). Thanks for guiding me through this confusion.

One issue I am having is arranging elements horizontally in a layout such that one of the elements expands width-wise with container width resize, and the other components have a static width. The heights should resize with the child.

I tried using RowLayout(Orientation.HORIZONTAL) and then setting the expanding column to RowData(1,-1) and the rest of the columns to RowData(-1,-1), but this doesn't work.

I tried ColumnLayout using ColumnData in a similar fashion to RowLayout and RowData and it generally works, but I cannot set margins between columns.

Do you have a technique that you'd employ in this scenario? Any ideas?

The_Jackal
21 Jul 2009, 1:41 PM
I might be misinterpreting you, but I think that you want this:

- add the first "width wise expanding" item with RowData(1,1)
- add the next fixed size item iwrh RowData(1, 40) for a 40 pixel wide item or
- add the next fixed size item iwrh RowData(1, .4) for a 40% wide item or (note you might need to make the first item 60% wide if you do this.