Monday, May 13, 2013

Monday Fun Component...???

Ups...what's that...a monday fun component...???
Why not...today I was traveling from Münster to Basel by train because I have to give a JavaFX training tomorrow and Wednesday. During the train ride there was some time and didn't had internet on the train so that I had to do something locally on my machine. 
Some time ago I found the following button somewhere on the web and I thought it might be useful as a control for my BeagleBoard.




Long story short, I simply created the control and instead of styling a ToggleButton or CheckBox (which would be the right approach here) I created a new control. I did this because I can...no, it was because I was much faster by drawing that stuff and convert it to a control as trying to figure out how to tweak the caspian.css in the way that a ToggleButton or CheckBox would look like the button above.
I created the control as a JavaFX 2.x control instead of a JavaFX 8 control because I would like to use it as a touchable button on my BeagleBoard which is running on JDK7 with JavaFX 2.x at the moment.
Here is the result that I was able to create...





This is really more a quick hack than a ready to go control but...I don't care...it works on my BeagleBoard and that was the target...so I'm fine with the result and if you would like to use it...here is the code...

Source as zip

The control has the following properties,

  • touchable
  • selected
  • text
  • ledColor

The touchable property will simply add touchEvent listeners instead of mouseEvent listeners to the control. So if you would like to use it on a touchable device you should switch touchable on.
The control will fire SelectEvents and will give you some convenience methods like onSelect and onDeselect where you could attach your EventHandlers to.

Like I said...a quick hack and if you have the time...feel free to attach the css to a CheckBox etc. and tweak an existing control which would be a better approach.

That's it for today...so keep coding... 


Monday, May 6, 2013

Java(FX) BBQ

Hi there,
Today's post is not about JavaFX but more about community. I decided to organize a little Java(FX) BBQ where I'll try to give people the chance to meet and have some fun. The event will happen at my house in Münster (Germany) and will be open for everybody who's interested in meeting some people that are interested in Java and especially in JavaFX :)
It will happen on a friday afternoon and the date is not fixed yet, so if you would like to attend, feel free to add yourself to the following Doodle:

JavaFX BBQ Doodle

I saw that some people from the JFXtras project signed up already so it might also be a good chance to meet and greet these guys behind the JFXtras project. If you would like to stay here over night you will find a guesthouse here

Gästehaus Asche

If not too many people sign up I will sponsor the beer which means you just have to bring your food with you and if you have to drive something to drink without alcohol.

If you have something to show or would like to discuss something related to JavaFX...feel free to bring your computer with you and I will take care about a beamer or something else if you would like to present something.

As a side note...my bbq grill is not that big so don't expect too much of it... :)

I will post more information about the location etc. as soon as we will have a date (at the moment everything looks like it will be the 21st of June).

That's it so far...would love to see you at the BBQ...so keep coding...

Friday, April 19, 2013

Validate it...

Hi there,
It's already some time ago when I released my last blog post but I was busy with presentation preparation, trainings, preparing stuff for my upcoming JavaFX related podcast etc.
I was playing around with validation using css styles and so far that is an easy way to do some validation. But I in the Java Swing days I used the GlasPane to draw validation icons on top of invalid or valid controls. This approach was not always useful but I liked it because I could use one set of validation icons and validate all kinds of controls. So I was asking myself how I could implement this behavior in JavaFX. 
I decided to go with the Canvas node because it has a translucent background by default and enables me to draw whatever I like by only using one node on the scene graph. The only disadvantage was that the Canvas node is like an image means it won't resize automatically but you have to take care about size by yourself.
Well the solution to this problem could be extending Canvas and implement the autosizing behavior or encapsulate the Canvas node into another node which could be resized automatically and react on the new size by using an InvalidationListener to the resizable control. I decided to encapsulate the Canvas node in a Region because it's lightweight and supports resizing. 
The implementation is more a proof of concept than a ready to go solution but it should be good enough to play around with it. It only takes two classes, the
  • ValidationPane
  • Validator
The ValidationPane is simply a Region which encapsulates a Canvas node. To use the ValidationPane one simply has to add the nodes that should get the validation overlays by using one of the following methods
  • add(Node node)
  • add(Pos position, Node node)
  • addAll(Node... nodes)
  • addAll(Pos position, Node... nodes)
Here is a short example that shows you how to add a TextField to the ValidationPane

TextField textField = new TextField();

ValidationPane validationPane = new ValidationPane();
validationPane.add(Pos.TOP_LEFT, textField);

As you could see it is possible to configure the position of the validation icon (the default position is Pos.TOP_LEFT).

There are five different states that one could use for validation
  • Validator.State.VALID
  • Validator.State.INVALID
  • Validator.State.INFO
  • Validator.State.OPTIONAL
  • Validator.State.CLEAR
