I'm using GWT 2.5.1 with uibinder xml for specifying ui layouts.
Being a newbie in this, can't figure out how to specify even a simple layout:
I want the [Somelabel:] and [Button] to take the minimal required place, and [Textbox] to occupy the rest. Tried different approaches: placing them to HorizontalPanel, FlowPanel, even DockLayoutPanel. None of them satisfy my requirements: HorizontalPanel just divides parent container to three equal parts, FlowPanel gives no respect to element width, DockLayoutPanel wants me to manually calculate and specify the width of [Somelabel:] and [Button] and still doesn't work at all.
That is the basic ui layout task and I can't believe that GWT does not have a way to specify what I want without manual pixelwidth calculation. Most different UI tools have the simple way to specify it.
this lays them in equal cells:
<g:HorizontalPanel width="100%">
<g:Label>Somelabel:</g:Label>
<g:TextBox ui:field="someTextBox"/>
<g:Button ui:field="someButton" text="Button"/>
</g:HorizontalPanel>
this lays them in a weird way (whether "float: left" specified for label or not; whether "float: right" specified for button or not):
<g:FlowPanel width="100%">
<g:Label>Somelabel:</g:Label>
<g:TextBox ui:field="someTextBox"/>
<g:Button ui:field="someButton" text="Button"/>
</g:FlowPanel>
this wants me to specify pixels but doesn't even display them:
<g:DockLayoutPanel width="100%" height="90">
<g:east size="30"><g:Label>Somelabel:</g:Label></g:east>
<g:center><g:TextBox ui:field="someTextBox"/></g:center>
<g:west size="50"><g:Button ui:field="someButton" text="Button"/></g:west>
</g:DockLayoutPanel>
[no image because it doesn't display anything]
I'm kinda stuck because the only kind-of-working xml is the HorizontalPanel one and it does not do what I want.
UP: added screenshots and tried "float:" css styles (which didn't change anything).
UP2: got the picture I wanted using LayoutPanel and specifying pixelwidth of each layer.
<g:LayoutPanel width="100%" height="40px">
<g:layer width="100px" left="0">
<g:Label>Somelabel:</g:Label>
</g:layer>
<g:layer left="100px" right="200px">
<g:TextBox ui:field="someTextBox"/>
</g:layer>
<g:layer width="200px" right="0">
<g:Button ui:field="someButton" text="Button"/>
</g:layer>
</g:LayoutPanel>
But the xml looks ugly, forces me to calculate pixels manually, and to specify each width in two places. Can I somehow leave the pixelwidth calculations to framework and just specify "place it there and give it minimum place it wants"?
If you refer to the GWT docs [here][1] it mentions your exact problem. Try using FlowPanel with float : left CSS property as specified.
EDIT :
This worked for me
Ui-Binder
<g:FlowPanel width="100%" addStyleNames="myTable">
<g:FlowPanel addStyleNames="myTableRow">
<g:Label addStyleNames="myTableLabel">Somelabel:</g:Label>
<g:FlowPanel width="100%" addStyleNames="myTableCell">
<g:TextBox ui:field="someTextBox" addStyleNames="myTableInput"/>
</g:FlowPanel>
<g:Button ui:field="someButton" text="Button" addStyleNames="myTableButton"/>
</g:FlowPanel>
</g:FlowPanel>
CSS :
.myTable {
display: table;
width: 100%;
}
.myTableRow {
display: table-row;
}
.myTableLabel {
display: table-cell;
}
.myTableCell {
display: table-cell;
width: 100%;
}
.myTableInput {
width: 100%;
}
.myTableButton {
display: table-cell;
}
Related
I'm trying to add a DataGrid on my view.
I know that a DataGrid can only stay in a Layout Panel, because of the ProvidesResize and RequiresResize interfaces.
The thing is, I want to add a filter on top of the DataGrid Table, and the filter can't have a fixed height, it could be bigger or smaller.
No Layout Panel would accept more then one child to be resized, but the LayoutPanel itself. But still, each layer needs a height to be set in percentage, and that's not OK as well.
If I change the DataGrid with a CellTable and then add both in a Flow Panel, the problem would be solved, but the table has to be scrollable.
What I would need is a FlowLayoutPanel but there is no such Panel in GWT
I was thinking that the only way would be to try to create a custom panel which would implement ProvidesResize and RequiresResize interfaces.
This is how it looks like using a LayoutPanel :
<g:layer left="2%" right="68%" top="2%" bottom="93%">
<g:Label ui:field="gridBlurb" addStyleNames="{res.viewStandardStyle.viewTitle}" />
</g:layer>
<g:layer left="2%" right="68%" top="9%" bottom="56%">
<g:SplitLayoutPanel>
<g:center>
<g:HTMLPanel>
<g:FlowPanel ui:field="criteriaPanel" visible="false" />
<g:FlowPanel>
<g:Button ui:field="refresh">
<ui:text from="{text.refreshButtonCaption}" />
</g:Button>
</g:FlowPanel>
</g:HTMLPanel>
</g:center>
</g:SplitLayoutPanel>
</g:layer>
<g:layer left="2%" right="2%" top="45%" bottom="5%">
<g:SplitLayoutPanel>
<g:center>
<c:DataGrid ui:field='table' />
</g:center>
</g:SplitLayoutPanel>
</g:layer>
<g:layer left='2%' right='2%' top="95%" bottom="0%">
<g:HTMLPanel>
<table style="width:100%">
<tr>
<td align='center'>
<c:SimplePager ui:field='pager' />
</td>
</tr>
</table>
</g:HTMLPanel>
</g:layer>
</g:LayoutPanel>
Can anyone help me with this ?
Many thanks in advance.
If you don't care about very old browsers, use flexbox CSS layout model - I use it with DataGrid (and for everything else) all the time.
Then you simply add display: flex; to your container (i.e. what you used LayoutPanel for), and then set flex-grow: 1 on your DataGrid. This will tell DataGrid to take all the available space after other widgets in the container have been rendered.
P.S. For the past few years I try to avoid LayoutPanels as much as possible for performance reasons, especially on mobile devices.
looks like the CSS did the trick.
Many thanks.
This is how it looks like :
<!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:c="urn:import:com.google.gwt.user.cellview.client">
<ui:with field='res' type='com.vsg.vraweb.client.resource.Resources' />
<ui:with field='text' type='com.vsg.vralang.client.GlobalConstants' />
<!--
CSS Tricks tutorial : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
1) 'display: flex;' - enables a flex context for all its direct children.
2) 'flex-direction: row | row-reverse | column | column-reverse;' - This establishes
the main-axis, thus defining the direction flex items are placed in the flex
container.
3) flex-grow: <number>; - This defines the ability for a flex item to grow if necessary.
-->
<ui:style>
.container {
display: flex;
flex-direction: column;
}
.dataGrid {
width: 100%;
flex-grow: 1;
}
</ui:style>
<g:FlowPanel addStyleNames="{style.container}">
<g:Label ui:field="gridBlurb" addStyleNames="{res.viewStandardStyle.viewTitle}" />
<g:HTMLPanel>
<g:FlowPanel ui:field="criteriaPanel" visible="false" />
<g:FlowPanel>
<g:Button ui:field="refresh">
<ui:text from="{text.refreshButtonCaption}" />
</g:Button>
</g:FlowPanel>
</g:HTMLPanel>
<c:DataGrid ui:field='table' addStyleNames="{style.dataGrid}"/>
<g:HTMLPanel>
<table style="width:100%">
<tr>
<td align='center'>
<c:SimplePager ui:field='pager' />
</td>
</tr>
</table>
</g:HTMLPanel>
</g:FlowPanel>
</ui:UiBinder>
I' m tying to make a dialog box that contains 3 parts: TextBox, DataGrid and Button. And I'm using DockLayoutPanel like that
<ui:style>
.panel {
width: 600px;
height: 500px;
}
</ui:style>
<g:HTMLPanel addStyleNames='{style.panel}'>
<g:DockLayoutPanel unit="PX">
<g:north size="45">
<g:TextBox>...
</g:north>
<g:south size="45">
<g:Button>...
</g:south>
<g:center>
<g:DataGrid>...
</g:center>
</g:DockLayoutPanel>
</g:HTMLPanel>
Here is my class
public class MyDialogBoxViewImpl extends DialogBox {
interface MyDialogBoxViewImplUiBinder extends
UiBinder<Widget, MyDialogBoxViewImpl> {
}
...
But the problem is that only TextBox is visible.
I'm not sure that it is properly to use DockLayoutPanel in DialogBox, but it is so suitable for my application. So can you help me with my issue and give me some advices how to replace DockLayoutPanel if it will need. Thanks.
Try setting explicitly the size of DockLayoutPanel.
For example:
<g:DockLayoutPanel unit="PX" width="100%" height="100%">
Your size values are "100%", but your unit is "PX". Try changing your unit to "PCT" for percentage width and height
Here is my problem: When I navigate to the view shown below, the disclosurepanel has a big distance to the grid and when I click on a disclosurepanel header it gets a "selection border" - But when I refresh the browser, everything is on the position where it should be and the disclosurepanel header doesnt get selected anymore when I click on it.
I have a ui.xml like this:
<g:HTMLPanel>
<g:VerticalPanel>
<g:Grid>
<g:row>
<g:customCell>
<g:Button ui:field="editBTN" width="50px"></g:Button>
</g:customCell>
<g:customCell>
<g:Button ui:field="deleteBTN" width="50px"></g:Button>
</g:customCell>
<g:customCell>
<g:Label ui:field="date" width="100px"></g:Label>
</g:customCell>
<g:customCell>
<g:Label ui:field="begin" width="100px"></g:Label>
</g:customCell>
<g:customCell>
<g:Label ui:field="end" width="100px"></g:Label>
</g:customCell>
<g:customCell>
<g:Label ui:field="pause" width="100px"></g:Label>
</g:customCell>
<g:customCell>
<g:Label ui:field="sum" width="100px"></g:Label>
</g:customCell>
<g:customCell>
<g:Label ui:field="tasks" width="100px"></g:Label>
</g:customCell>
</g:row>
</g:Grid>
<g:DisclosurePanel>
<g:header>test</g:header>
</g:DisclosurePanel>
<g:DisclosurePanel>
<g:header>test</g:header>
<g:Grid>
<g:row>
<g:customCell>
<g:TextBox ui:field="fromDATEtbx" width="100px"></g:TextBox>
</g:customCell>
<g:customCell>
<g:TextBox ui:field="toDATEtbx" width="100px"></g:TextBox>
</g:customCell>
</g:row>
</g:Grid>
</g:DisclosurePanel>
</g:VerticalPanel>
</g:HTMLPanel>
Is this a known bug/mistake?
I have noticed sometimes this "selection border" for my disclosure panels when was working in debug mode. Did not see this in production mode though.
If you really need to get rid of that effect by all means, you can try to set "outline: none;" to your disclosurePanel.getHeader().getParent() which will prevent showing the highlighted border (which is usually OK for active focused element in new browsers) for <a href=...> element that wraps the disclosure panel's header.
You may also check what is happening with that header in devtools, when you see the unexpected space between elements. And compare that to what you see after refresh. So you may notice the difference and then find out what causes that.
Ok solved the Problem.
Somehow it adds
td {
padding: 8px;
}
to your styling. I simply set
td {
padding: 0px;
}
to my uibinder.
I have a global presenter that contains a Header Footer and the main content slots, when header always on the top, footer always on the bottom...
My question is: How can i add scroll bar to my Global Presenter?
I know that there were a lot of questions like this but i cant find the right answer for me.
I have UiBinder that has the code:
<g:RootLayoutPanel width="100%" height="100%">
<g:layer left="0px" right="0px" top="0px" bottom="0px">
<g:DockLayoutPanel unit="EM">
<g:north size="5.0">
<g:HTMLPanel ui:field="headerContentPanel" />
</g:north>
<g:center size="1.0">
<g:FlowPanel ui:field="mainContentPanel" />
</g:center>
<g:south size="1.5">
<g:HTMLPanel ui:field="footerContentPanel" />
</g:south>
</g:DockLayoutPanel>
</g:layer>
</g:RootLayoutPanel>
I have tried to add ScrollPanel that is contains the RootLayotPanel or other panels.. but than all the inner panel receive size zero.
I have tried to use a vertical panel inside the scrollPanel but than I can't put the footer at the bottom.
Does someone has an answer?
==================================================================================
I succeeded to do it, here is my new code:
<g:RootLayoutPanel width="100%" height="100%">
<g:layer>
<g:ScrollPanel width="100%" height="100%">
<g:DockPanel width="100%" horizontalAlignment="ALIGN_CENTER" verticalAlignment="ALIGN_MIDDLE">
<g:Dock direction="NORTH" >
<g:HTMLPanel ui:field="headerContentPanel" />
</g:Dock>
<g:Dock direction="CENTER" verticalAlignment="ALIGN_MIDDLE" horizontalAlignment="ALIGN_CENTER">
<g:FlowPanel ui:field="mainContentPanel" />
</g:Dock>
<g:Dock direction="SOUTH" verticalAlignment="ALIGN_BOTTOM" horizontalAlignment="ALIGN_CENTER">
<g:HTMLPanel ui:field="footerContentPanel" />
</g:Dock>
</g:DockPanel>
</g:ScrollPanel>
</g:layer>
</g:RootLayoutPanel>
But I have small problem: my footer isn't attached to bottom, no matter what i tried..
Does someone know the solution?
Layout Panels do not work properly in scroll panels. But scoll panels can be used in Layout Panels:
For example to scrolling the center part:
<g:DockLayoutPanel unit="EM">
<g:north size="5.0">
<g:HTMLPanel ui:field="headerContentPanel" />
</g:north>
<g:center size="1.0">
<g:ScrollPanel>
<g:FlowPanel ui:field="mainContentPanel" />
</g:ScrollPanel>
</g:center>
<g:south size="1.5">
<g:HTMLPanel ui:field="footerContentPanel" />
</g:south>
</g:DockLayoutPanel>
Another possibility is to use DockPanel instead Layout Panels.
If the header included in the scroll bar :
<g:ScrollPanel>
<g:DockPanel>
<g:Dock direction="NORTH" height="100px">
<g:HTMLPanel ui:field="headerContentPanel" />
</g:Dock>
<g:Dock direction="CENTER">
<g:FlowPanel ui:field="mainContentPanel" />
</g:Dock>
<g:Dock direction="SOUTH" height="100px">
<g:HTMLPanel ui:field="footerContentPanel" />
</g:Dock>
</g:DockPanel>
</g:ScrollPanel>
And then put this in RootLayoutPanel or RootPanel
Or use DockPanel in Layout Panels.
For example: we want to have scrollable header and center part, but west panel and bottom always in view:
<g:DockLayoutPanel width="100%">
<g:west size="100.0">
<g:Label>West side </g:Label>
</g:west>
<g:center>
<g:ScrollPanel>
<g:DockPanel>
<g:Dock direction="NORTH" height="100px">
<g:HTMLPanel ui:field="headerContentPanel" />
</g:Dock>
<g:Dock direction="CENTER">
<g:FlowPanel ui:field="mainContentPanel" />
</g:Dock>
</g:DockPanel>
</g:ScrollPanel>
</g:center>
<g:south size="50">
<g:HTMLPanel ui:field="footerContentPanel" />
</g:south >
</g:DockLayoutPanel>
And then put this in RootLayoutPanel.
Forget all the GWT (UiBinder) syntax and all the cascaded layout for a moment. Just consider this simplified example:
We have a window, let's say with a current height of 1000px.
We have a container (just imagine a simple black box) that takes up 100% of the window height - so it has 1000px height.
In this case, there is nothing to scroll. So with scroll=auto there will be no scroll bar on the window. (Forget any possible scroll bars inside our black box.)
If you want a layout where the header stays on top, while everything else scrolls (with a scrollbar that takes up 100% height), you should probably start with a header with "position=fixed". So what you would do in HTML is this:
<div class="headerContent">My header</div>
<div class="everythingElse">
<div class="mainContent">...</div>
<div class="footerContent">My footer</div>
</div>
CSS:
.headerContent {
position: fixed;
top: 0;
left: 0;
height: 5.0em;
width: 100%;
background-color: red;
}
.everythingElse {
margin-top: 5.0em; /* Same as the height of the header */
}
You can do the same in GWT UiBinder. Just replace the divs with simple FlowPanels (if you like), and apply the css (with a UiBinder CSS class referenced using the addStyleNames attribute). No DockPanels needed. When the height of "everythingElse" exceeds the window height, the default setup of the body tag shows the scroll bar.
Newbie Alert:
I have been furiously looking for a way to size a particular cell of a HorizontalPanel.
What I am trying to do is implement a 2-cell Horizontal Panel and set the left cell to say 200px. However, I am trying to make the right cell fill the rest of the window, not its cells contents.
I cannot see the wood for the trees, please help...
HorizontalPanel horizontalPanel=new HorizontalPanel();
horizontalPanel.setWidth("100%");
Widget widget1=new Widget();
Widget widget2=new Widget();
horizontalPanel.add(widget1);
horizontalPanel.add(widget2);
horizontalPanel.setCellWidth(widget1,"200");
In above code if the widget2's width is set to 100% then widget2 will fill rest of the window.If the widget2's width is not 100% it will not fill rest of the window.Just check the width of your second cell content.It should not be 100%.
I found I needed to tweak Damo's answer slightly to make this work.
You have to set the explicit size of the widget in the first cell. But then set the second cell to have a width of 100%.
<g:HorizontalPanel width="100%">
<g:cell>
<g:SimplePanel width="200px"/>
</g:cell>
<g:cell width="100%">
<g:SimplePanel width="100%"/>
</g:cell>
</g:HorizontalPanel>
Or if you are doing this with UiBinder:
<g:HorizontalPanel width="100%">
<g:cell width="200">
<!-- Stuff -->
</g:cell>
<g:cell>
<!-- More Stuff -->
</g:cell>
</g:HorizontalPanel>