Lqd's Journal

Icon

It's actually pronounced liquid!

Fun Friday Trick: Generics type inference + static imports = don’t wait for Java 7

Welcome to another fun edition of fun friday on a fun monday.

Today, we’ll see a very simple trick, that uses the regular generics type inference with a factory method and static imports, to make generics more readable.

Reading the java 7 language “pre” proposals (from polls and all), and especially the one about adding more type inference on generic objects construction, i remembered a very simple trick i stumbled upon years ago.

What if you named your factory method as a constructor and imported it using the static import feature ? Turns out, i kinda like how it cleans up the code.

Today, we’re using this, and it’s a mouthful:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

I think the java 7 proposal (when it’s released, there’s no draft for it yet, only informal polls, and a starting proposal here) will allow to turn it into
Map<String, List<String>> anagrams = new HashMap<>();

First of, notice the ugly empty <>, it would look cleaner without it, but because of backwards compatibility, it might not be “possible”. We’ll see.

While today’s trick turns it into this, (assuming it was added to HashMap of course)

// in java.util.HashMap for instance
// very common code except for the name
public static <K, V> HashMap<K,V> HashMap()
{
   return new HashMap<K, V>();
}

// in your code, where the magic happens
import static java.util.HashMap.HashMap;

// oooh, pretty
Map<String, List<String>> anagrams = HashMap();

