Friday, November 29, 2013

JavaFX on Android

Hi there,

Today I finally was able to get one of my JavaFX custom controls running on my Android based Nexus 7 and I think this is a good reason to share it with you...
So first of all I have to say THANK YOU to Johan Vos for setting up a Bitbucket Project that makes the setup very easy. So for those of you that don't know what I'm talking about, please take a look here

https://bitbucket.org/javafxports/android/wiki/Home

There you will find a description how to compile a JavaFX project for Android. Well for those of you that know me you can imagine that running a "boring" standard JavaFX application is fine but I would like to see one of my controls running on my Nexus 7 :)
So the first thing I did was trying to get one of my Enzo controls running on my Nexus 7 and what should I say...I failed... :(
Well that was not really surprising because you need JDK7 style Custom Controls to let them run on your Android device. 
That means you usually would need

  • Control
  • Skin
  • Behavior
  • CSS

for your control. So I backported the SimpleGauge from Enzo to JDK7 and tried to get it running on the Nexus 7...and again failed.

The only thing that I saw was a little white square on the Nexus which looked to me like the scene was not properly resized. The next step was instantiating the scene directly with a with and height and now...I saw a white box with the right size but without any control...

This reminded me on the problems that I had with JavaFX Custom Controls on the BeagleBoard xM and so I used a different approach which is extending Region to create the control.

So instead of using the Control, Skin, Behavior and CSS approach I now simply created a class that extends Region and contains all the properties and drawing code.
And what should I say...it worked as you can see on this little video that I recorded with my iPad mini.





UPDATE: 
I've updated the app and instead of using random numbers it now shows live measured temperature, humidity and pressure data from one of my Raspberry Pi's. Btw the video also shows the same code running on my iPad mini :)

Here is the link: https://www.youtube.com/watch?v=KqSjywExsTs

So there are a few things I would like to tell you that might lead to problems...

Creating the jar from the IDE didn't work for me so I created the jar by using the javafxpackager like follows


javafxpackager -createjar -appclass PACKAGES.AND.YOUR.MAIN.CLASS -outfile YOUR_JAR_NAME.jar -v -nocss2bin -srcdir /PATH/TO/YOUR/PROJECTS/CLASS/FILES

That creates a jar file that you can start on the console by calling
java -jar AndroidFX.jar

After that was done I followed the instructions from Johan Vos and here you should use Gradle 1.4 (I got problems when using Gradle 1.9).

And another important thing was that I have to use JDK7 as the standard VM when compiling everything.


So for those of you that would like to try the Android APK file directly you can download it here:

AndroidFX-debug.apk

And for those that would like to take a look at the code that I used, feel free to fork it on Bitbucket...

https://bitbucket.org/hansolo/androidfx

I think that's all I have to say for today, so enjoy your upcoming weekend and as always...keep coding...

Wednesday, November 27, 2013

Enzo part II

And another one...
This time let me tell you something about another control in the lcd package...the LcdClock. To give you an idea what I'm talking about...here is a little screenshot



As you can see it looks similar to the Lcd control and indeed it is based on the Lcd control and supports all the Lcd styles that I showed in the last post.
Because this is just a simple clock there not so many features that you can adjust. The main things are

  • title
  • alarms
  • locale
  • dateFormat
  • dateSeparator

The title is just a simple text that will be shown on top of the LcdClock. When I created the LcdClock I remembered the time on the University where we had to spent some time in the CleanRoom and observe some processes. Most of the times we use a little AlarmClock with either a countdown timer or with a simple alarm to remind us on running processes etc.
So the idea was to have the ability to add one or more alarms to the LcdClock that will fire an event and can also execute something by themselves. So let me give you an example.

class Commando implements Alarm.Command {
    @Override public void execute() {
        System.out.println("This will be executed by the alarm");
    }
}

Alarm alarm = 
    new Alarm(Alarm.Repitition.ONCE,
              LocalDateTime.now().plusSeconds(30),
              Alarm.ARMED,
              "Some text",
              new Commando());

The Alarm class that I use here offers different features

  • time
  • repetition
  • armed
  • text
  • command

The time specifies the alarm time and the repitition defines if this alarm will be triggered only once or if it will be triggered in intervals. Possible values are

  • Alarm.Repetition.ONCE
  • Alarm.Repetition.HOURLY
  • Alarm.Repetition.DAILY
  • Alarm.Repetition.WEEKLY

You can arm or unarm an alarm by calling the setArmed(boolean) method on the alarm instance. 
Each alarm can have it's own text that you can use as an alarm message or for whatever you like. And at least we have the Command interface that simply has an execute() method which will be called when the alarm is due. 
The alarm indicator in the LcdClock will be visible as long as there are alarms in the internal list.
You can add and remove Alarms in the LcdClock and if an Alarm is due it will be removed from the list of Alarms if it has a repetition of Alarm.Repetition.ONCE.

Please keep in mind that this control (like all others in Enzo) was not made for production code and might contain bugs but if you like it you can fork it on bitbucket


https://bitbucket.org/hansolo/enzo/wiki/Home

That's it for today...so enjoy JavaFX and keep coding...

Monday, November 25, 2013

Enzo part I

Hi everyone,

As you might know I've started another JavaFX controls library named Enzo which you can find on github.
This project started as a playground for JDK8 and JavaFX8 and in the meantime it contains some controls that I would like to share with you.
So this is the first post of a series about the Enzo controls. The idea is to explain one control with each post and because it's my favourite control I will start with the Lcd control.

