jaroslav@550: jaroslav@541: jaroslav@541: jaroslav@541: jaroslav@541: HTML for Java APIs jaroslav@541: jaroslav@541: jtulach@982: jaroslav@541: jaroslav@541: jaroslav@541:

jtulach@940: Use Java to write application logic; Use HTML5 to render the UI; jaroslav@630: {@link net.java.html.json.Model Animate an HTML page from Java} jtulach@668: (see Duke being rotated by CSS); jaroslav@543: Use {@link net.java.html.json.OnReceive REST} or jaroslav@543: WebSockets; jaroslav@543: interact with JavaScript; jaroslav@543: Get the best of both worlds! jtulach@940: jtulach@940: The goal of these APIs is to use full featured Java runtime jtulach@1033: (like real HotSpot VM), jtulach@940: but still rely on a very lightweight rendering technology jtulach@940: (so it can potentially fit jtulach@1033: Bck2Brwsr and definitely jtulach@940: to various types of phones). What can be more lightweight jtulach@940: (from a browser perspective) than jtulach@1033: HTML!? jtulach@940: By default we use {@link net.java.html.boot.fx JavaFX's WebView} jtulach@1033: component to display the HTML. jtulach@940: We eliminate the need to manipulate the DOM directly, jtulach@940: there is a special {@link net.java.html.json Java to Knockout.js binding}. jtulach@1033: As a result the HTML uses Knockout.js syntax, jaroslav@541: yet the application code can be written in Java. jaroslav@541:

jtulach@940: jtulach@1006:

Improvements in version 1.3

jtulach@1006: jtulach@1023: {@link net.java.html.json.Model Model classes} can have jtulach@1023: {@link net.java.html.json.Model#instance() per-instance private data}. jtulach@1017: {@link net.java.html.json.Model Model classes} can generate jtulach@1017: builder-like construction methods if builder jtulach@1017: {@link net.java.html.json.Model#builder() prefix} is specified. jtulach@1056: {@link net.java.html.json.Property#mutable} can be false jtulach@1056: to define a non-mutable (almost constant) property. That jtulach@1056: in case of Knockout bindings means: the property is jtulach@1056: represented by a plain value rather than an observable in the JavaScript jtulach@1056: object. The JavaFX presenter can be executed in headless mode - jtulach@1006: just specify -Dfxpresenter.headless=true when launching jtulach@1006: its virtual machine and no window will be shown. This is particularly jtulach@1006: useful for testing. Configure your surefire or failsafe jtulach@1006: plugins like:
jtulach@1006: <plugin>
jtulach@1006:   <groupId>org.apache.maven.plugins</groupId>
jtulach@1006:   <artifactId>maven-surefire-plugin</artifactId>
jtulach@1006:   <version>2.13</version>
jtulach@1006:   <configuration>
jtulach@1006:       <systemPropertyVariables>
jtulach@1006:           <fxpresenter.headless>true</fxpresenter.headless>
jtulach@1006:       </systemPropertyVariables>
jtulach@1006:   </configuration>
jtulach@1006: </plugin>
jtulach@1006: 
jtulach@1033: OSGi headers are now jtulach@1021: enterprise OSGi ready. jtulach@1033: Switched to minified version 3.4.0 jtulach@1033: of knockout.js. jtulach@1039: Better support for jtulach@1039: recursive @Model definitions. jtulach@991:

What's Been Improved in Version 1.2.3?

jtulach@940: jtulach@940: One can control {@link net.java.html.json.OnReceive#headers() HTTP request headers} jtulach@940: when connecting to server using the {@link net.java.html.json.OnReceive} jtulach@951: annotation. It is possible to have jtulach@951: {@link net.java.html.json.ComputedProperty#write() writable computed properties}. maxnitribitt@964: There is an easy way to enable Firebug in maxnitribitt@964: the JavaFX based Web View - maxnitribitt@964: just run with -Dfirebug.lite=true as maxnitribitt@964: this video maxnitribitt@964: demonstrates. jtulach@943: Bugfix of issues 250503, jtulach@943: 252987. jtulach@940: jtulach@886:

What's New in Version 1.1?

jtulach@940: jtulach@886:

jtulach@886: The content of a {@link net.java.html.BrwsrCtx context} jtulach@886: can be selected by registering implementations under specific jtulach@940: {@link org.netbeans.html.context.spi.Contexts.Id technology identifiers} jtulach@940: and requesting them during jtulach@940: {@link org.netbeans.html.context.spi.Contexts#newBuilder(java.lang.Object...) construction} jtulach@886: of the context. org.netbeans.html:ko4j module's implementation jtulach@886: offers ko4j, xhr and websocket identifiers jtulach@940: for its registered services jtulach@886: (e.g. {@link org.netbeans.html.json.spi.Technology}, jtulach@886: {@link org.netbeans.html.json.spi.Transfer} and jtulach@886: {@link org.netbeans.html.json.spi.WSTransfer}). jtulach@886: org.netbeans.html:ko-ws-tyrus jtulach@940: module registers its jtulach@940: {@link org.netbeans.html.json.spi.Transfer Java based JSON} and jtulach@886: {@link org.netbeans.html.json.spi.WSTransfer WebSocket} implementations jtulach@886: under the name tyrus. jtulach@920:

jtulach@920:

jtulach@920: A particular DOM subtree jtulach@920: that a knockout.js model gets jtulach@940: applied to can be selected by using jtulach@921: {@link net.java.html.json.Models#applyBindings(java.lang.Object,java.lang.String) jtulach@920: Models.applyBindings(m, id)} with an id of an HTML element. jtulach@940: There is new {@link net.java.html.json.Model#targetId()} attribute jtulach@940: which controls behavior of the generated applyBindings method. jtulach@920: If specified and non-empty, then the generated method jtulach@920: will call {@link net.java.html.json.Models#applyBindings(java.lang.Object,java.lang.String)} jtulach@920: with this and the provided {@link net.java.html.json.Model#targetId() target id}. jtulach@920: If specified, but left empty, then the generated method jtulach@920: calls {@link net.java.html.json.Models#applyBindings(java.lang.Object)}. jtulach@920: If unspecified, the method will not be generated at all jtulach@920: (a change with respect to older versions). However one can jtulach@920: still use {@link net.java.html.json.Models#applyBindings(java.lang.Object)} jtulach@920: or {@link net.java.html.json.Models#applyBindings(java.lang.Object,java.lang.String)} jtulach@920: to perform the association of any model with the page element. jtulach@982:

jtulach@920:

jtulach@870: Memory model when using Knockout bindings has been improved jtulach@870: (required additions of two new methods: jtulach@870: {@link org.netbeans.html.json.spi.PropertyBinding#weak()} and jtulach@870: {@link org.netbeans.html.json.spi.FunctionBinding#weak()}) and jtulach@870: now the Java {@link net.java.html.json.Model models} can garbage collect, jtulach@940: when no longer used. Library writers that use jtulach@940: {@link net.java.html.js.JavaScriptBody} annotation can also jtulach@903: control garbage collection behavior of method arguments by jtulach@903: setting {@link net.java.html.js.JavaScriptBody#keepAlive() keepAlive=false} jtulach@903: attribute. jtulach@886:

jtulach@940: jtulach@832:

What's New in Version 1.0?

jtulach@940: jtulach@832:

jtulach@832: {@link net.java.html.json.Property#array() Array properties} are now jtulach@832: mutable from the knockout.js jtulach@838: point of view (required {@link org.netbeans.html.json.spi.Proto.Type#replaceValue one SPI change}). jtulach@834: The page lookup mechanism can use {@link net.java.html.boot.BrowserBuilder#locale(java.util.Locale) locale} jtulach@834: to load localized a page with appropriate suffix. jtulach@841: All SPI were moved under the NetBeans namespace - e.g. jtulach@841: {@link org.netbeans.html.boot.spi}, jtulach@841: {@link org.netbeans.html.context.spi}, jtulach@841: {@link org.netbeans.html.json.spi}, jtulach@841: {@link org.netbeans.html.sound.spi}, and also jtulach@852: {@link org.netbeans.html.json.tck}. Methods annotated jtulach@852: with {@link net.java.html.js.JavaScriptBody} annotation and jtulach@852: without fallback Java code now throw {@link java.lang.IllegalStateException} jtulach@852: with a message suggesting to switch to proper jtulach@852: {@link net.java.html.BrwsrCtx#execute browser context} to jtulach@852: prevent endless debugging when one forgets to do so. jtulach@832:

jtulach@940: jtulach@887:

jtulach@940: What's new in older versions? Click the jtulach@940: link jtulach@940: to view even more jtulach@887: historic changes below: jtulach@887:

jtulach@940: jtulach@887: jtulach@887:
jtulach@887: jtulach@940: jtulach@771:

What's New in Version 0.9?

jtulach@940: jtulach@771:

jtulach@771: System can run in {@link net.java.html.boot.BrowserBuilder#classloader(java.lang.ClassLoader) Felix OSGi container} (originally only Equinox). jtulach@788: {@link net.java.html.json.ComputedProperty Derived properties} jtulach@788: now deeply check changes in other {@link net.java.html.json.Model model jtulach@788: classes} they depend on and recompute their values accordingly. jtulach@810: Knockout.js library has been updated jtulach@810: to version 3.2.0. jtulach@771:

jtulach@940: jtulach@771:

What's New in 0.8.x Versions?

jtulach@940: jaroslav@720:

jaroslav@720: Setters or array properties on classes generated by {@link net.java.html.json.Model} jtulach@838: annotation can be accessed from any thread. {@link org.netbeans.html.sound.spi.AudioEnvironment} jtulach@747: can be registered into {@link net.java.html.BrwsrCtx}. There is jtulach@747: a {@link net.java.html.json.Models#parse(net.java.html.BrwsrCtx, java.lang.Class, java.io.InputStream, java.util.Collection) method} jtulach@940: to parse a JSON array and convert it into jtulach@747: {@link net.java.html.json.Model model classes}. jtulach@940: Improved behavior of enum values in jtulach@758: {@link net.java.html.json.Model knockout bindings}. jaroslav@720:

jtulach@940: jtulach@702:

jtulach@940: Few bugfixes for better portability. jtulach@702: New API for {@link net.java.html.boot.script.Scripts headless execution} jtulach@703: on top of Nashorn - does not run knockout for Java jtulach@940: fully yet jtulach@702: (reported as JDK-8046013), jtulach@940: however even in current state it is quite jtulach@703: {@link net.java.html.boot.script.Scripts useful for testing} jtulach@940: of jtulach@703: {@link net.java.html.js Java/JavaScript interactions}. jtulach@702:

jtulach@940: jtulach@654:

jtulach@656: {@link net.java.html.boot.fx.FXBrowsers} has been extended jtulach@656: with new helper methods to make it easier to use HTML+Java jtulach@656: API in existing JavaFX applications. jtulach@656: The annotation processor is made jtulach@654: more robust with respect to errors in callback syntax of jtulach@654: {@link net.java.html.js.JavaScriptBody} body parameter. jtulach@654: Javadoc of {@link net.java.html.BrwsrCtx#execute} method jtulach@654: has been improved based on a failure of its usability study. jtulach@654: There can be additional parameters to methods annotated by jtulach@654: {@link net.java.html.json.OnReceive} that allows one to jtulach@654: pass state when a JSON call is made and use it when it finishes. jtulach@654: The mechanism of discovery of sibling HTML page has been jtulach@654: extended to work on systems that don't support jtulach@654: {@link java.lang.Class#getProtectionDomain}. jtulach@654:

jtulach@940: jaroslav@617:

jtulach@650: The first argument of method annotated by jtulach@650: {@link net.java.html.json.OnReceive} annotation has to jtulach@650: be the associated {@link net.java.html.json.Model model class}. jtulach@650:

jtulach@940: jtulach@650:

jtulach@647: {@link net.java.html.json.OnReceive} annotation now accepts jtulach@647: {@link java.util.List} of data values as second argument jtulach@647: (previously required an array). jtulach@647:

jtulach@940: jtulach@940: jtulach@887:

What's New in 0.7.x Versions?

jtulach@940: jtulach@647:

jaroslav@617: {@link net.java.html.js.JavaScriptBody} annotation has new attribute jaroslav@617: {@link net.java.html.js.JavaScriptBody#wait4js()} which allows jaroslav@617: asynchronous execution. Libraries using jaroslav@617: {@link net.java.html.js.JavaScriptBody} are urged to use this jaroslav@617: new attribute as much as possible, as it can speed up execution jaroslav@617: in certain environments. jaroslav@617:

jtulach@940: jaroslav@617:

jaroslav@617: Use {@link net.java.html.BrwsrCtx#execute(java.lang.Runnable)} in jaroslav@617: multi-threaded environment to execute your code on the browser thread. jtulach@940: See example jaroslav@617: {@link net.java.html.BrwsrCtx#execute(java.lang.Runnable) using Java timer}. jaroslav@617:

jtulach@887:
jtulach@940: jaroslav@541:

Interesting Entry Points

jtulach@940: jaroslav@541:

Learn how to {@link net.java.html.json.Model animate an HTML page from Java} jaroslav@541: without referencing single HTML element from the Java code. jaroslav@541:

jaroslav@541:

Use {@link net.java.html.json.OnReceive JSON} to communicate jaroslav@541: with REST based server API. jaroslav@541:

jaroslav@541:

Use WebSockets jaroslav@541: and JSON. jaroslav@541:

jaroslav@541:

Call JavaScript methods from Java and vice versa, via jaroslav@541: JavaScriptBody. jaroslav@541:

jaroslav@541: jaroslav@541:

Getting Started

jaroslav@541: jtulach@940: There are many ways jtulach@940: to start developing jtulach@940: Html for Java application. jaroslav@541: However to be sure one chooses the most recent setup, it is recommended jtulach@940: to switch to good old command line and use a jaroslav@541: Maven archetype jtulach@940: associated with every version of this project. Make sure at least jaroslav@610: JDK7 is your installed Java and type: jtulach@940:
jaroslav@541: $ mvn archetype:generate \
jaroslav@541:  -DarchetypeGroupId=org.apidesign.html \
jaroslav@541:  -DarchetypeArtifactId=knockout4j-archetype \
jtulach@759:  -DarchetypeVersion=0.8 # or newer version, if available
jaroslav@541:         
jtulach@940: Answer few questions (for example choose myfirstbrwsrpage as artifactId) jaroslav@611: and then you can: jaroslav@541:
jaroslav@541: $ cd myfirstbrwsrpage
jaroslav@541: $ mvn process-classes exec:java
jaroslav@541:         
jtulach@940: In a few seconds (or minutes if jaroslav@541: Maven jtulach@940: decides to download the whole Internet of dependencies) you should jtulach@940: see a sample Hello World application rendered in a jaroslav@611: JavaFX jaroslav@611: web view component (that of course requires your JDK to come jtulach@940: with JavaFX; jtulach@940: JDK7 jtulach@940: and JDK8 from Oracle contain everything that is needed). jtulach@940: The generated application is built around one jaroslav@611: Java source (uses the {@link net.java.html.json.Model} annotation to jaroslav@611: auto-generate another Data.java class during compilation) jaroslav@611: and one HTML file (uses the Knockout jtulach@940: syntax to data-bind the HTML elements to the jaroslav@611: generated Data model): jaroslav@541:
jaroslav@541: $ ls src/main/java/**/DataModel.java
jaroslav@541: $ ls src/main/webapp/pages/index.html
jaroslav@541:         
jtulach@940: That is all you need to get started. Play with the sources, jaroslav@611: modify them and enjoy jaroslav@541: Html for Java! jtulach@940: jaroslav@614:

IDE Support

jtulach@940: jaroslav@614:

jaroslav@614: This API is part of NetBeans.org project and as such jaroslav@614: it works naturally with the NetBeans IDE. jaroslav@614: On the other hand, the API is using nothing NetBeans specific, jaroslav@614: it builds on standard Java6 APIs and as such it shall work fine jaroslav@614: in any IDE. jaroslav@614:

jtulach@940: jaroslav@614:

jtulach@940: A lot of work is done by jaroslav@614: jaroslav@614: annotation processors jaroslav@614: that generate various boiler plate code during compilation. This jaroslav@614: is a standard part of Java since JDK6, but for example Eclipse jaroslav@614: is known not to deal with processors well and developers using jaroslav@614: it need to be careful. IntelliJ users hasn't reported any issues jtulach@940: and of course, NetBeans IDE support for jaroslav@614: processors jaroslav@614: is outstanding. jaroslav@614:

jtulach@940: jaroslav@614:

jaroslav@614: When using {@link net.java.html.js.JavaScriptBody} annotation, it is jaroslav@614: useful to do a bit of post processing of classes. There is a jtulach@940: Maven jaroslav@614: plugin for that. jtulach@940: NetBeans IDE will invoke it when doing a build. Other IDEs may jtulach@940: need some hint to do so. jaroslav@614: Anyway: If one does not see all (generated) sources or is getting jtulach@940: {@link java.lang.LinkageError}s when executing the application, jaroslav@614: switch to command line and do clean build jaroslav@614: from there: jaroslav@614:

jaroslav@614:
$ mvn clean install
jaroslav@614:

jaroslav@614: If that succeeds, your IDE of choice will hopefully jtulach@940: pick the generated sources up and present the result of the build jtulach@940: properly. If not, jtulach@940: download NetBeans, jtulach@940: you will be pleasantly jtulach@940: surprised - for example with our excellent jtulach@940: Java/JavaScript jaroslav@614: debugging support. jaroslav@614:

jtulach@940: jaroslav@615: jaroslav@615:

Deploy Your Application

jaroslav@615:
jtulach@940: jaroslav@615:

jaroslav@615: It is not goal of this documentation to list all possible ways jtulach@940: to package and deploy applications which use this API. However it is jaroslav@615: important for new comers to see the benefits of using the jaroslav@615: HTML for Java API and as such jtulach@940: let's list at least few bundling options, known to work at the time of writing jaroslav@615: this documentation. jaroslav@615:

jtulach@940: jaroslav@615:

jaroslav@615: First of all, this is a client technology. You write client applications jaroslav@615: with it which may, but need not connect to a server. You don't need jtulach@940: Tomcat or WebLogic to deploy jaroslav@615: HTML for Java applications. jaroslav@615:

jtulach@940: jaroslav@615:

jaroslav@615: jaroslav@615: The sample project generated by jaroslav@615: org.apidesign.html knockout4j-archetype is configured jaroslav@615: to use JavaFX jtulach@940: as the rendering technology. This setup is primarily suitable for jaroslav@615: development - it needs no special packaging, starts quickly and jtulach@940: allows you to use classical HotSpot VM debuggers. A final jaroslav@615: artifact from the build is also a ZIP file which you can use jaroslav@615: and distribute to your users. Good for desktop applications. jaroslav@615:

jtulach@940: jaroslav@615:

jaroslav@615: jaroslav@615: jaroslav@615: All the HTML for Java libraries jtulach@638: are packaged as OSGi jaroslav@615: bundles and as such they can easily be run in NetBeans as well as jtulach@940: in Eclipse. As a result one can use jaroslav@615: OSGi jtulach@940: and have a common module system for both platforms. In addition to that jtulach@638: one can render using jaroslav@615: HTML and have a common UI in both platforms. In such case jaroslav@615: your application would be packaged as a set of jaroslav@615: OSGi bundles. jtulach@940: Read jaroslav@615: more... jaroslav@615:

jtulach@940: jaroslav@615:

jaroslav@615: jaroslav@615: jaroslav@615: jaroslav@615: jtulach@940: jaroslav@615: There is more and more attempts to execute Java bytecode jtulach@638: in a browser, without any special Java plugin installed. jaroslav@615: The HTML for Java is jaroslav@615: carefully designed to produce lightweight, well performing jaroslav@615: applications even on such restricted environments. It uses jaroslav@615: no reflection calls and that allows to statically pre-compile jaroslav@615: the applications into JavaScript. One of such environments jtulach@940: is called Bck2Brwsr, jtulach@638: another TeaVM. Both support the jtulach@940: {@link net.java.html.js.JavaScriptBody} annotation. Read jaroslav@615: more or play jtulach@940: a minesweeper game packaged for your browser jaroslav@616: (of course jaroslav@616: written in Java): jaroslav@615:

jtulach@940: jaroslav@616: jaroslav@616: jaroslav@616:
jaroslav@616: jaroslav@616: jaroslav@616: jaroslav@616: jaroslav@616: jaroslav@615:

jtulach@654: jaroslav@615: jtulach@940: jtulach@940: Now when we have seen that the jtulach@940: HTML for Java applications jaroslav@615: can run on any modern browser, we can ask whether they can also jtulach@940: fit into a phone!? Yes, they can and especially to phones jaroslav@615: that can execute Java code already! Just by changing your jaroslav@615: packaging you can create an APK file and deploy it to your jtulach@940: Android phone. jtulach@624: Read more... jtulach@654: In case you'd like your application to reach out to second biggest jtulach@940: group of smartphone users, don't despair: It jtulach@654: seems the set of devices that can execute jtulach@940: HTML for Java applications jtulach@940: has been extended to iPads and iPhones. Get the jtulach@654: details here jtulach@654: and deploy everywhere! jaroslav@615:

jaroslav@615:

jtulach@940: Convinced it makes sense to use jaroslav@615: HTML for Java jtulach@940: APIs for writing applications that are jaroslav@615: written once, displayed anywhere? Or do you have an jaroslav@615: environment which is not supported? In such case you can bring jaroslav@615: HTML for Java jaroslav@615: to your environment yourself. Just implement your own jtulach@838: {@link org.netbeans.html.boot.spi.Fn.Presenter}! jaroslav@615:

jtulach@940: jaroslav@607:

Other Resources

jtulach@940: jaroslav@607: Duke and HTML5. Together at last! jtulach@940: jaroslav@607: The javadoc for latest and previous versions is also available jaroslav@607: online: jaroslav@607: jaroslav@541: jaroslav@541: