Clicky

Announcing Flash4j 3.1



We're very excited to announce the General Availability of Flash4j 3.1!

Flash4j is our Java-based application toolkit that leverages the GWT Toolkit to help developers build high performance Rich Internet Applications for the Desktop.

The goal of Flash4j is to leverage Flash and HTML5 in an innovative way, helping you build stunning web applications. At Emitrom, we believe in combining Flash and HTML5 to create amazing products instead of having a Flash vs HTML5 approach. Lets see what is new in this release.

Developing in the Open

Like all our products, the codebase for Flash4j is also hosted on GitHub! This gives everyone the possibility to follow the framework's evolution and even contribute to it.

Client Side File IO (PDF,Excel) for any Web Application

The ability to read and write files on the client is a powerful feature for any web application. Take a reporting tool, for example. Being able to generate reports on the client without hitting the server is a big performance boost (your sever will thank you).

Flash4j has always had client-side file generation (specially PDF and Excel), but this feature required the use of the Flex framework. With release 3.1 we are bringing this capability to any web application, as shown below.

package com.emitrom.flash4j.demo.client; import com.emitrom.flash4j.clientio.client.ClientIO; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; public class ClientIOExample implements EntryPoint { @Override public void onModuleLoad() { // initialize the ClientIO module ClientIO.init(); Button b = new Button("Click Me"); b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { // create a PDF File PDF pdf = new PDF(); pdf.addPage(); pdf.setTextStyle(new RGBColor(0x000000)); pdf.setFont(new CoreFont(), 10); pdf.addText("Hello World"); ClientIO.saveFile(pdf.save(), "file.pdf"); } }); RootPanel.get().add(b); } }

The code above creates a PDF file on the client in a regular GWT application!
ClientIO can also be used to read files.
package com.emitrom.flash4j.demoo.client; import com.emitrom.flash4j.clientio.client.ClientIO; import com.emitrom.flash4j.core.client.events.Event; import com.emitrom.flash4j.core.client.events.handlers.EventHandler; import com.emitrom.flash4j.core.client.net.FileFilter; import com.emitrom.flash4j.core.client.net.FileReference; import com.emitrom.flash4j.core.client.utils.ByteArray; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.RootPanel; public class ClientIOExample implements EntryPoint { @Override public void onModuleLoad() { ClientIO.init(); Button b = new Button("Click Me"); b.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { final FileReference fileReference = ClientIO.browse(new FileFilter("My File", ".txt")); fileReference.addEventHandler(Event.SELECT, new EventHandler() { @Override public void onEvent(Event event) { fileReference.load(); fileReference.addEventHandler(Event.COMPLETE, new EventHandler() { @Override public void onEvent(Event event) { ByteArray data = fileReference.getData(); String content = data.readUTFBytes(data.getBytesAvailable()); Window.alert(content); } }); } }); } }); RootPanel.get().add(b); } }
In the previous sample we read a text file from the user's computer and show an alert with its contents. Again, no server roundtrip, thus saving bandwidth and server processing power! This feature can be used in combination with any web library. Regular GWT, ExtGWT, SmartGWT, Ext4j... You name it. The ClientIO API can even be exported to native JavaScript using the GWT Exporter project. How powerful is that?

Core Flash support

