Duplicating widget in UiBinder XML file - gwt

Let's say I have Toolbar widget with buttons I'm passing in XML definition. I'd like to have the same toolbar both on top and bottom of the widget I'm creating.
<g:HTMLPanel>
<ns:Toolbar>
<g:Button ui:field="b1Top">1</g:Button>
</ns:Toolbar>
<p>Lorem ipsum</p>
<ns:Toolbar>
<g:Button ui:field="b2Bottom">1</g:Button>
</ns:Toolbar>
</g:HTMLPanel>
This way I need to assign same handlers individualy for each button. Is there any way to define the toolbar in one place without creating new toolbar widget with particular widgets to show?
I hope you understand what I want to achieve. :)

Well you can always create a Ui-Binder for your Toolbar and declare the methods and handlers for the buttons. and then use multiple instances of it.
Toolbar ui-binder
<ns:Toolbar>
<g:Button ui:field="b1Top">1</g:Button>
</ns:Toolbar>
Your ui-binder
<g:HTMLPanel>
<TB:Toolbar />
<p>Lorem ipsum</p>
<TB:Toolbar />
</g:HTMLPanel>

This is not exactly what you've asked, but you can set multiple widgets in the #UiHandler parameters:
#UiHandler( { "b1Top", "b2Bottom" } )
void onButtonClick(ClickEvent event) {
Window.alert("Click !");
}

Related

May I use DockLayoutPanel in DialogBox in GWT

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

Using a TreeItem with a Widget as content in a single GWT UiBinder template

I am attempting to initialise a TreeItem with a Widget defined within a UI Binder template as the TreeItem's content. Initially I started with a template like this:
<g:Tree>
<g:TreeItem>
<g:HTMLPanel>
<p>This is the root item's content.</p>
</g:HTMLPanel>
<g:TreeItem>
<g:HTMLPanel>
<p>This is the child's content.</p>
</g:HTMLPanel>
</g:TreeItem>
</g:TreeItem>
</g:Tree>
Expecting to end up with a tree structure something like this:
+ This is the root item's content.
Expanding to:
- This is the root item's content.
\ This is the child's content.
But this doesn't work. The HTMLPanel widgets are created as children of the TreeItems, rather than being the items' widgets, so I end up with a structure like this:
- (root item has no content)
\ This is the root item's content.
- (first child has no content)
\ This is the child's content.
So I tried extending the TreeItem class like so:
public class WidgetTreeItem extends TreeItem {
#UiChild(tagname="widget", limit=1)
public void setWidget(IsWidget isWidget) {
super.setWidget(isWidget.asWidget());
}
}
And then, importing the package containing WidgetTreeItem into the c namespace, I have a template like this:
<g:Tree>
<c:WidgetTreeItem>
<c:widget>
<g:HTMLPanel>
<p>This is the root item's content.</p>
</g:HTMLPanel>
</c:widget>
<!-- Should create a child TreeItem with the HTMLPanel as its Widget. -->
<g:HTMLPanel>
<p>This is the child's content.</p>
</g:HTMLPanel>
</c:WidgetTreeItem>
</g:Tree>
But this doesn't work, either. It fails with the following exception:
Only TreeItem or Widget subclasses are valid children: <c:WidgetTreeItem>.
Can anyone see how to achieve what I am attempting?
Given a little inspiration from this answer, I have found my solution. Given my original example, the XML now looks like this:
<g:Tree>
<g:HTMLPanel ui:field="rootContent">
<p>This is the root item's content.</p>
</g:HTMLPanel>
<g:HTMLPanel ui:field="childContent">
<p>This is the child's content.</p>
</g:HTMLPanel>
<g:TreeItem widget="{rootContent}">
<g:TreeItem widget="{childContent}">
</g:TreeItem>
</g:TreeItem>
</g:Tree>
Some playing around was required here. Most notably, this only works provided that the content panels are contained within a widget implementing the HasWidgets interface. The Tree class satisfies this requirement. It is also worth noting that the content fields must be defined before they are used.
Probably following could help you.
<g:Tree>
<g:TreeItem text="This is the first parent item's content.">
<g:TreeItem text="This is the child 1's content." />
<g:TreeItem text="This is the child 2's content." />
</g:TreeItem>
<g:TreeItem text="This is the second parent item's content.">
<g:TreeItem text="This is the child 3's content." />
<g:TreeItem text="This is the child 4's content." />
</g:TreeItem>
</g:Tree>
You can append TreeItems as many as you want.

