Is it possible to reference an ImageResource with #url in UiBinder, when the ImageResource and the UiBinder are not in the same package?
For example:
My shared ClientBundle :
package com.myproject.client.resources;
class SharedResources extends ClientBundle {
ImageResource myImage();
}
And, the UiBinder file in package com.myproject.client.anotherpackage
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field="res" type="com.myproject.client.resources.SharedResources"/>
<ui:style>
#url myImg {insert reference to res.myImage}
.theClass {
background: myImg no-repeat center center #d7d6d6;
width: 21px;
}
</ui:style>
<g:HTMLPanel styleName="{style.theClass}"/>
</ui:UiBinder>
I know I could move the CSS to com.myproject.client.resources and then I would have easy access to the myImage (since the CSS and myImage would be in the same package), but I would prefer to keep the CSS inside the UiBinder and reuse the shared myImage from within the UiBinder.
There's a discussion regarding this issue here, but it does not answer my question:
https://groups.google.com/forum/#!topic/google-web-toolkit/ExOJAEfQmkY
I reached the same problem and my solution was to use ui:image. This solution will not reuse and refer directly to the ClientBundle like I think you want, but it gives you the possibility of not moving your CSS, or copying the image to your folder, or creating a new ClientBundle.
The code is something like:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field="res" type="com.myproject.client.resources.SharedResources"/>
<ui:image field="resImage" src="../resources/image.png" />
<ui:style>
#url myImg resImage
.theClass {
background: myImg no-repeat center center #d7d6d6;
width: 21px;
}
</ui:style>
<g:HTMLPanel styleName="{style.theClass}"/>
</ui:UiBinder>
I kept the SharedResources reference just to illustrate using your example, but it isn't being used in this case.
Related
I want to create a wrapper-widget that is providing some kind of "default" layout for different pages. I want to be able to do something like this:
<!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:m="urn:import:gwt.material.design.client.ui"
xmlns:m.addins="urn:import:gwt.material.design.addins.client.ui"
xmlns:mz="urn:import:com.mz.client.admin.widget"
>
<ui:style>
</ui:style>
<mz:defaultpagelayout.DefaultPageLayout>
<m:MaterialTitle title="Basic Information"/>
<m:MaterialTextBox text="Forename"/>
<m:MaterialTextBox text="Surname"/>
</mz:defaultpagelayout.DefaultPageLayout>
</ui:UiBinder>
Where DefaultPageLayout is just a container that provides a certain look for the actual content. I've tried to do it like this:
DefaultPageLayout.ui.xml:
<!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:m="urn:import:gwt.material.design.client.ui"
xmlns:m.addins="urn:import:gwt.material.design.addins.client.ui">
<ui:style>
.main-content {
padding: 20px;
}
</ui:style>
<g:HTMLPanel addStyleNames="{style.main-content}">
</g:HTMLPanel>
</ui:UiBinder>
DefaultPageLayout.java:
public class DefaultPageLayout extends Composite {
private static DefaultPageLayoutUiBinder uiBinder = GWT.create(DefaultPageLayoutUiBinder.class);
interface DefaultPageLayoutUiBinder extends UiBinder<Widget, DefaultPageLayout> {
}
public DefaultPageLayout() {
this.initWidget(uiBinder.createAndBindUi(this));
}
}
But this is actually not working:
[ERROR] Found unexpected child element: <m:MaterialTitle title='Basic Information'> (:13)
What do I have to do to get such a widget working for me here?
Your DefaultPageLayout needs to implement HasWidget (and ideally HasWidgets.ForIsWidget)
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
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.
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.
I would like to share a CSS across multiple widgets using .
I can see that css class name are obfuscated but the class definition
is not showing up when I inspect the element in firefox / chrome.
Here're my codes. Can anyone suggest what am I missing? Thanks.
Style.css
.nameSpan { color: #3E6D8E; background-color: #E0EAF1;}
Resources.java
public interface Resources extends ClientBundle {
#Source("Style.css")
Style style();
public interface Style extends CssResource {
String nameSpan();
}
}
uibinder.ui.xml
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='com.my.app.widgets.logoname.Resources'/>
<g:HTMLPanel>
<div>
Well hello there
<g:InlineLabel ui:field='nameSpan' styleName="res.style.nameSpan">kevin</g:InlineLabel>
</div>
</g:HTMLPanel>
</ui:UiBinder>
uibinder.class
public class uibinder extends Composite {
private static uibinderUiBinder uiBinder = GWT.create(uibinderUiBinder.class);
interface uibinderUiBinder extends UiBinder<Widget, uibinder> {}
#UiField(provided = true) final Resources res; // the style doesn't show no matter provided=true is declared or not.
public uibinder(Resources res) {
res = GWT.create(Resources.class);
initWidget(uiBinder.createAndBindUi(this));
}
You have to use res.style().ensureInjected()
You need to assign the style (styleName attribute) somewhere. For example:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:with field='res' type='com.my.app.widgets.logoname.Resources'/>
<g:HTMLPanel>
<div>
Well hello there
<g:InlineLabel ui:field='nameSpan' styleName="{res.nameSpan}">kevin</g:InlineLabel>
</div>
</g:HTMLPanel>
</ui:UiBinder>
The attribute ui:field you've declared does not set the css style. It defines the attribute that is to be filled in in your uibinder class. See the GWT doc for some guidance.