Problems with GWT panel types - java

thanks in advance for your help.
I'm currently trying to create a w3c standards compliant HTML/CSS interface for a GWT app, much of this rests on using the right types of panel in the right place rather than using nested horizontal and vertical panels which write out tables in the UI.
I'm a total n00b at GWT and cannot figure out why replacing the top Vertical Panel in the code below causes the app to stop working. Any UI coding resources, advice of any kind would be very much appreciated.
<g:VerticalPanel>
<g:FormPanel ui:field="loginFormPanel" action="/cms/j_acegi_security_check.rpc" >
<g:HTMLPanel>
<g:Label ui:field="signinLabel" styleName="{style.signinStyle}">
<ui:msg key="signInText">Welcome to Perform CMS</ui:msg>
</g:Label>
<g:Label ui:field="emailLabel" styleName="{style.loginFontStyle}">
<ui:msg key="emailAddress">Email adress</ui:msg>
address
</g:Label>
<g:TextBox ui:field="email" name="j_username" styleName="{style.loginTextBoxStyle}"/>
<g:Label styleName="{style.fontStyle}" ui:field="usernameError"/>
<g:Label ui:field="passwordLabel" styleName="{style.loginFontStyle}">
<ui:msg key="password">Password</ui:msg>
</g:Label>
<g:PasswordTextBox ui:field="password" name="j_password" styleName="{style.loginTextBoxStyle}"/>
<g:Label styleName="{style.fontStyle}" ui:field="passwordError"/>
<g:HTMLPanel ui:field="submitPanel">
<g:HTMLPanel ui:field="submitButtonPanel" styleName="{style.buttonPanelStyle}">
<g:Image url="/cms/images/new_button_search_left.png" styleName="{style.image}"></g:Image>
<g:Label ui:field="signIn" styleName="{style.submitLabelStyle}">
<ui:msg key="signIn">Sign in</ui:msg>
</g:Label>
<g:SubmitButton styleName="{style.hide}">Submit</g:SubmitButton>
<g:Image url="/cms/images/new_button_search_right.png" styleName="{style.image}"></g:Image>
</g:HTMLPanel>
</g:HTMLPanel>
<g:HTMLPanel ui:field="submitErrorsPanel" styleName="{style.submitErrorPanel}">
<g:Label styleName="{style.fontStyle}" ui:field="submitErrorMessages"/>
</g:HTMLPanel>
</g:HTMLPanel>
</g:FormPanel>
<g:HTMLPanel ui:field="loginSuccessPanel" styleName="{style.hide}">
<g:Label styleName="{style.fontStyle}" ui:field="loginSuccessMessageLabel"/>
</g:HTMLPanel>
</g:VerticalPanel>

You don't say how your app stops working, but the GWT compiler generates different JS for every user agent specified in your project's gwt.xml. By default there may be 5 or 6 different versions of your program and the right one is decided in at runtime. These versions exist because there is no such thing as W3C compliance in browsers. One browser might get closer than others but all have their quirks that GWT tries to hide you from.
The GWT vertical panel at your root usually gets turned into a table with each child being a cell in a row. Note you still need a root element in the XML, but it could be a flow or html panel. Changing from a vertical panel will probably cause the child elements to flow sideways or do other weird things. If you wanted them to stay vertical you could throw a <br> between them, or style the enclosing <div>.
The best thing to do for layout issues is to install a tool into your browser which allows you to inspect the DOM. For example, Firefox has Firebug, IE has the IE Developer Toolbar, Opera has a developer console etc. You can select the errant element and see its place in the hierarchy as well as which styles apply to that element. Firebug even let you tweak styles in real time which can be handy for on the spot experimentation.

Related

Vaadin FormLayout formatting