It’s less code. It’s cleaner without the <>. It looks a little like a C++ constructor – from a distance (: – , but it has added perks too, it’s a real factory method, so you can verify arguments and throw exceptions *without* creating objects, and so on.

The way we’re doing it today is relatively easy to write since IDEs are helping, so you could see the java 7 proposal as of limited value, but code is written once, and read multiple times. That’s why i think both the proposal and today’s trick have value.

The IDEs are however a little less successfull at providing you intellisense for static imports it seems. You can solve that by modifying the default class template, or by typing HashMap.HashMap() and refactoring it to a static import (or soon will be able to do so).

You don’t have to wait for java 7 for generics to become easier to use, and even though it would be cleaner if the function was in, say, HashMap, you could still have a helper class à la java.util.Collections or google collections’ Lists and Maps, and so on, if you really wanted to.

So, this is really about a way of naming factory methods and importing them statically, making it rather transparent to use today, without waiting for potential language changes. Both are not perfectly clean, but i don’t think we’ll be getting a real clean way (full type inference on the variable) any time soon, so, in the meantime, pick your poison.

Next up: more composite tricks, and the real reason why they might be useful to you. Yes, there is a plan behind the randomness.

Fun Friday: Simple java composite tricks

Welcome to the first fun friday installment, sometimes on a friday i’ll post one of those, and sometimes on a monday instead of friday, just like today.

Out first topic is a very simple trick using transparent proxies, looking nice when implementing Composites – you might have seen it called event sink depending on what kind of composite you’re making. We’ll use a list of instances and a proxy, both of a specified interface which can be any interface you want.

We’ll call a method on that proxy, and under the hood we’ll use that reified call to call the same method but on all the instances of our list, in a somewhat functional style. We’ll just loop over our elements inside the InvocationHandler used by the proxy and invoke the methods on each of them.

The interesting part here is that we can specify the container we’ll use to hold those elements (eg a specific collection – I’ve built an example with a LinkedList; a custom built collection – using Callables – where you can specify your way of creating the collection; or a special thread-safe collection), our own way of looping (from the end or from the beginning of the list; or depending on the type of listeners inside of it, say the ones which are not direct implementors will be called afterwards) and finally our own way of invoking the callback method on each instance (on the regular main thread; on a specified thread, say, EDT *wink*; or why not say that an exception thrown while invoking the callback method will invalidate the listener and remove it from the list of elements). This alllows versatile event handling code here too, and is only a couple hundred lines for the basic support.

Starting from a very simple interface.

public interface IComposite <T>
{
   // you can return void
   //  if you don't want method chaining
   IComposite<T> add (T t);
   IComposite<T> remove (T t);
   
   T delegate();
}

You can gradually build the different composite implementations we just talked about, and get code that looks like this pretty easily (just showing adding one element to the list and slighty reformated for easier reading here, changed some long methods names, etc – the full source is linked at the end of this post)

public class CompositeTest
{
   
// Totally random listener interface
public static interface IListener
{
   void callback ();
}

//Totally random listener interface too:
//  could have been MouseListener for instance
public static interface ISwingListener
   extends EventListener
{
   void callback (String event);
}

public static void main (String [] args)
{

IComposite<IListener> sink = Composites
 .createLinkedListComposite (IListener.class);
sink.add (new IListener()
{
   @Override
   public void callback ()
   {
      System.out.println ("IListener callback ()");
   }
});
sink.delegate().callback();

IComposite<ISwingListener> sink2 = Composites
 .createEventComposite (ISwingListener.class);
sink2.add (new ISwingListener()
{
   @Override
   public void callback (String event)
   {
      System.out.println ("ISwingListener ('"
        + event + "') - on EDT: "
        + SwingUtilities.isEventDispatchThread ());
   }         
});
sink2.delegate().callback ("Main thread test");

// And now with method chaining     
IComposite<ISwingListener> sink3 = Composites
 .createEDTComposite (ISwingListener.class)
 .add (new ISwingListener()
{
   @Override
   public void callback (String event)
   {
      System.out.println ("ISwingListener ('"
        + event + "') - on EDT: "
        + SwingUtilities.isEventDispatchThread ());
   }         
});

sink3.delegate().callback ("EDT dispatch test");

}
}

It’s probably more instructive to do it yourself than using my code, since it’s very small, but here it is anyway (an Eclipse project). You could also imagine special composites that actually use what the callbacks return, like aggregating results or calculating mean min or max values.

See you next friday, monday, soon enough (:

Scenile: Using JavaFX Project Nile in Java with Scenario

Introduction

I’d like to start today with a little helper library. I call it scenile because it integrates scenario (the scenegraph powering the JavaFX runtime) with project nile (the JavaFX production suite) (plus it’s funny). I’ve talked about it on my twitter stream so some of you might be familiar with it.

Project nile allows creating resources directly from designers’ tools (such as Adobe’s Illustrator and Photoshop) or from SVG files (inkscape also exports  files that can be used by JavaFX, i don’t know if it has been updated for 1.0 though), which can then be used in your javafx script application . This is really good and will help pave the way for better java UX. Nile exports FXZ files, which are FXD files zipped, plus any resource that might be used there, images, fonts, etc. The FXD file format is basically some JavaFX script describing the scene with primitives like rectangles, effects, transforms and so on.

However, i really wanted those features in the java world. Scenile is the result of this wish. It loads fxd/fxz files and creates the appropriate scenario objects, fills the properties, creates the scenegraph and returns it to you. After that, its work is done and scenario takes over to render, animate, etc.

As it stands today, scenile is at version 0.1, i’m still not happy with some of its internals yet, but i wanted to release it early. The whole FXD primitive set is certainly not supported but it can convert the nile samples and many other files i’ve thrown at it. Sometimes i stumbled upon nile bugs, but everything it suceeded in exporting, scenile was able to load correctly in my tests.

For the library users, it’s basically calling one function asking to load a fxz file, so the extensibility – or documentation *clears throat* – doesn’t matter much yet.

Demo and downloads

Domo, arigato, mister, roboto

Domo, arigato, mister, and roboto

I made a little demo to show how you’d use it and. I first created a comp (which you can see more clearly here at flickr) and exported it to fxz with nile. Now, if you load the scene with scenile, give it to a JSGPanel, you’re good to go, and you can then add it to your Swing app for example.

I thought of it as a character selection in some kind of game. It just shows 4 little robots, clicking on one shows its name in the console when launched locally. Clicking the badge at the bottom pauses or resumes the floating animation. As a side note, in the demo, i rasterized the background: because of its complexity (around 13k nodes resulting in a 6M fxd/1.6M fxz) the demo took between 10 and 20s to load, and the animations were far from smooth. Scenario is still being optimized and debugged as we speak, and animated content doesn’t perform all that well all the time (that’s why neither does JavaFX). In the demo, this lite version is much smaller  (around 150+ nodes) and performs well on the couple machines i tested it on.

Here’s the code, and here are the binaries (not packed), both containing 1 or 3 samples. I’m using java 6 in order to get the new gradient classes, if need be i could make a java 5 version.

Click the following image to launch the demo with webstart. (Note: the demo is a little perf intensive because of the animations and gaussian blurs. It depends on the javafx runtime, and works normally on windows – with the direct3d pipeline. I don’t have access to a Mac so i don’t know how it runs there. The animation is pretty sluggish on linux, scenario and decora do not pick up opengl even though the 3 machines or so i tested it on are pretty recent, with up to date drivers. Caching the nodes in images improves the situation but it’s not looking really good either. I’m sorry about that, but i’m not sure there’s anything i could do at this point, except maybe wait for JavaFX 1.1 or the final linux version – if anyone has any idea i’ll be glad to make the appropriate changes)

launch domo arigato demo

Supported scenario versions and license

Ok, that one’s a tough cookie. I first thought about supporting all versions of scenario. At the moment, scenario exists in two states, an open source version (0.6) under the GPL, and a 1.0+ version under the JavaFX license. Both have strengths and weaknesses.

The open source scenario is asleep at the moment (i’m trying not to say it’s dead). There’s more and more forum posts asking about its status, its license, the bug fixes and new features that are in the 1.0, but there’s no answer yet. Eventually, JavaFX will be open sourced, so when that time comes scenario should be as well.

The closed source version is on the opposite very much alive but cannot be distributed (in fact i think neither can the fxd support jar both the javafx.com samples and i use) and you have to depend on the whole fx runtime instead of the small scenario jar.  I believe a jnlp extension containing scenario/decora/javacss would really be useful and actually help people wait for days when the licenses are a little less restrictive. Not a lot of people were able to use it because of the GPL anyway.

I’d still like for them to be able to use Scenile though. Right now, a couple features are 1.0 specific, if anyone using scenario 0.6 needs compatibility, i’ll do that by the next version. That’s why the code is licensed under the modified BSD license. If you use scenario 0.6 directly and can comply to its GPL license, the BSD is compatible with the GPLv2 (even though scenile will be usable for you only at v0.2 or so, not right now). There’s no problem either if you use scenario 1.0+ by depending on the javafx runtime, or if somehow we get a jnlp extension for scenario, since the BSD is very permissive and thus also compatible with the JavaFX license.

Final words

This is really a simplistic piece of technology, however the possibilities are almost limitless because it streamlines the graphic resources integration. By helping integrating those really easily, you can do whatever you want in the design phase. I intend to post other demos showcasing those possibilities some more: it’s not just useful for character selections in games, but also in traditional ui design, or as i hope we’ll see soon, skinning components and look-and-feels, and more.

Hopefully i’ll see you there.