I'm starting work on a little HTML5 canvas game, and I was thinking GWT would be a great idea. I'd like to use Java, because 1. I have a lot of experience with it and 2. I would like to do it in an OO language. However, I read something about it being a pain to manage the HTML and CSS through GWT. So I was wondering, could I set up the canvas and style it using plain HTML+CSS, but then do everything else in GWT?
You don't need to use GWT to generate HTML or CSS.
I mostly use GWT with Ui:Binder, where the top-level element is HTMLPanel. Inside it, as much as possible is plain HTML and CSS. I try to keep project-level CSS in an outside .css file to ensure consistency, but you can pull as much CSS as necessary inside the Ui:Binder template.
Example of a Ui:Binder template, where I mix widgets (HTMLPanel, FlowPanel) with pure HTML. I use GWT widgets when I need some convenient functionality that they already provide, but you can deal with them as elements as well.
<ui:style>
.empty {
width: 100%;
line-height: 96px;
font-size: 16px;
text-align: center;
}
</ui:style>
<g:HTMLPanel>
<h2 class="sides">My Favorites</h2>
<div ui:field="emptyLabel" class="{style.empty}" >You have no favorites at this time.</>
<g:FlowPanel ui:field="container" addStyleNames="row flex-wrap" />
</g:HTMLPanel>
Related
I have list of articles in html.In every article i have multiple image tags like added below
<img alt="quick-start" class="alignnone size-full wp-image-16745" height="224" sizes="(max-width: 474px) 100vw, 474px" src="http://localhost/myfolder/my-content/uploads/2016/11/Quick-start.jpg" srcset="http://localhost/myfolder/my-content/uploads/2016/11/Quick-start.jpg 474w, http://localhost/myfolder/my-content/uploads/2016/11/Quick-start-300x142.jpg 300w" style="box-sizing: border-box; margin-top: 10px; margin-bottom: 10px;" width="474" />
Problem Statement:
I want to replace urls of image present in src, srcset i-e http://localhost/myfolder/my-content/uploads/2016/11/Quick-start.jpg to some other url.
whats the best approach to do that. I am thinking about functional programming in java
Yes this can be done using java.But it will be easy if you manipulate using java script framework like jquery.
$(".image2").attr("src","image1.jpg");
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
As far as I understand, GWT is not creating sprites by default except for some old browsers. Instead it stores images as Strings somewhere in javascript code or somehow else. I have heard that changing the property...
<set-property name='ClientBundle.enableInlining' value='false' />
...will force GWT to generate image sprites (i.e. big images combined from small icons) from image resources I provided.
The questions are:
1) can I force GWT to use my own sprite file our designer has created for me instead of generating such a file automatically?
2) what is the best way of dealing with images in GWT from your experience?
Create a ressource for your bundle image :
interface MyResources extends ClientBundle {
#Source("mySpriteImage.png")
ImageResource mySpriteImage();
#Source("myCss.css")
MyCssResource myCss();
}
interface MyCssResource extends CssResource {
String myBackground();
}
So now there are two ways to use the ImageResource obtained from MyResources. The first is to attach it to a CSS rule using the #sprite directive. myCss.css:
#sprite .myBackground {
gwt-image: "mySpriteImage";
}
.image1 {
width: 16px;
height: 16px;
background-position: 0 0;
}
.image2 {
width: 16px;
height: 16px;
background-position: -16px 0;
}
.image3 {
width: 32px;
height: 32px;
background-position: -16px -16px;
}
/* ... */
You create your sprites classes and set your class name.
<ui:UiBinder> <!-- Preamble omitted for this example. -->
<ui:with field="myResources" type="com.mycompany.MyResources"/>
<g:Image styleName="{myResources.myCss.myBackground} {myResources.myCss.image1}"/>
</ui:UiBinder>
JavaScript libraries like jQuery have the ability to dynamically add/remove classes to DOM elements like so:
$("#some-element").addClass("make-me-pretty");
This is important because it allows you to dynamically apply different styling rules to those elements.
In GWT-land, you might have a UiBinder XML snippet 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:gwt="urn:import:com.google.gwt.user.client.ui">
<div>
<span id="">Some content</span>
<gwt:RadioButton ...>
...
</gwt:RadioButton>
<!-- etc. -->
</div>
</ui:UiBinder>
For the non-Widget elements, such as the <span>, how can I dynamically add/remove classes in the Java code?
Speaking of <gwt:RadioButton>, I can't seem to find GWT's reference XSD for UiBinder XML, or some kind of official reference to the legal definitions for all the elements and attributes of com.google.gwt.* XML. For instance, where can I find documentation for what child elements and attributes gwt:RadioButton supports? And not just for that one widget, for all of them! Can someone point me in the right direction?
Thanks in advance!
You can find the UiBinder.xsd in gwt-user-<version>.jar (At least from 2.4.0 onwards, but I suspect older versions as well).
As for your other question: You can always traverse the DOM using
yourUi.getElement().getElementsByTagName( "span" )
and find the Element with the matching id, but that isn't very elegant. I actually have never encountered this situation; it is an interesting question!
Hope that helps.
Cheers,
To any UIobject (including RadioButton) you can:
yourUI.addStyleName("your-class");
in GWT: styleName = class
More UIObject methods
I think you can do something like this.
Map your as a UI field to a GWT 'SpanElement'.
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'>
<div>
Hello, <span ui:field='nameSpan'/>.
</div>
</ui:UiBinder>
In your class that binds to the above ui.xml file, you could change the class as follows
interface MyUiBinder extends UiBinder<DivElement, HelloWorld> {}
private static MyUiBinder uiBinder = GWT.create(MyUiBinder.class);
#UiField SpanElement nameSpan;
public HelloWorld() {
setElement(uiBinder.createAndBindUi(this));
}
public void changeClass(){
nameSpan.setClassName("newClass");
}
I guess you have a html page where you load your widgets into.
You could assign a class in the **.ui.xml file exactly like in a html page.
<div class="MyClass" align="middle">
<gwt:VerticalPanel>
.......
</gwt:VerticalPanel>
</div>
Then write you css rule in you main.css file.
.MyClass{background-color:black;}
When the view is loaded the the main.css file will "see" the name of the class and act upon it.
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?