CSS selector/inheritance in GWT UiBinder when using external stylesheet - gwt

I am using GWT 2.4.0 + UiBinder.
In my ui.xml file i have referenced external style sheet using below line.
<ui:style
type="com.codelaboration.twykin.frontend.widgets.qa.client.view.QABox.QAStyle"
src="QABox.css" />
Now i have below code in the same ui.xml file
<div class="{style.imagePanel}">
<div ui:field="lblUser"/>
</div>
In QABox.css i have defined the "imagePanel" and also used CSS inheritance for applying the CSS to all divs inside the imagePanel class:
.imagePanel {float: left; width: 100px; text-align: center;}
.imagePanel div {float: right; width: 530px;}
Now the problem is GWT is obscufacting the style name, so now imagePanel will be changed to some weird name, so the ".imagePanel div" wont going to work. So basically my question is how to use CSS selector in UiBinder when external stylesheet had been declared in ui.xml only.
Thanks.

you can add external css in your gwt application.
you have to give the relative path to your style resource.
hear is the piece of code.
in your uibinder xml
<ui:style src="QAStyle/QABox.css" />
<div class="{style.imagePanel}">
<div ui:field="lblUser"/>
</div>
it will find css in the QAStyle package.
or you can also use ClientBundle that will avoid your path problems. See Using an external resource.
it will help you.

Related

If class exist in first parent then apply CSS

If class 'hello' visible then apply some css to 'banner2' class. is it possible? Looking for CSS solution not Javascript.
<div id="banner">
<div class="hello"></div>
</div>
<div class="banner2">
</div>
It's not possible to select a div based on visibility in CSS alone. You can easily use jQuery / JS, but since you don't want that I'd suggest trying out some trickery with CSS combinators and the checkbox hack, depending on how you are planning on changing the visibility of "hello".
The option doesn't exist yet in CSS.
When Selectors 4 will be available you could do it this way:
.banner:has(> .hello) + .banner2
But as of this moment, you can only do it with javascript

How can i vertical-align & horizontal-align components inside a FlowPanel?

As stated in http://www.gwtproject.org/doc/latest/DevGuideUiPanels.html, Google said we should not use HorizontalPanel & VerticalPanel to make layouts since it can have some browser incompatibility problems. Google suggests to use FlowPanel instead.
VerticalPanel can usually be replaced by a simple FlowPanel (since block-level elements will naturally stack up vertically).
HorizontalPanel is a bit trickier. In some cases, you can simply replace it with a DockLayoutPanel, but that requires that you specify its childrens' widths explicitly. The most common alternative is to use FlowPanel, and to use the float: left; CSS property on its children. And of course, you can continue to use HorizontalPanel itself, as long as you take the caveats above into account.
However, we now run into another problem.
How to vertical-align & horizontal-align components inside a FlowPanel?
This doesn't work.
<g:FlowPanel height="100%" addStyleNames="{res.css.alignMiddle}">
.alignMiddle{
vertical-align:middle;
}
I tried myFlowPanel.getElement().getStyle().setVerticalAlign(VerticalAlign.MIDDLE); but it also doesn't work.
Also, another approach is to use <table> html tag inside a HTMLPanel, but some people said different browsers may render gui differently the widgets inside <table> causing some quirks. Google doesn't suggest to use <table> inside a HTMLPanel, so we shouldn't use.
But, then:
How to vertical-align & horizontal-align components inside a FlowPanel?
i found a solution
<g:FlowPanel addStyleNames="{res.css.outer}">
<g:FlowPanel addStyleNames="{res.css.alignMiddle}">
more widget here....
</g:FlowPanel>
</g:FlowPanel>
.outer {
display: table;
height: 100%;
width: 100%;
}
.alignMiddle{
display: table-cell;
vertical-align: middle;
text-align:center;
}

FlowPanel vs. HTMLPanel in GWT UiBinder