GWT Activity : How to use an activity, place, eventbus and uibinder

I'm new at GWT and I wonder myself how to use an Activity, Place ,EventBus and UIbinder.
The layout of my app is smth like this :
Widget 1:
<g:DockLayoutPanel ui:field="myPanel" unit='PX'>
<g:north size='60'>
<m:HeaderPanelImpl styleName='{res.style.panelBorder}' ui:field='headerPanel' />
</g:north>
<g:south size='60'>
<g:HTMLPanel styleName='{res.style.panelBorder}' ui:field='footerPanel' />
</g:south>
<g:center>
<g:SimpleLayoutPanel styleName='{res.style.panelBorder}' ui:field='centerPanel' />
</g:center>
</g:DockLayoutPanel>
Here in "widget1.headerPanel" a have navigation which controls which widget to be shown in “widget1.centerPanel”.
The widgets which have to be shown in “widget1.centerPanel” are “widget2.0” and ”widget2.1”.
Widget2.0
<g:DockLayoutPanel unit='PX'>
<g:north size='100'>
<g:HTMLPanel styleName='{res.style.panelBorder}'>
<g:Label>TopPanel</g:Label>
</g:HTMLPanel>
</g:north>
<g:west size='200'>
<g:HTMLPanel styleName='{res.style.panelBorder}'>
<g:Label>LeftPanel</g:Label>
</g:HTMLPanel>
</g:west>
<g:east size='200'>
<g:HTMLPanel styleName='{res.style.panelBorder}'>
<g:Label>RightPanel</g:Label>
</g:HTMLPanel>
</g:east>
<g:center>
<g:SimpleLayoutPanel styleName='{res.style.panelBorder}' ui:field='centerPanel' />
</g:center>
</g:DockLayoutPanel>
Widget2.1
<g:HTMLPanel>
<g:Label>Settings</g:Label>
</g:HTMLPanel>
In ”widget2.0.topPanel” I have navigation which controls which widget will be shown in “widget2.0.centerPanel”
The widgets which have to be shown in “widget2.centerPanel” are “widget3.0” and ”widget3.1”.
Widget3.0
<g:HTMLPanel>
<g:Label>Content 1</g:Label>
</g:HTMLPanel>
Widget3.1
<g:HTMLPanel>
<g:Label>Content 2</g:Label>
</g:HTMLPanel>
My question is how to handle "onPlaceChangeEvent" ?
In example if url is mydomain.com/myapp.html#home:content1
the app has to show widget 1, widget 2.0 and widget 3.0
If the url is mydomain.com/myapp.html#home:content2
the app has to show widget1, widget 2.0 and widget 3.1
If the url is mydomain.com/myapp.html#settings
the app has to show widget1 and widget 2.1
I'm wondering between two variants :
To create to 2 ActivityManagers. One for the activities from widget1.navigation and one for the activites from widget2.navigation. But what happens if widget2 is created before widget 1 ?
To create one Activity which creates couple views.
Code:example
public class MonthlyViewActivity extends AbstractActivity implements MonthlyView.Presenter {
private Widget2_0 widget2_0;
private Widget3_0 widget3_0;
......
public void start(AcceptsOneWidget panel, EventBus eventBus) {
widget2_0 = new Widget2_0();
widget3_0 = new Widget3_0();
..........
}
....
}
What is the best practice for this case ?
if you are using eclipse create a MVP architecture in your project it will create many files like activity, place, one interface, one implementation class and a corresponding ui xml class. you have to create a activity mapper and activity history manager class. and in your on lode module set a default place for your application. after words on any event call go to method for any place and provide the link of your page and there check the get the value of token amd on basis of that value display your widgets what you want to display.

Gwt UIBinder DockLauout north element raise error as must contain a widget, but found <app:HeaderPanel ui:field='headerPanel'>

