Set of goodies for J2CL apps
APACHE-2.0 License
It's a set of helper processors that can speed up J2CL development by generating boiler-plate code.
The latest version: https://search.maven.org/search?q=g:org.treblereel.j2cl.processors
It contains the following features:
@GWT3EntryPoint acts pretty much the same as Gwt2 EntryPoint, the annotated method will be called on application startup.
public class App {
@GWT3EntryPoint
public void init() {
HTMLButtonElement btn = (HTMLButtonElement) DomGlobal.document.createElement("button");
btn.textContent = "PRESS ME !";
}
}
@ES6Module allows us to use Es6 modules via JsInterop.
@ES6Module
@JsType(isNative = true, namespace = "org.treblereel.j2cl.shim")
public class ES6Test {
public String id;
public native boolean isTest();
}
class ES6Test {
constructor() {
/** @type {string} */
this.id = "#id"
}
/**
* @return {boolean}
*/
isTest() {
return true;
}
}
export { ES6Test };
@GWT3Export allows a resulted JavaScript file to be called from the pure JavaScript environment.
public class ExportTestClass {
@GWT3Export
public static String test(String s) {
return s;
}
@GWT3Export
public Promise<String> promise() {
return Promise.resolve("Hello world!");
}
}
var test = new org.treblereel.j2cl.exports.ExportTestClass();
test.test('INSTANCE METHOD CALL');
test.promise().then(function(result) {
});
@TranslationBundle j2cl-maven-plugin 0.21 brings us support of Closure's .xtb
translation bundles that are a very effective way to translate your application.
.xtb
support is only available for j2cl-maven-plugin 0.21 and above and works only in ADVANCED mode, otherwise default values will be used.To use @TranslationBundle
, you need to do the following steps:
.xtb
auto discovery: <translationsFile>
<auto>true</auto>
</translationsFile>
pom.xml
<defines>
<goog.LOCALE>en</goog.LOCALE>
</defines>
@TranslationBundle
@TranslationBundle
public interface MyBundle {
...
}
The processor will generate the MyBundleImpl.java
implementation in the same package where MyBundle is.
Create a translation property bundle for MyBundle with a locale declared in the following format:
MyBundle_en.properties
or MyBundle_en_US.properties
containing key value pairs like:hello = Hello World!
or hello = Hello {$arg}!
{$arg}
is a placeholder for a string argument.Declare corresponding methods in your MyBundle interface.
@TranslationBundle
public interface MyBundle {
@TranslationKey(defaultValue = "Hello World!")
String hello();
@TranslationKey(defaultValue = "Hello {$arg}!")
String hello(String arg);
}
Default value is used if no translation property value is found for a given locale and key.
If a value contains the {$arg}
placeholder, it will be replaced with the argument provided to the method. Placeholder is surrounded with curly brackets and a corresponding method argument must be named the same;
unescapeHtmlEntities = true
in the @TranslationKey
annotation. @TranslationKey(defaultValue = "<div>HELLO</div>", unescapeHtmlEntities = true)
String hello();
@TranslationKey
annotation. @TranslationKey(key = "greetings", defaultValue = "Hello World!")
String hello();
@GWT3Resource is a lightweight port of GWT2 resources. Its main purpose is to embed various resources into the JavaScript bundle.
Here we declared a bundle of the resources that will be embedded into the JavaScript bundle:
@GWT3Resource
public interface CombinedClientBundle extends ClientBundle {
@Source("logo.png")
ImageResource linuxLogo();
TextResource welcome();
@DataResource.MimeType("audio/mpeg")
@Source("alarmloop.mp3")
DataResource resourceMimeTypeAnnotationAudioOgg();
}
Later, we can use it like this:
CombinedClientBundle resources = CombinedClientBundleImpl.INSTANCE;
DomGlobal.document.body.appendChild(resources.linuxLogo().getImage());
HTMLDivElement container = (HTMLDivElement) DomGlobal.document.createElement("div");
DomGlobal.document.body.appendChild(container);
container.textContent = resources.welcome().getText();
HTMLAudioElement audio = (HTMLAudioElement) DomGlobal.document.createElement("audio");
DomGlobal.document.body.appendChild(audio);
audio.src = resources.resourceMimeTypeAnnotationAudioOgg().asString();
audio.controls = true;
Take a look at tests for more details.