To set the validation state of a node you simply have to call the setState() method on the validation pane, for the example above this would look like follows

validationPane.setState(textField, Validator.State.INVALID);

If you set the validation state to Validator.State.VALID the validation icon will fade out after 1500 ms to keep the interface clean. 
If the node is invalid the validation icon will stay visible as long as it is in the invalid state.
On the following screenshot you could see three different states (Validator.State.CLEAR has no indicator).


You could see all three available indicators on the image above (invalid, valid and info). 
The idea was to use the validation not only for textfields (which is most of the times the standard use case) but for example also for complete layout containers like a HBox, GridPane etc.
Therefor it works on the JavaFX Node instead of Control. I did not make very indeep tests with it and cannot guarantee that it works in any case but like I said it's more a proof of concept than a ready to go solution.
To use it you simply have to wrap your existing root pane in an additional StackPane and put the ValidationPane on top by adding it at the last node to the StackPane. Because the ValidationPane is transparent to mouse events it won't catch events and should be "invisible" to your application. The following image should try to give you an idea...



It was fun to create and very similar to the Swing GlasPane approach and proofed that even if JavaFX is based on a SceneGraph using nodes for visualization one could easy adopt a bitmap based approach by using the Canvas node.

If you are interested in the source code, please find it here.

ATTENTION: I'm using lambdas in the code which might not work in every IDE !!!


UPDATE:
During the last JavaFX training course at Canoo in Basel one of the attendees pointed me to a useful feature for the validation pane. If you think about nodes that are invalid and are not visible. These nodes should not show their validation icon right...so I've added this behavior to the ValidationPane. So if you would like to take a look, feel free to get the code from BitBucket. I've also updated the demo to show the new behavior.


That's it for today so keep coding...

Friday, March 1, 2013

Just for the fun(k) of it...

Hi there,
again time for some fun. This time it's (again) about a clock that simply has an awesome design. I blogged about it nearly exact two years ago, it's the QlockTwo from Biegert & Funk...maybe it should better be Biegert & Fun :)
This clock is simple and stylish and two years ago I've created a Swing version from it which was fun. After I have finished the JavaFX training course last week in Basel at Canoo Headquarters a colleague of mine came to me and showed me his version of a JavaFX QlockTwo and I showed him the Swing version. Well what should I say, on my way back home I could not withstand and started porting the Swing version to JavaFX (thanx Sven for pointing me on that).
Two years ago I've implemented german, english, french and dutch as supported languages but now that we have friends in Spain too (yes José this is for you) I decided to add also a spanish version. The original QlockTwo also supports something like a seconds only mode where the current seconds will be displayed and because this was not in my original version I've added it to the JavaFX version too. 
Long story short, here is a screenshot that shows nearly all styles available (only dark-chocolate is missing on the screenshot), here you go...



The main problem was to get the display of the time right for all the languages (and there are still some problems) but overall it was great fun to create it. So if you figure out problems, just let me know or file an issue on github.

And because the original QlockTwo costs € 345 for the small version and € 885 for the standard version which means I guess most of you could not afford to buy one...I decided to add the control to the Enzo library which you could find on github. So everyone who's interested could have it's own version on his desktop monitor.

Well having the clock on the desktop monitor is some kind of nice but having it on a Raspberry Pi would be even better, so I've also added it to the Enzo7 library which you could find here (only as binary because things will change in the future). Means that if you have a lcd panel attached to your Raspberry Pi (like I have :) ) you could use the Raspberry Pi as a poor mans QlockTwo.

That's it for today, I hope you enjoy JavaFX as much as I do...keep coding...


Monday, February 4, 2013

One class gauge...

Aloha...
Last week I prepared some things for my JFokus session and found a nice gauge on the web that looks like this...


It shows the temperature...wait a moment...the JavaFX app on my BeagleBoard also shows the temperature...why not use this gauge to visualize it. The gauge seems to be simple enough so that there should be no performance problems with the restricted resources of the BeagleBoard.
Long story short...here is the result...


I used different colors for the sections because this colors look better on the lcd screen that is connected to my BeagleBoard. In addition I've also added an indicator that shows up if a given threshold is exceeded.
When you create a custom JavaFX control for the JDK7 implementation that runs on the BeagleBoard you can't use the 

  • Control
  • Skin
  • Behavior
  • css

approach because the control won't show up. So the solution is to create the complete control in one file which is totally fine for such a simple control.
And that's exactly what I did and now I could use this control on my BeagleBoard JavaFX app to show the measured temperature.
One could define the sections with their colors, a min- and max-value and a threshold for the gauge. The tickmark implementation is really simple and won't really work with large ranges, so for me it works out and if you would like to use that thing by yourself...feel free to fork it on github.

That's all for today...so...keep coding...




Sunday, February 3, 2013

Native idea...

Hi there,

