考虑一个其UI有标签的GWT应用程序。在一个标签中,有一些固定大小的元素,后跟DataGrid
。
_______________________________________________
| ______ |
| Tab1 / Tab2 \ Tab3 |
|_____/ \________________________________|
| Fixed size widgets here. || |
| Fixed size widgets here. || |
| ---------------------- || |
| Datagrid headings tab scrollbar -->|| |
| cell cell cell cell || || |
| cell cell cell cell || || |
| cell cell cell cell ||<-- datagrid || |
| cell cell cell cell || scrollbar || |
| cell cell cell cell || || |
| cell cell cell cell || || |
-----------------------------------------------
我希望DataGrid
填充窗口中的剩余高度,并在浏览器窗口调整大小时更改高度,但约束条件是它不会小于指定的最小高度(例如3行,不包括标题)。在此应用程序中,数据网格中通常只有大约10行。
有两个滚动条。我希望他们表现得像这样:
数据网格滚动条允许导航数据网格中的行。如果可以看到数据网格中的所有行,则不应显示它。
标签滚动条滚动选项卡的内容,使标签选择器可见。通常这是隐藏的,因为datagrid完全包含在浏览器窗口中,并且datagrid滚动条可用于查看内容。但是,数据网格具有最小高度,如果浏览器窗口中没有空间,则可以看到选项卡滚动条。
我的问题是:我如何实现这一目标?
我有一些示例代码。首先,模块加载如下:
public class Proj implements EntryPoint {
public void onModuleLoad() {
RootLayoutPanel.get().add(new App());
//RootPanel.get("app").add(new App());
}
}
我认为我需要RootLayoutPanel
版本而不是RootPanel
,但我欢迎对此发表评论。
现在有些UiBinder
代码:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:d="urn:import:com.google.gwt.user.cellview.client"
>
<ui:style>
.foo {
min-height: 100px;
max-height: 300px;
}
</ui:style>
<g:TabLayoutPanel ui:field="tabLayout" barUnit="PX" barHeight="30" >
<g:tab>
<g:header> Tab One </g:header>
<g:ScrollPanel height="100%"> <!-- Hack? height="100%":-->
<g:FlowPanel>
<g:Label text="Window.getClientHeight():"/>
<g:Label ui:field="label" text="Window.getClientHeight()"/>
<g:Label text="grid.getElement().getAbsoluteTop():"/>
<g:Label ui:field="label2" text="grid.getElement().getAbsoluteTop()"/>
<d:DataGrid styleName='{style.foo}' ui:field="grid"/>
</g:FlowPanel>
</g:ScrollPanel>
</g:tab>
</g:TabLayoutPanel>
</ui:UiBinder>
最后定义class App
:
public class App extends ResizeComposite {
@UiTemplate("App.ui.xml")
interface ThisUiBinder extends UiBinder<Widget, App> {
}
private static ThisUiBinder uiBinder = GWT.create(ThisUiBinder.class);
@UiField
TabLayoutPanel tabLayout;
@UiField
Label label;
@UiField
Label label2;
@UiField (provided=true)
DataGrid grid;
static class Data {
String foo;
public Data(String foo) {
this.foo = foo;
}
}
private static final List<Data> DATA = Arrays.asList(
new Data("A"), new Data("Q"), new Data("w"),
new Data("e"), new Data("r"), new Data("t"),
new Data("y"), new Data("u"), new Data("i"),
new Data("o")
);
private final int MINSIZE = 100; // of grid, in px
public App() {
grid = new DataGrid<Data>();
TextColumn<Data> fooColumn = new TextColumn<Data>() {
@Override
public String getValue(Data object) {
return object.foo;
}
};
grid.addColumn(fooColumn, "foo");
grid.setRowCount(DATA.size(), true);
grid.setRowData(0, DATA);
initWidget(uiBinder.createAndBindUi(this));
//grid.setHeight("100%"); // hack, 100% of what?
//tabLayout.setHeight("100%"); // hack, 100% of what?
onResize(); // Hack!
}
public void onResize() {
label.setText(String.valueOf(Window.getClientHeight()));
// Note that this is 0 on the first call (from our constructor),
// which does not give the desired result!
label2.setText(String.valueOf(grid.getElement().getAbsoluteTop()));
// Works very badly! Jumpy and eratic!
int newsize = Window.getClientHeight() - grid.getElement().getAbsoluteTop();
if (newsize > MINSIZE) {
grid.setHeight(String.valueOf(newsize)) + "px");
}
}
}
onResize()中的机制不仅对我来说闻起来很糟糕(它是作为一个实验实现的),而且它也很可笑地工作。
有没有一种巧妙的方法可以完全用CSS做到这一点?或者是否必须在onResize()中完成某些事情?我使用GWT的一个动机是避免浏览器之间的差异引起的问题,纯CSS是正确的方法吗?
我已将height
设置为100%
在各个地方作为黑客,看看它有什么不同。我非常希望能够正确地理解这一切是如何挂在一起的 - 任何阅读建议都会受到欢迎。我也尝试过遵守http://www.dave-woods.co.uk/100-height-layout-using-css/中的指南,例如使用CSS:
html, body {
height: 100%;
}
我还发现了这个信息:https://stackoverflow.com/a/11866677/685715。但它并没有解决我的问题。
答案 0 :(得分:0)
您有三种选择:
使用附加到Window的ResizeHandler。调整窗口大小时,计算并设置DataGrid的大小。
在选项卡中使用LayoutPanel(或VerticalPanel0。设置固定宽度小部件,然后设置DataGrid小部件:
myLayoutPanel.setWidgetTopBottom(myDataGrid, 120, Unit.PX, 0, Unit.PX);
此解决方案不需要调整大小处理程序,但会为您的布局引入额外的小部件(即HTML代码)。
答案 1 :(得分:0)
假设Datagrid上面的静态小部件的高度是常量并且已知的,我会这样做:
UiBinder代码:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:d="urn:import:com.google.gwt.user.cellview.client"
>
<ui:style>
.foo {
min-height: [HEIGHT OF STATIC WIDGETS + 100px];
max-height: [HEIGHT OF STATIC WIDEGET + 300px;
}
</ui:style>
<g:TabLayoutPanel ui:field="tabLayout" barUnit="PX" barHeight="30" >
<g:tab>
<g:header> Tab One </g:header>
<g:ScrollPanel >
<g:LayoutPanel addStyleNames="{style.foo}">
<g:layer top="0" height="[HEIGHT OF STATIC WIDGETS]">
<g:FlowPanel>
<g:Label text="Window.getClientHeight():"/>
<g:Label ui:field="label" text="Window.getClientHeight()"/>
<g:Label text="grid.getElement().getAbsoluteTop():"/>
<g:Label ui:field="label2" text="grid.getElement().getAbsoluteTop()"/>
</g:FlowPanel>
</g:layer>
<g:layer top="[HEIGHT OF STATIC WIDGETS] bottom="0">
<d:DataGrid ui:field="grid"/>
</g:layer>
</g:LayoutPanel>
</g:ScrollPanel>
</g:tab>
</g:TabLayoutPanel>
</ui:UiBinder>
这应该完全适用于UiBinder代码(不需要进行Java更改或大小计算)。
当然,这仅适用于知道DataGrid上方固定大小的小部件的总高度(只需将&#34; [静态WIDGETS高度]&#34; 替换为相应的大小
或者您也可以尝试将DataGrid
包裹在ResizeLayoutPanel
内,这将为DataGrid
提供明确的尺寸,并且不需要{{1}的完整链最多LayoutPanels
。但是我不确定这是否适用于DataGrid上的 min-height 。您可能希望将其移至RootLayoutPanel
本身。