Im new at vaadin 7 and have a little issue with formatting.
I have spend a few hours but no luck.
I have:
2 Form layouts on my vertical Layout.
2 Labels on each form layout.
Better check the screenshot
I want format label test as on the right part of screenshot.
Can you please advice or share thoughts or ideas.
I'm not 100% certain if I get what you're trying to do, but you might be able to achieve this through custom CSS.
It is hard to write out the exact CSS since it would require seeing the HTML generated by Vaadin and testing it with that, but it would be something like this for the labels:
.padded-form-layout v-caption:first-child {
float: left;
padding-left: 30px; /* set desired padding used for each label */
}
Of course, you'll need something similar for the values as well.
Above, padded-form-layout is the class name you define for layouts that need this look. In Java:
formLayout.setStyleName("padded-form-layout");
To figure out what the CSS modifications needed are I recommend you open the page in browser (Chrome or Firefox will do) and use the dev tools to directly modify the CSS to figure out what rules are needed. I usually do this by simply typing a style tag to the element, something like this (in this example, style="XXXXX" would be added manually. This is possible at least with Chrome's developer tools):
<div class="v-formlayout v-layout v-widget v-has-width" style="width: 100%;">
<!-- ... -->
<td class="v-formlayout-captioncell">
<div class="v-caption v-caption-hasdescription">
<span id="gwt-uid-21" for="gwt-uid-22" style="XXXXX">First name:</span>
<span class="v-required-field-indicator" aria-hidden="true">*</span>
</div>
</td>
<!-- ... -->
</div>
To be able to use the CSS, you'll need to either add it to your theme somehow and compile it (see Vaadin documentation about themes), or by using the #StyleSheet annotation

Gwt custom text box having baloon popup

how to make a custom text box in Google web toolkit(gwt) having balloon feature of displaying error messages?
i am using Google web toolkit(gwt) in java on eclipse and i don't see any function providing this functionality.
You should implement your own "composite". To "compose" a "balloon"/tooltip with the inputs of your form.
Here is an example of the ui.xml for a text area using Gwt-bootstrap. (Doing the same in plain GWT is straightforward, if not, I'll be glad to convert this example).
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:b="urn:import:com.github.gwtbootstrap.client.ui">
<b:WellForm>
<b:Fieldset>
<b:ControlGroup>
<b:Label styleName="field_label" ui:field="label" />
<b:TextArea ui:field="myWidget"/>
<b:HelpInline ui:field="errorMessage" visible="false" />
</b:ControlGroup>
</b:Fieldset>
</b:WellForm>
If by "balloon" you mean "tooltip", then add a mouseOverHandler and a mouseOutHandler to display/hide the error message (HelpInline here, but could be any widget) when there is one to display.
If you are satisfied with this you should implement some inheritance mechanism to reuse everything around this tag
<b:TextArea b:id="textArea" ui:field="textArea"/>
for all kinds of widgets.
By using composite you can have a single line reused for all error messages ("balloons" or something else) for all your input widgets, and switch between HelpInline, Label, etc easily.
EDIT
The sample code with plain GWT
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HorizontalPanel ui:field="widgetContainer">
<g:Label styleName="field_label" ui:field="label" />
<g:TextArea ui:field="myWidget"/>
<g:Label ui:field="errorMessage" visible="false" />
</g:HorizontalPanel>
I suggest using a HorizontalPanel to display the field's label (ui:field="label"), the input field itself (ui:field="myWidget") and the error message (ui:field="errorMessage") on one line, but other kind of panels are also possible, or you can use CSS to position the elements as you want.

Write Multiple Full HTML 'Files' to Single Output Stream?

I'm writing a testing utility- I want to show multiple finished HTML "pages" in a single browser window.
Is this possible? I'm using Java Servlets.
For example, normally the user goes to a utility screen, fills in a bunch of fields and POSTS this to my servlet, which builds up a full HTML stream based on their input and writes it to HttpServletResponse.getWriter(). When the user views source, they get a <html> ... </html>.
What I want to do is allow users to request multiple "screens" and get the results in a single web page where you'd scroll down to see the 2nd, 3rd, etc. screens, maybe there is some kind of divider in between. I thought of frames or iframes, but didn't have luck. I have seen where I can write my big html stream to a javascript variable, then use document.write to dump it into the iframe. But that seems pretty awkward, and I'd have to be really careful about escaping quotes and stuff.
You will have to use iframes or frames to do this. A single web page can only contain one set of html tags and thus one html page.
Another idea would be to render the page by your script and then capture a picture of it and then have a page containing images. You will of course loose all interaction with the page.
I'm not sure what you're trying with your frames, but I imagine frames should work OK for what you've described.
Instead of trying to post to more than one URL from your form, you just post to a servlet that returns a page with the frameset, and each frame has a source that points to one of the URLs you want to test. For example:
<form action="testServlet" method="post">
<input type="text" name="someValue" />
</form>
The testServlet then returns a page with this content:
<frameset rows="33%,33%,33%">
<frame src="testUrl1?someValue=value">
<frame src="testUrl2?someValue=value">
<frame src="testUrl3?someValue=value">
</frameset>
The only problem with this is that you're doing a GET instead of a POST, but that's easy to get around. All you would need do is to implement the doGet method within your servlets and just call doPost from within doGet.
Just leave out the <html>/</html> tags for each page and wrap the whole thing inside a single large ....
Like this maybe:
<html>
[page1Content]
<hr />
[page2Content]
<hr />
[page3Content]
<hr />
</html>

How to put Google Adsense in GWT

Do anyone know how to put Google adsense ads inside a GWT web application?
You can put the javascript-code from Adsense in the single HTML page that GWT starts with. This way the advertising will not be displayed in the same area as GTW but above/below the GWT code. For advertising that could be ok.
This example places a baner above the application:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>www.javaoracleblog.com</title>
<script type="text/javascript" language="javascript" src="com.javaoracleblog.aggregator.nocache.js"></script>
</head>
<body>
<script type="text/javascript"..
ADsense code here
</script>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
</body>
</html>
In order to indicate to Google WT that the site of Google adsense can be trusted you need to add a regex matching URL to the -whitelist command line argument.
Note that this will probably not solve the problems desribed in the above "Why I dumped GWT" article.
According to this thread on AdSense:
Short version, you can't use Adsense
via Ajax without breaking the
programme policies/t&c's
Long version...
Ad code passed through an xmlhttp call
is not rendered, it's just treated as
text (hence, responseText). The only
way to execute js code is to use
"responseXML" coupled with the
"exec()" command.
For instance...
If your xml contains something along
the lines of:
This is the
content from the external
file javascript code
goes here
You would assign a variable (called
page_data for instance) using
ajax_obj.responseXML, run the XML
through a parser and run
exec(js variable or line from XML
here);
Not really helpful from an Adsense
standpoint, but that's how it's done.
It's also worth mentioning Why I dumped GWT:
Another problem were my adsense
banners. Since I didn’t have a lot of
content on the page, the banners were
sometimes off topic. An even bigger
problem was that the banners stayed
the same when people searched for
different keywords (since the ajax
refresh didn’t trigger an adsense
refresh). I solved this by doing the
search with a page refresh instead of
an ajax call. The ajax part of the
site was limited to sorting, faceting,
i18n and displaying tips.
You might check out the interview I did with InfoQ. It includes a sample chapter from my book and it happens to be on SEO.
It's not trivial, but I think the solutions in the chapter let GWT work nicely in an environment where SEO is important. The basic solution is to implement something I call 'bootstrapping'. This means that your pages take the info that would normally come across in GWT-RPC requests and serialize them into the page. The GWT widget then loads this information without an RPC request. While your page serializes the info into JavaScript, it's easy to also write a <noscript> to the page that can be used for SEO.
Take a look at the PDF included here: InfoQ GWT it goes into all the detail. The whole sample project is here: google code with source on github.
If you really want AdSense to be kinda "inside" GWT I'd use the Frame widget. Basically the Frame widget generates an <iframe ...> inside your GWT code. First I've thought iframe, UGH! But the <iframe> tag is still part of the HTML5 spec and has been even extended by some attributes that seem to be there for exactly this "sandboxing" purpose. And with corresponding CSS styling you will not have any scrollbars around your <iframe>.
And here is the actual solution:
You should put
<ui:style>
.sponsor {
border: 0em;
width: 20em;
height: 6em;
float: right;
display: inline;
}
</ui:style>
<g:HTMLPanel>
<g:Frame ui:field="sponsor" url="issue/extern/Google-AdSense.html" styleName="{style.sponsor}"/>
</g:HTMLPanel>
into your .ui.xml file and the logic into the corresponding .java file:
#UiField
Frame sponsor;
Also you should put the actual Google AdSense code (the <script> stuff) into a separate HTML file inside GWT's public folder which is - in this case - called Google-AdSense.html and is located inside the extern folder inside the public folder. issue (in the Frame url attribute) is in this case the GWT output folder.
And here is how it looks like: The ad in the upper right corner.
Btw this is also the way to embed the Google Analytics code into GWT.
Here is how I do it. I have a demo and source code here: http://code.google.com/p/gwt-examples/wiki/DemoGwtAdsene
You can use AdSense and GWT together without using frames or other hacks if you take some care in how you create your host pages.
The key is to include your AdSense code in the host page and then to manipulate the dom element containing the ad but to not detach it from the page. So you can reposition the ads into the body of your other gwt code as long as the dom structure is not changed.
If you do detach and reattach the containing dom element then it will appear to work in Chrome and Firefox but IE will show a blank space. I tried initially to move the ads DIV element into a DockLayoutPanel and thought everything was great until I belatedly tested it in IE.
So this is OK:
Element element = Document.get().getElmentById("ad");
element.getStyle().setPosition(ABSOLUTE);
element.getStyle().setTop(20, PX);
But this is not:
myPanel.add(ElementWrapper.wrap(element));
because adding a widget to another widget re-parents it.
This means that you cannot use any of the built-in LayoutPanel stuff to hold your ad div because Layout cannot wrap an existing element (It creates its own DIV in its constructor). You may be able to modify the layout panel stuff so it wraps an element and does not re-parent it... but I have not tried this yet.
I've tested the results in IE6+, Chrome and Firefox. Downside is that you cannot refresh the ads unless you load a new page. But in my case GWT was used to enhance html pages so that was not an issue. In any case... are users more likely to click on a different ad than one they read several times? Not sure it is so vital.
I could do this using DFP Small Business + Async Publisher tag + AdSense integration:
Here is the code:
On of your host page, put your publisher tag, something like:
<head>
<script type="text/javascript" src="http://www.googletagservices.com/tag/js/gpt.js"></script>
<script type="text/javascript">
var slot1 = googletag.defineUnit('/XXXX/ca-pub-YYYYYYYYYYYYYYY/transaction', [468, 60], 'div-gpt-ad-ZZZZZZZ-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
</script>
...
</head>
I've created a view with uiBinder, with a div with the id specified at the head, like this:
<g:HTMLPanel height="62px" width="100%">
<div id='div-gpt-ad-ZZZZZZZ-0' style='width:470px; height:60px;'>
</div>
</g:HTMLPanel>
On the onLoad() method of the view, you initialize the ad, like this:
#Override
protected void onLoad() {
setupAd();
}
public static native void setupAd() /*-{
$wnd.googletag.cmd.push(function() {$wnd.googletag.display('div-gpt-ad-ZZZZZZZ-0')});
}-*/;
To refresh the ad, just call refresh ad for the slot specified at head:
public static native void refreshAd() /*-{
$wnd.googletag.pubads().refresh([$wnd.slot1]);
}-*/;
That's all!
For more information about the publisher tag, check:
http://support.google.com/dfp_sb/bin/answer.py?hl=en&answer=1649768
Now I'm struggling to know how to make AdSense bot to craw my ajax application. I've implemented the Ajax Crawling scheme:
https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
But I've got the information from AdSense forum that the AdSense bot (Mediapartners-Google) doesn't work with "escaped fragment" Ajax scheme.
Does anybody know if Google plan to make any progress on that?
This limits this approach to serve just interest based ads, since the context based ad serving depends on ajax crawling scheme.
Google's AdSense bot crawls your page to determine what ads to serve. Therefore, you should not put AdSense on pages with mostly dynamic content. It won't work well.
Maybe you should look into other ad programs?

Jasper report generating bad HTML

If I view the HTML generated by one of my Jasper reports in IE7 I see the following:
<BR /><BR />
<A name="JR_PAGE_ANCHOR_0_1">
<TABLE style="WIDTH: 1000px" cellSpacing="0" cellPadding="0" bgColor="#ffffff" border="0">
<-- table body omitted -->
</TABLE>
The two BR tags are added via the JRHtmlExporterParameter.HTML_HEADER parameter. After these tags and before the beginning of the report table that there's an unclosed anchor tag that is generated by Jasper reports. The fact that this tag is not correctly closed is messing up the formatting of my report because IE is hyperlinking the entire report TABLE. I'm not using this anchor tag, so if I could prevent Jasper from generating it, that would solve my problem.
Incidentally, this problem only occurs in IE, in Firefox everything works fine because the anchor tag is properly closed.
Thanks in advance,
Don
I took Phil's advice and dove into the Jasper source code. I've fixed the problem and submitted it to the project. Details of the cause and resolution are available here.
That's odd code, the <br /> tags are XHTML-style, while the unclosed a tags are good old HTML, like the upper case tag names. If you serve such page with plain HTML header/content-type, perhaps IE will be happy.
When you write that Firefox closes the tag, I suppose you mean it correctly doesn't extend the hyperlink span over block tags. Note that FF's view source can display closing tags that are not there when you save the page to disk!
Frankly, I don't know if you can get rid of these anchors with some config. If nobody comes with a real solution, maybe you can download Jasper's source code and search JR_PAGE_ANCHOR in it, looking if the code generating it is conditionally driven.
Or, if you can, you can apply post-processing of the generated code.
In excel export A1 cell transfor to JR_PAGE_ANCHOR_0_1.Some of tips are setting IS_ONE_PAGE_PER_SHEET property doing true, IS_DETECT_CELL_TYPE doing true but these are not working for me.
To avoid from this situation , configure your xlsx report configuration is worked for me (set ignore anchor is key point);
private final SimpleXlsxReportConfiguration xlsxReportConfiguration;
JRAbstractExporter exporter;
this.xlsxReportConfiguration = new SimpleXlsxReportConfiguration();
...
xlsxReportConfiguration.setIgnoreAnchors(true);
...
exporter = new JRXlsxExporter();
exporter.setConfiguration(xlsxReportConfiguration);

Categories

Resources