This will be a short blogpost about how to get native packaging up and running in IntelliJ Idea. Usually I used NetBeans to create native packages in JavaFX because it's so easy with NetBeans but it would be nice to be able to build the native package also in IntelliJ. Fortunately Thierry Wasyl blogged about how to create startable JavaFX jar files in IntelliJ Idea a few weeks ago so I just had to modify his work a bit to get also native packages out of a build.
In principle you just have to do the following:

1. create a Java project in IntelliJ Idea or use an existing one

2. go the 'Build' menu and select 'generate Ant Build...'



3. open the generated ant xml file and delete all content

4. copy the following content into the ant xml file


<?xml version="1.0" encoding="UTF-8"?>
<project name="PROJECT_NAME" default="default" basedir="." xmlns:fx="javafx:com.sun.javafx.tools.ant">

<!-- 
Project structure:
PROJECT_NAME/src              Sources folder
PROJECT_NAME/lib              Folder of external jar files
PROJECT_NAME/build            Folder for the output
PROJECT_NAME/build/classes    Folder that will contain the class files
PROJECT_NAME/build/dist       Folder that will contain the jar file
PROJECT_NAME/build/bundles    Folder that will contain the native package
-->

    <property name="application.title" value="APPLICATION_TITLE"/>
    <property name="vendor.name" value="VENDOR_NAME"/>
    <property name="java.home" value="${env.JAVA_HOME}"/>
    <property name="source.dir" value="src"/>
    <property name="lib.dir" value="lib"/>
    <property name="out.dir" value="build"/>
    <property name="out.dir.classes" value="${out.dir}/classes"/>
    <property name="out.dir.dist" value="${out.dir}/dist"/>
    <property name="out.dir.dist.lib" value="${out.dir.dist}/lib"/>
    <property name="app.jar.name" value="JAR_FILE_NAME.jar"/>
    <property name="main.class" value="PATH.TO.MAIN.CLASS"/>
    <property name="manifest.classpath" value="lib"/>
    <property name="manifest.externaljars" value="${manifest.classpath}/EXT_LIB1.jar ${manifest.classpath}/EXT_LIB2.jar"/>

    <path id="external.jars">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
    </path>

    <path id="classpath">
        <fileset dir="${java.home}/lib" includes="**/*.jar"/>
        <path refid="external.jars"/>
    </path>

    <target name="default">
        <taskdef resource="com/sun/javafx/tools/ant/antlib.xml"
                 uri="javafx:com.sun.javafx.tools.ant"
                 classpath=".:${java.home}/lib/ant-javafx.jar"/>
    </target>

    <target name="clean">
        <delete dir="${out.dir}"/>
    </target>

    <target name="init" depends="clean">
        <mkdir dir="${out.dir}"/>
        <mkdir dir="${out.dir.classes}"/>
        <mkdir dir="${out.dir.dist}"/>
    </target>

    <target name="compile" depends="default, init">
        <javac srcdir="${source.dir}" destdir="${out.dir}/classes" classpathref="classpath"
               source="1.7"
               target="1.7" />
        <copy todir="${out.dir}/classes">
            <!-- Define all filetypes that you need in your project -->
            <fileset dir="${source.dir}">
                <include name="**/*.png"/>
                <include name="**/*.fxml"/>
                <include name="**/*.css"/>
                <include name="**/*.wav"/>
                <include name="**/*.ttf"/>
                <include name="**/*.otf"/>
                <include name="**/*.html"/>
            </fileset>
        </copy>
        <copy todir="${out.dir.dist.lib}">
            <fileset dir="${lib.dir}">
                <include name="**/*.jar"/>
            </fileset>
        </copy>
    </target>

    <target name="build" depends="compile">
        <fx:application id="APPLICATION_TITLE" mainClass="${main.class}"/>

        <!-- Create the jar file -->
        <fx:jar destfile="${out.dir.dist}/${app.jar.name}">
            <fx:application refid="${application.title}"/>

            <manifest>
                <attribute name="Implementation-Vendor" value="${vendor.name}"/>
                <attribute name="Implementation-Title" value="${application.title}"/>
                <attribute name="Implementation-Version" value="1.0"/>
                <attribute name="Class-Path" value="${out.dir.dist.lib}"/>
                <attribute name="Main-Class" value="com/javafx/main/Main"/>
                <attribute name="JavaFX-Application-Class" value="${main.class}"/>
                <attribute name="JavaFX-Class-Path" value="${manifest.externaljars}"/>
            </manifest>

            <fileset dir="${out.dir.classes}"/>
        </fx:jar>

        <!-- Create the native package -->
        <fx:deploy verbose="true" width="200" height="400" nativeBundles="all" outdir="${out.dir.dist}" outfile="${application.title}">
            <fx:application name="${application.title}" mainClass="${main.class}"/>
            <fx:resources>
                <fx:fileset dir="${out.dir.dist}" includes="*.jar"/>
                <fx:fileset dir="${out.dir.dist}" includes="lib/*.jar"/>
            </fx:resources>
            <fx:info title="${application.title}" vendor="${vendor.name}"/>
        </fx:deploy>
    </target>
