JVx and Java 8, Events and Lambdas

Post to Twitter

With version 8, Java has received support for lambda expressions and of course also JVx and its users directly profit from this new feature.

In case you do not know what a lambda expression is, it is basically the possibility to inline functions, sometimes also called "anonymous functions" and should not be confused with "anonymous classes", which Java has supported for quite some time now. Let's look at a simple example of anonymous classes:

new Thread(new Runnable()
{
    public void run()
    {
        // your code
    }
}).start();

This launches a thread that does something. The Runnable in our example is the anonymous class. Now with the new lambda support we don't need to write the interface implementation, but can directly tell it to run a function:

new Thread(() -> { /* your code */ }).start();

The empty parentheses and the arrow indicate a new anonymous function. The parentheses contain the list of parameters of the function that is going to be invoked, in our case it is empty because Runnable.run() does not have any parameters. So the anatomy of a lambda looks like this:

new Thread((optional explicit cast to target interface)(parameters) ->
{
    function body
});

Internally this is still compiled into an anonymous class, but the code becomes a lot smoother and easier to read.

Additionally it is now possible to reference functions directly, like this:

// instance
new Thread(this::worker).start();
// static
new Thread(YourWorkClass::worker).start();

Especially the last possibility is very exciting, as our event system has a very similar mechanism but until recently did not have compile-time safety and checks.

The new lambda feature is backwards compatible and can easily be used in JVx. Here is a simple test window that shows the new lambda expressions in combination with JVx events:

import javax.rad.genui.component.UIButton;
import javax.rad.genui.container.UIFrame;
import javax.rad.genui.layout.UIBorderLayout;
import javax.rad.ui.event.UIActionEvent;

public class LambdaShowcaseFrame extends UIFrame
{
    public LambdaShowcaseFrame()  
    {
        initializeUI();
    }

    public void doJVxAction(UIActionEvent pActionEvent)
    {
        System.out.println("JVx");
    }

    public void doLambda2(UIActionEvent pActionEvent)
    {
        System.out.println("Lambda 2");
    }

    private void initializeUI()
    {
        //before Java 8
        UIButton buttonJVx = new UIButton("JVx Style");
        buttonJVx.eventAction().addListener(this, "doJVxAction");

        // with Java 8

        UIButton buttonLambda1 = new UIButton("Lambda 1");
        buttonLambda1.eventAction().
                addListener(pActionEvent -> System.out.println("Lambda 1"));

        UIButton buttonLambda2 = new UIButton("Lambda 2");
        buttonLambda2.eventAction().addListener(this::doLambda2);

        setLayout(new UIBorderLayout());
        add(buttonJVx, UIBorderLayout.NORTH);
        add(buttonLambda1, UIBorderLayout.WEST);
        add(buttonLambda2, UIBorderLayout.EAST);
    }
}