When using UiBinder what is the preferred method of creating a simple layout like this?
FlowPanel:
<!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'>
<ui:style>
.outer {
display: table;
height: 100%;
width: 100%;
}
.inner {
background: #DDD;
display: table-cell;
vertical-align: middle;
}
</ui:style>
<g:FlowPanel styleName="{style.outer}">
<g:FlowPanel styleName="{style.inner}">
<g:Label ui:field="someLabel"/>
</g:FlowPanel>
</g:FlowPanel>
</ui:UiBinder>
HTMLPanel:
<!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'>
<ui:style>
.outer {
display: table;
height: 100%;
width: 100%;
}
.inner {
background: #DDD;
display: table-cell;
vertical-align: middle;
}
</ui:style>
<g:HTMLPanel styleName="{style.outer}">
<div class="{style.inner}">
<g:Label ui:field="someLabel"/>
</div>
</g:HTMLPanel>
</ui:UiBinder>
Edit: I know they produce the same html when rendering, I'm wondering if there is any justification for using one style over the other.
The javadocs say that the FlowPanel is the simplest panel, but at what point does using an HTMLPanel become preferable. e.g.
<FlowPanel>
<FlowPanel>
<Widget>
</FlowPanel>
<FlowPanel>
<Widget>
</FlowPanel>
</FlowPanel>
vs.
<HTMLPanel>
<div>
<Widget>
</div>
<div>
<Widget>
</div>
</HTMLPanel>
Thanks.
UiBinder - HTMLPanel vs. div is a fairly similar question but asks about using a div vs. a HTMLPanel.
Actually they will render same in your case - div. There is no difference unless you start adding more elements to FlowPanel.
You can try FlowPanel behaviour here:
http://examples.roughian.com/index.htm#Panels~FlowPanel
You should use HTMLPanel in cases when you need to write your own custom HTML code on the page. It allows to write HTML code inside of HTMLPanel tag.
For example you can't do such trick with FlowPanel.
I recently read Tags First GWT Programming. It seems to me, that the technique he describes would allow you to have much better control over the ultimate rendering of your page, while maintaining the advantages of GWT.
I think the dichotomy that you're asking about between FlowPanel and HTMLPanel isn't really the right question. Instead, it is best to recognize that they're meant for different things.
HTMLPanel is capable of a lot more than FlowPanel is. When you need to dynamically add and remove widgets that are embedded in some custom html, use an HTMLPanel. If you just want some widgets to align together on the page with normal html flow (like some text and pictures) use a FlowPanel.
My personal advice would be to use the simplest thing that can do what you need it to.
I recommend the second example. If possible you should prefer using a plain HTML tag such as "div" over a widget such as "FlowPanel" because of the overhead having an unused logical widget.
This may seems trivial first but it saves you a lot of headache (memory leaks, gquery operations, ...) when you have to deal with a lot of items.

How to show initially hidden DIV with GWT?

I have a DIV tag which I can made either
display: none;
or
visibility: hidden;
Then I want to show it with GWT.
But when I am trying to do
RootPanel.get("myid").setVisible(true);
or
RootPanel.get("myid").setVisible(false);
and it has no effect.
I saw in Firebug, that thess functions add "display: none" or remove it in turn. Since there is one explicit "display: none" hardcoded, the DIV is constantly hidden.
So, how can I accomlish the task? Thanks.
In your JSP
<div id="myid" style="display:none ; width:100%">
In your GWT EntryPoint class
DOM.getElementById("myid").getStyle().setDisplay(Display.BLOCK);

Get UiBinder widget to display inline instead of block

I'm trying to get my UiBinder-defined widget to display inline, but I can't. My current code is:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' xmlns:g='urn:import:com.google.gwt.user.client.ui'>
<ui:style>
.section {
border: 1px solid #000000;
width: 330px;
padding: 5px;
display: run-in;
}
</ui:style>
<g:HTMLPanel>
<div class="{style.section}">
<div ui:field="titleSpan" class="{style.title}" />
<div class="{style.contents}">
<g:VerticalPanel ui:field="messagesPanel" />
</div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
This works fine in terms of how the widget looks internally, but I want to throw a bunch of these widgets into a FlowPanel and have them flow when the window is resized. The HTMLPanel is a div, but I can't get the display attribute to assign. I can't force the style name, since the following throws an error:
<g:HTMLPanel styleNames="{style.section}">
And I can assign an additional style, but it doesn't apply the display setting.
<g:HTMLPanel addStyleNames="{style.section}">
This displays the border and sets the size, as expected, but it doesn't flow. Firebug shows the styles on the div are border, width, and padding, but no display.
Is there a way to make a widget in UiBinder so that it'll display inline instead of block? And if so, can I make it compatible with having a VerticalPanel inside (can I do it without making the entire widget pure HTML without any GWT widgets)?
PS: I saw question 2257924 but it hasn't had any answers lately, and he seems to be focused on getting a tag, not specifically getting inline layout. I don't care directly about , if I can just get the top-level tag for my widget to flow inline, I'm happy.
It seems your problem is caused by using display: run-in instead of the more "standard" display: inline. IE and Firefox don't support run-in and it seems that Firebug prunes the style upon adding.
Try changing the style to display: inline (or inline-block if you want some properties of a block, like width, but beware of the quirks of IE + inline-block).
It should be <g:HTMLPanel styleName="{style.section}">, not <g:HTMLPanel styleNames="{style.section}"> - styleNames is a typo (which appears in the UiBinder docs, so I'm sure that's where you got it from). styleName is the correct thing to use.
Also, Igor Klimer is correct that you should use display: inline or display: inline-block rather than display: run-in.
In general, you can tell the available attribute names by looking for setXXX methods on the UIObject class, and the attribute name is just the XXX. So, UIObject has a setStyleName method, which you access using the attribute called styleName.