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...