</project>



5. modify all the yellow marked text in the build xml file which should be self explaining

6. open the Ant Build area and add the build xml file by pressing the plus button



7. select the build entry and press play and after some seconds you should have a native package of your JavaFX application.

Please keep in mind that I'm running 7u13 on OS X which means the path to the jdk might be different on your machine. This build script is also able to add external jar files but therefor you have to put the external jar files in a "lib" folder that is at the same level as the source folder.



After the build is finished you should find a build folder that contains a classes folder which contains all the generated class files. In addition you will find a dist folder that contains the jar file and the lib folder with the external libs (jars)


In the dist folder you will also find a bundles folder that contains the native package and the setup program.



In my case it's the app folder and the dmg file.

You could also download the buildfx.xml file directly here.

I hope this was helpful for some of you...so keep coding...







Wednesday, January 9, 2013

Fun with PreView releases...

Aloha,
I was not sure if it is worth the time to blog about something that might be outdated within weeks but it's so much fun that I decided to share it with you.
At Devoxx 2012 I talked to Daniel Blaukopf (Oracle) where he told me that it won't take long until JDK8 for ARM Preview will be released for the Raspberry Pi and in the beginning of December last year it happened...yipppeah
As much as I loved coding for the BeagleBoard...coding for the Raspberry Pi is even more fun and that's not because of Java/JavaFX (which is in principle the same) but more because the setup of the Raspberry Pi is much easier than the BeagleBoard.
Long story short I had a Raspberry Pi already and the second was ordered at that time so that I was able to start coding for the Pi directly after JDK 8 was released.
First of all I have to say that the instructions on the Oracle page are really good this time and you could get something up and running within a short time.
Because I started porting some of my controls to JDK8 already I was really looking forward to use some of these controls on the Pi...BUT...it didn't work :(
I was not sure why and tried different things but in the end the solution was quite simple...the Embedded team and the Desktop team at Oracle just based their SDKs on different snapshots which lead to my problems.
Don't get me wrong...the "normal" Java stuff works fine but when it comes to Custom Controls (and that's the stuff I'm interested in) you will find different behavior in JavaFX between JDK8 SE and JDK8 for ARM. The problem is only because of one class...SkinBase. 
In JDK8 SkinBase moved from 

    com.sun.javafx.scene.control.skin.SkinBase

to 

    javafx.scene.control.SkinBase

In addition to this the constructor changed from

    SkinBase(Control control, ControlBehavior behavior)

to

    SkinBase(Control control)

So that seems to be not a big deal right...you just have to adjust your Skin class and everything should be fine...
This is only correct for the JDK8 SE version because the JDK8 ARM preview is based on a different version it still takes two arguments in the constructor.
The solution for the problem was to extract the jfxrt.jar from the JDK8 ARM preview, link it to your project and compile your project against JDK7 on the Desktop. Most of the time I spent on figuring out how to compile the jar in a way that it works on the Raspberry Pi on JDK8 ARM preview.

Because it's only a temporary version and will change in the near future I won't post any source code here but I will give you the jar with the controls so you can play with it on your Raspberry Pi.

Related to the new name of the css file in JDK8 which is now Modena instead of Caspian I named the lib Enzo because of Enzo Ferrari who's company Ferrari is placed 18 km away from Modena in Italy. (You have to login to Jira to see the images of Modena and Caspian).
The lib contains the following controls:

  • Clock
  • Lcd
  • Led
  • LedBargraph
  • SevenSegment
  • SimpleIndicator

These are the controls that you will also find in the JFXtras-labs project but implemented in a different way. I completely change the style of creating controls after I discussed with Jonathan Giles, Richard Bair and Jasper Potts.
You don't have to decompile the jar file to get the source code because I will blog about Enzo in the near future anyway and for those of you that can't wait you could find a repository on github here.
There's also a radial gauge in the package but it's work in progress so you can't really use it because it has no tickmarks at all at the moment :)

Download:
Binary jar: Enzo7.jar

Because this post has no images right now...here is one to see the controls in Action running on one of my Raspberry Pi's



The image shows my Raspberry Pi no. 3 that is connected to a 10" touch screen. In addition I've attached logitech usb audio speakers and a high power rgb led from yoctopuce. On the display you see two Lcd controls visualizing the temperature measured by my Raspberry Pi no. 1 and no. 2, two SimpleIndicator controls that visualize the temperature range of each pi and a Clock control showing the current time.

I've also recorded a little video of the setup that you could find on YouTube.

Have fun and keep coding...