In our previous releases the core Flash API was only exposed through our Flex module, which meant one had to load the entire Flex framework even if only core Flash functionalities were needed. In 3.1 we are introducing the Flash Core module. This module gives access to the Flash platform without any dependency to Flex, which results in a much faster load time. package com.emitrom.flash4j.app.client; import com.emitrom.flash4j.core.client.display.Graphics; import com.emitrom.flash4j.core.client.display.Shape; import com.emitrom.flash4j.flash.client.FlashEntryPoint; import com.emitrom.flash4j.flash.client.FlashRootPanel; public class FlashApp extends FlashEntryPoint { @Override public void onLoad() { Shape s = new Shape(); Graphics g = s.getGraphics(); //draw a green circle g.beginFill(0x00FF00); g.moveTo(250, 0); g.curveTo(300, 0, 300, 50); g.curveTo(300, 100, 250, 100); g.curveTo(200, 100, 200, 50); g.curveTo(200, 0, 250, 0); g.endFill(); s.setXY(300, 300); FlashRootPanel.get().addChild(s); } }
Here we used core Flash APIs to draw a circle on te screen. All in Java!

Support for Apache Flex 4.9

This release of Flash4j adds support for the latest stable release of Apache Flex (4.9).

UI Binder Support for Flex !

When we created the Java API for Flex one of the most requested features was MXML support. In the ActionScript world MXML allows developers the express the Flex UI in a declarative way, which is less verbose and more intuitive, especially for non programmers.

We heard you and added UI Binders support for Flex!

As in MXML, UI Binders enables a declarative way to define the User Interface in a GWT project. Flash4j introduces a custom parser to enable the GWT compiler to generate a Flex UI from the UI Binders XML declaration. <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:mx="urn:import:com.emitrom.flash4j.flex.client.ui.mx" > <mx:Panel ui:field="panel" title="Flash4j 3.1 and UI Binder" verticalCenter="0" horizontalCenter="0" percentWidth="50" percentHeight="50" status="Emitrom" > <mx:Label fontSize="20" centered="true" text="Hello World" /> </mx:Panel> </ui:UiBinder> As you can see, the code is simpler and less verbose than if it was written in pure Java. Below is the result.

Google Maps Support for Flex

In September 2011, Google announced the deprecation of the Google Maps API for Flash in favor of a JavaScript API. This news left Flex developers wondering how they would integrate Google Maps in their applications.

Wonder no longer! Flash4j 3.1 adds a seamless integration with the Google Maps JavaScript API.
New in the framework is a new MapWidget that can be used to display a Google Map into any Flash4j based Flex application. The Map can then be accessed and modified using the Maps API from Emitrom's Pilot library. public class Flex4jExplorer extends FlexEntryPoint { @Override public void onLoad() { FLEX.getRootPanel().setBackgroundColor(Color.BURLYWOOD); Panel container = new Panel("Flash4j 3.1 - Google Maps Support"); container.setStatus("Emitrom"); container.setPercentSize(80, 70); container.setCentered(true); MapWidget mapWidget = new MapWidget(); mapWidget.asUIComponent().strech(); mapWidget.addMapLoadHandler(new MapLoadHandler() { @Override public void onMapLoad() { GMap googleMap = new GMap(mapWidget.getMap()); googleMap.setMapType(MapTypeId.HYBRID); } }); container.addElement(mapWidget); FLEX.getRootPanel().addElement(container); } }
Thanks to Flash4j, Google Maps has never been so easy to integrate in a Flex application.

Java Bean support for List Based Component

Data driven components like List or DataGrid can only work with BaseModel instances. BaseModel wraps a lightweight JavaScripObject allowing easy data transmission between GWT and the Flash player. Although this approach works, it forces you to create a class that extends BaseModel and some kind of Data Transfer Object to turn your Java Bean into a BaseModel.

What is missing is a way to use your Java Beans as is, without having to extend the Flash4j base classes.

With the 3.1 release of Flash4j, it is now possible to use any Java Beans for data-bound components such as List and DataGrid. This allows you to send your Java Beans from the server to the client using GWT RPC.

Lets say you have the following Java Bean

public class SuperHeroe { private String realName; private String nickName; public SuperHeroe() { } public SuperHeroe(String realName, String nickName) { super(); this.realName = realName; this.nickName = nickName; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } public static List<SuperHeroe> getList() { List<SuperHeroe> list = new ArrayList<SuperHeroe>(); list.add(new SuperHeroe("Logan", "Wolverine")); list.add(new SuperHeroe("Scott Summers", "Cyclops")); list.add(new SuperHeroe("Professor Charles Francis Xavier", "Professor X")); list.add(new SuperHeroe("Jean Grey-Summers", "Marvel Girl")); list.add(new SuperHeroe("Kurt Wagner", "Nightcrawler")); list.add(new SuperHeroe("Robert Louis Drake", "Iceman")); list.add(new SuperHeroe("Ororo Lqaldi T' Challa-Wakandas", "Storm")); list.add(new SuperHeroe("Henry Phillip McKoy", "Beast")); return list; } }

As you can see this is a plain old Java object not extending any of Flash4j classes. The 'getList' method could be a service method that retrieves the list of superheroes from a database.

With Flash4j 3.1 you can use this class directly in a DataGrid without any modification.

public class Flex4jExplorer extends FlexEntryPoint { @Override public void onLoad() { FLEX.getRootPanel().setBackgroundColor(Color.BISQUE); Panel container = new Panel("Java Beans support for Grid"); container.setStatus("Emitrom"); container.setPercentSize(80, 70); container.setCentered(true); //Use the model localtor to contrust BaseModel out of the List of superheroes List<BeanModel> superHeroes = ModelLocator.locate(SuperHeroe.class).createModel(SuperHeroe.getList()); DataGrid dataGrid = new DataGrid(superHeroes); dataGrid.setColumns(new DataGridColumn("RealName", "realName"), new DataGridColumn("NickName", "nickName")); dataGrid.setStreched(true); FLEX.getRootPanel().addElement(container); } }

On line 12 you see how we use the ModelLocator class to turn the List of SuperHeroes into a list of BeanModel. The conversion from POJO to BeanModel is done automatically for you. Below is the result.


Flash4j also gives you the ability to retrieve the original bean from the BaseModel

dataGrid.addEventHandler(ListEvent.ITEM_CLICK, new EventHandler() { @Override public void onEvent(Event event) { ListEvent e = ListEvent.cast(event); BeanModel model = (BeanModel) dataGrid.getData().get(e.getRowIndex()); SuperHeroe sh = model.getBean(); Alert.show(sh.getRealName() + " a.k.a " + sh.getNickName(), "You selected !!"); } });

Flash4j Roadmap

As you can probably imagine, we have been hard at work to make Flash4j the best tool for writing desktop-based Rich Internet Applications. Still, we are planning on adding support for more amazing features in the future, so stay tuned to this space or in our Google+ community.

Flash4j brings a lot of exciting new capabilities and we hope you enjoy using it.

Happy coding!

The Emitrom Team