While trying to use Gwt UIBinder to have a custom widget loaded from main UI i am getting exception as
[ERROR] <g:north size='5'> must contain a widget, but found <app:HeaderPanel ui:field='headerPanel'> Element <g:DockLayoutPanel styleName='{style.outer}' unit='EM'> (:8)
while parsing XML in development mode. Below is the XML which I created for the same
<!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:app='urn.import:com.test.test.client'
xmlns:test='urn.import=com.test.test.client'>
<ui:style src="Resources/GlobalStyles.css" />
<g:DockLayoutPanel unit='EM' styleName='{style.outer}'>
<g:north size='5'>
<app:HeaderPanel ui:field='headerPanel' />
</g:north>
<g:west size='14'>
<test:FriendList ui:field='friendList' />
</g:west>
<g:center>
<g:HTMLPanel styleName='{style.boxPadding}'>
<div class="{style.titleBar}">Latest Activity</div>
<g:ScrollPanel ui:field='mainPanel' styleName='{style.mainPanel}' />
</g:HTMLPanel>
</g:center>
<g:south size="3">
<g:HTMLPanel styleName='{style.footerPanel}'>
<div>
Contact us
|
Privacy
|
About
</div>
</g:HTMLPanel>
</g:south>
</g:DockLayoutPanel>
</ui:UiBinder>
The headerPanel widget exits in the hierarchy. The corresponding code for above UiBinder is given below
public class TestApp implements EntryPoint {
#UiField
HeaderPanel headerPanel;
#UiField
ScrollPanel mainPanel;
RootLayoutPanel root;
private static TestApp singleton;
public static TestApp get() {
return singleton;
}
interface TestAppUiBinder extends UiBinder<DockLayoutPanel, TestApp> {
}
private static TestAppUiBinder uiBinder = GWT
.create(TestAppUiBinder.class);
#Override
public void onModuleLoad() {
// TODO Auto-generated method stub
singleton = this;
DockLayoutPanel outer = uiBinder.createAndBindUi(this);
root = RootLayoutPanel.get();
root.add(outer);
}
}
Basically I am novice in Gwt and trying to learn the things. Any pointer in this regard will be a great help.
Thanks.
What is
<app:HeaderPanel ui:field='headerPanel' />? If it does not extend Widget then it will not work. Try putting <g:Label>FOO</g:Label> in there and see if it works. Also make sure that your xmlns is correct. It will look for Header Panel in the package com.test.test.client. If you are trying to use the gwt Header Panel then it needs to be
<g:HeaderPanel ui:field="headerPanel" />
I think you are misunderstanding the xmlns. This tells gwt where to look for your java class. Both app and test are pointing to the same package. You should only add namespaces when you want to include your own custom widget classes or extra things like CellTable and DataGrid. I believe you are wanting to use the header.
Issue got fixed as it was xml parsing issue.
Thanks for providing inputs.

GWT - CssResource - common style - good practice

I have 5 views(.ui.xml). On every view i paste soemthing like that:
<ui:style src="../MyStyle.css" />
and on every button on every page I put styleName attribute:
<g:Button ui:field="buttonName" styleName="{style.myButtonStyle}" />
My Question is: Do I have to put styleName for all my buttons ? I would like to do something general style for this kind of widget .
What is good practice for this case?
Have you tried to customize GWT themes or create your own ? I think this is what you need to do.
Create your own button MyButton by extending Composite and define the UIBinder for this Button with style once.
Next you can re-use this button by adding your own namespace in the views.
Here's your widget :
package com.example.widgets;
...
public class MyButton extends Composite {
interface MyButtonUiBinder extends UiBinder<Widget, MyButton> {
}
private static MyButtonUiBinder uiBinder = GWT.create(MyButtonUiBinder.class);
#UiField
Button wrapped;
public MyButton() {
initWidget(uiBinder.createAndBindUi(this));
}
}
and the UIBinder file :
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
.myStyle {
text-shadow: gray;
color: gray;
font-size: 12px;
text-decoration: italic;
}
</ui:style>
<g:HTMLPanel>
<g:Button ui:field="wrapped" styleName="{style.myStyle}" />
</g:HTMLPanel>
</ui:UiBinder>
In your views, you can now include this button in the UIBinder files :
<!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:k='urn:import:com.example.widgets'>
<g:AbsolutePanel width="350px" height="225px">
<g:at left='10' top='0'>
<k:MyButton></k:MyButton>
</g:at>
</g:AbsolutePanel>
</ui:UiBinder>
If you need to set the text or other properties on your personal widget, simply delegate the methods from the wrapped button to expose them.
One way would be to use addStyleDependentName() which would create an additional style by appending that to the primary style name, and allow you to apply specific styling.
For example, .gwt-Button is the default primary style for Button. If you have a set of 5 (N) buttons you like to style in the same way, you'd instantiate them with , which would add an additional style for this button: .gwt-Button-customButton, which you can add to a .css file and include in the module once.