The Lcd control can be found in the package: eu.hansolo.enzo.lcd

If you instantiate a Lcd control you will get something like this...



This is the simplest version of the Lcd control only showing a value. The control offers many different features and if everything is enabled it will look like this...





As you can see there are different kind of symbols and text fields available.
On the next screenshot you will find the name of each feature...




Most of the above features could switched on/off (except the backgroundText which depends on the used valueFont). Because all controls in Enzo will come with a Builder (I liked the builders so I decided to add them to my controls) the code to instantiate the full blown lcd will look like this...

Lcd lcd = LcdBuilder.create()
                    .prefWidth(480)
                    .prefHeight(192)  
                    .styleClass(Lcd.STYLE_CLASS_STANDARD)
                    .backgroundVisible(true)                     
                    .value(42)
                    .foregroundShadowVisible(true)
                    .crystalOverlayVisible(true)
                    .title("Title")
                    .titleVisible(true)
                    .batteryVisible(true)
                    .signalVisible(true)
                    .alarmVisible(true)
                    .unit("°C")
                    .unitVisible(true)
                    .decimals(2)
                    .minMeasuredValueDecimals(2)
                    .minMeasuredValueVisible(true)
                    .maxMeasuredValueDecimals(2)
                    .maxMeasuredValueVisible(true)
                    .formerValueVisible(true)
                    .threshold(26)
                    .thresholdVisible(true)
                    .trendVisible(true)
                    .trend(Lcd.Trend.RISING)
                    .numberSystemVisible(true)
                    .lowerRightTextVisible(true)              
                    .valueFont(Lcd.LcdFont.LCD)
                    .animated(true)

                    .build();

As you can see in the code above there is a styleClass method in the builder where you can define the visual appearance of the Lcd control. And because there are so many nice Lcd displays out there I've tried to cover as many as I've found. 
To give you an overview over all available styles I created another screenshot for you...



As you can see there are a lot of different styles available and all of them are defined in CSS. You will find more realistic versions and also some flat ui styled ones.
In case you don't want to use a style at all you can simply switch of the background by calling setBackgroundVisible(false). With this feature you could use the Lcd also on your own backgrounds which sometimes might be useful.
You will also find features like the signal, trend, alarm or battery indicator which you can switch on or off by calling 

  • setSignalVisible(true/false
  • setTrendVisible(true/false)
  • setAlarmVisible(true/false)
  • setBatteryVisible(true/false)

The signal, trend and battery indicator also have getters and setters to set their value. So to set the battery to another value you can call

  • setBatteryCharge(double 0...1)

and for the signal indicator please call

  • setSignalStrength(double 0...1)

The trend indicator has 6 different states that you can call, the states are

  • UP
  • RISING
  • STEADY
  • FALLING
  • DOWN
  • UKNOWN

and the method to set one of these is

  • setTrend(Lcd.Trend.STATE)

Keep in mind that you have to take care about the trend which means you have to check whether it's rising or falling, so you can implement your own algorithm to calculate the trend.

You have 5 different fonts available to visualize the main value of the Lcd control. The available fonts are

  • Lcd.LcdFont.STANDARD
  • Lcd.LcdFont.LCD
  • Lcd.LcdFont.DIGITAL
  • Lcd.LcdFont.DIGITAL_BOLD
  • Lcd.LcdFont.ELEKTRA

which will look like this


Lcd.LcdFont.DIGITAL

Lcd.LcdFont.DIGITAL_BOLD

Lcd.LcdFont.ELEKTRA

Lcd.LcdFont.LCD

Lcd.LcdFont.STANDARD
If you use the Lcd control to measure values in a longer interval (> 2 sec) you can use the animation feature which will count the value from the current value to the new value in the time that you specified with setAnimationDuration(double duration) in ms. This is useful if you for example measure the temperature every 5 minutes you could set the animation duration to 60000 ms which will then slowly increase/decrease the value to the new measured value within a minute. But if you measure values more quickly (interval < 2 sec) you should switch off the animation by calling setAnimated(false). This will directly set the lcd value to the new value.

Another maybe useful feature is the ability to blink the value of the Lcd control by calling setBlinking(true). This feature can be used to indicate that a threshold was exceeded or simply to grab the attention of the user.

The Lcd control supports three different number systems that you can use which are


  • Lcd.NumberSystem.DECIMAL
  • Lcd.NumberSystem.HEXADECIMAL
  • Lcd.NumberSystem.OCTAL


which will display the current value in the choosen number system.
The lower right text can therefor be used to display the current number system by calling setNumberSystemVisible(true which will override the setLowerRightText("YOUR TEXT") method. Here are examples for the different modes


Lcd.NumberSystem.DECIMAL


Lcd.NumberSystem.HEXADECIMAL

Lcd.NumberSystem.OCTAL
It is also possible to use the Lcd control as a simple text display by enabling the text mode with setTextMode(true).
There is no scrolling or animation implemented for the text but this might come in future releases of the control.
Keep in mind that the text mode will not work with the Lcd.LcdFont.LCD because this is a 7-Segment font which has no characters.
Here are some examples






You can also use the text mode in combination with all the other features as on the following picture



I hope I covered most of the features of the Lcd control and if you have a special need for an additional feature you could either let me know and hope that I'll find some time to implement it or you can fork the project on bitbucket and do it yourself... :)

If you are interested in the sources you can find them on bitbucket at

https://bitbucket.org/hansolo/enzo/wiki/Home

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