Enzo

Thursday, April 17, 2014

Just flip it...

Hi there,

When writing this blog post I'm on a trip in Canada visiting my good friend Todd Costella for a JavaFX training. So before the training started I've found a control that I've created 2 years ago and that was not very well coded so I decided to port it to JavaFX 8 and add it to my Enzo library. 
The control is a simple panel that has two sides to which one could add some content. To switch between both sides the panel has to methods, flipToFront() and flipToBack(). I personally think that this kind of control could be quite useful in applications to keep the focus of the user at the position where you would like to have it. E.g. changing the properties of a control can be done at the location where the location is placed instead of using a properties menu etc.
Here is a little video that demonstrates the usage of such a panel.



This might not be usable for everything but in some applications it could make sense.

For those of you that are interested in this, you will find it as part of the Enzo controls library on bitbucket.

So that's all for today and don't forget...keep coding...

Monday, April 7, 2014

Just because you asked for it... Part II

And again a little post about a control that you've asked me for...

The Horizon control from the SteelSeries Swing library is now also available as a JavaFX 8 control (but like the AirCompass it's just a quick conversion without many possibilities for modifications).
To those of you that don't know what I'm talking about, this was the original Horizon Swing control...



And here is the JavaFX 8 version of the Horizon control...


As you can see it doesn't look exactly the same but I hope it's good enough for those of you who asked for it.

Otherwise...just fork it on BitBucket and do it yourself :)

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

Thursday, April 3, 2014

Poor mans live editor...

Aloha,

I was looking for an idea on how to show what one could do with the JavaFX WebView except showing html content and had an idea on how to combine the WebView and Nashorn for some live editing.
So you might have seen live editors where you can edit code and directly see some visual feedback (e.g. SwingPad).
Well I was not after recreating this editors but only on how to do this in a very simple way and this is what I've came up with.
Create a simple HTML page with just a textarea like follows:

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript">
        var doc = document;
        function getCode() {
            window.status = doc.getElementById('codeArea').value;
        }
    </script>
    <style type="text/css">
        textarea {
            font-size: 12px;
        }
    </style>
</head>
<body style='background-color: rgb(216, 222, 227)'>
<textarea id='codeArea' name='codeArea' onkeyup='getCode()' rows='23' cols='55'>
// Import JavaFX classes
var Color   = javafx.scene.paint.Color
var Led     = Packages.eu.hansolo.enzo.led.Led
var LedType = Packages.eu.hansolo.enzo.led.Led.LedType


// JavaFX Code in JavaScript syntax
led.ledType  = LedType.ROUND
led.ledColor = Color.RED
led.on       = false
</textarea>
</body>

</html>

As you can see the HTML page only has one textarea that contains some code. The code is JavaScript and should set some parameters of an Enzo Led JavaFX control later on.
I hooked up an onkeyup listener that will trigger the getCode() method each time a key was pressed.
This method only set the window.status to the current value of the textarea tag.
The nice thing in the JavaFX WebView is the possibility to hook up a ChangeListener to the window.status of the loaded HTML page.
That means as soon as the window.status in the loaded HTML page changed, the ChangeListener in the JavaFX application will be triggered and one could read the new status of the HTML page (which is the text in the textarea in this case). 
This is the point where Nashorn joins the game, I simply pass the text from the textarea to the Nashorn JavaScript engine and try to evaluate it as code. If the code is valid it will be executed immediately. To see the changes in the JavaFX application I've added the Enzo JavaFX Led control to the Scene. The last thing we need to do is to inject the Led control instance to the Nashorn scripting engine so that Nashorn is able to change the parameters of the Led control.

Here is the JavaFX code that demonstrates the live editor.

public class Demo extends Application {
    private ScriptEngineManager scriptEngineManager;
    private ScriptEngine        scriptEngine;
    private StackPane           ledContainer;
    private Led                 led;
    private WebView             webView;
    private WebEngine           webEngine;


    // ******************** Initialization ************************************
    @Override public void init() {
        led = new Led();

        ledContainer = new StackPane(led);
        ledContainer.setPrefSize(400, 400);
        ledContainer.setPadding(new Insets(10, 10, 10, 10));        

        initNashorn();
    }

    private void initNashorn() {
        scriptEngineManager = new ScriptEngineManager();
        scriptEngine        = scriptEngineManager.getEngineByName("nashorn");

        // Inject led object into Nashorn scripting engine
        scriptEngine.put("led", led);
    }

    private void initWebView() {
        webView = new WebView();
        webView.setPrefSize(600, 400);
        webEngine = webView.getEngine();
        webEngine.load(Demo.class.getResource("editor.html").toExternalForm());
        webEngine.getLoadWorker().stateProperty().addListener((ov, o, n) -> {
            if (Worker.State.SUCCEEDED == n) {
                webEngine.setOnStatusChanged(webEvent -> {
                    try {
                        scriptEngine.eval(webEvent.getData());
                    } catch (Exception e) {/* code was not valid */}
                });
            }
        });
    }


    // ******************** Application start *********************************
    @Override public void start(Stage stage) {
        initWebView();

        HBox pane = new HBox();
        pane.setSpacing(10);
        pane.getChildren().addAll(ledContainer, webView);

        Scene scene = new Scene(pane);

        stage.setTitle("WebView live edit");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

Keep in mind that you JDK8 and Enzo to run that code. The result should look similar to this...




This is a very easy poor man live editor that has a lot potential for improvements (like adding a syntax highlighting JavaScript library like highlight.js or codemirror) but it shows the power of the JavaFX WebView in combination with Nashorn.

That's it again...so enjoy Java and keep coding...

Wednesday, April 2, 2014

Just because you asked for it...

Hi there,

I know I know...long time no post but that's like it is when you're busy...
So today I just have a short post for you about a control that I've originally created for the SteelSeries Swing components library but because you've asked for a JavaFX version I've decided to quickly create one and here you go.
The control I'm talking about is the so called AirCompass which simply visualizes the bearing like you know it from airplanes.
The original version can be found here and it looked like this...



The JavaFX version looks a bit different (because I did not spent much time on it) but should be good enough, here it is...


It has not many properties but you can set the bearing, you can enable/disable animated rotation and you can set the color of the plane and the orientation text...that's it.

So if you would like to use it, feel free to get it on bitbucket.

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



Wednesday, February 19, 2014

Fun with JavaFX on Raspberry Pi again...

Hi there,

Long time no post...I know...but today it's time for another blogpost. This time it's about a little lcd display for the Raspberry Pi that I've found on the web. I really like the embedded computing scene with all it's nice little projects that solve little problems but what I don't like is all the loose wires and breadboards lying around. The reason for that is that it's really hard to take this stuff with you to conferences and show use them for demos. This stuff is just to fragile and I really don't want to take a soldering iron with me to fix problems before my conference session :)
Long story short...I like everything that is small, robust and where I don't see many cables.
With this on my mind I'm skimming the web from time to time searching for new gadgets that might be useful and in the beginning of last week I've found the following little lcd display


The really nice thing about that display is it's size and that you can plug it directly on the Raspberry Pi. And because it's really thin it will fit in a standard Raspberry Pi housing. But before you start to drill holes into your existing Pi case you should think about to buy an already prepared one like the following from TEK-BERRY


Sometimes things are sooooo easy :)
Of course there are many displays available for the Raspberry Pi but in this case I read something about FrameBuffer and X-Windows support which brought JavaFX on my mind. 

The Lcd display and the case are available at Watterott.com

LCD Display

TEK-BERRY Case

So I ordered a display (30 €) and a case (9 €) and when it arrived last Saturday I've put everything together. 
To get the LCD display running you need a special Raspbian image and modify some settings.
A detailed instruction can be found on GitHub and the image can be downloaded here.

When you follow the instructions the lcd display will be used as standard display on the console and also with support for x-windows.

The next thing was to figure out how to get JavaFX running on that display. Because there are frame buffer drivers available for the display it should somehow be possible to get JavaFX running on this display from the command line but I was not able to figure out how to do that (to be honest I only spent 2 hours on it). 
And because I knew that x-windows works on the device I decided to start my JavaFX application from x-windows because there I also have touch support. The LCD supports simple touch events (afaik 2 point touch) but no swipes etc. 

When using x-windows with an attached touchscreen you will always see the mouse pointer (even if no mouse is attached). To get rid of the mouse pointer in x-windows you might want to use unclutter that will hide the mouse pointer after a defined interval and only makes it visible when the user touches the display. To install unclutter you just have to type

sudo apt-get install unclutter

You can use unclutter as follows

unclutter -idle 0.01 -root

which defines the number of seconds before the pointer will disappear (1/100 second in this case) but this won't work directly from the shell, instead we will use it in the next step.

To start a JavaFX application from the command line using x-windows you simply have to add a file named .xsession to your users home folder. And in this file you simply have to call your JavaFX jar file with the parameter -Djavafx.platform=gtk. So your .xsession file should look similar to the following

unclutter -idle 0.01 -root
java -Djavafx.platform=gtk YOUR_APPLICATION.JAR PACKAGE.MAIN

The nice thing about using a .xsession file is that as soon as you call startx on the command line it will start x-windows and directly load your application. If your application uses the fullscreen (which is 320x240 pixel in this case) only your application will popup on the screen. And even better, if you close your application also x-windows will be closed and you are back to console...nice isn't it...

If you are up to this step you will figure out that the x-axis of the touch events is mirrored which means if you touch the display on the left part the mouse pointer will appear on the right part of the display. To correct this behavior you have to open the file

/usr/share/X11/xorg.conf.d/10-edev.conf

with a texteditor (e.g. vim, nano etc.) and search for the last topic (should state touchscreen somewhere). Here you have to add the following line

Option "InvertX" "true"

If you don't use unclutter you have to invert the y-axis instead means you have to add the following line 

Option "InvertY" "true"

And that's it, with this setup you can run JavaFX on the embedded LCD display with touch support which makes the Raspberry Pi very useful as display for current weather, measured data, switch or whatever you have on your mind...

I use it as another display for my JavaFX everywhere demo where I monitor a sensor network with different devices. 



As an example I've tried to record a little video that you can find on youtube.

On the video you can see that I use some kind of swipe events to navigate between the screens of my application. But because the display doesn't support swipe events I've simply implemented them by using EventHandlers on the Scene that are listening for MousePressed and MouseReleased events.

So that's it for today...keep coding...

Monday, December 16, 2013

DateAxis310

Aloha everybody,
Last week I was traveling to Dierk K├Ânig in Zurich by train which gave me some time for some coding...as always :)
Because I use JSR310 (date and time API) in my Sensor Network project and I was trying to visualize some data in a JavaFX line chart.
In principle this should be no problem BUT there is no date axis in the JavaFX charts API.
Lucky me that some people ran into the same problem before me and created a date axis already. There are two implementations I knew which are the one from Pedro Duque Vieira (@P_Duke) which you could find here

http://pixelduke.wordpress.com/2013/12/13/dateaxis-and-xybarchart-update/

the other date axis implementation was made by Christian Schudt and can be found here

http://myjavafx.blogspot.de/2013/09/javafx-charts-display-date-values-on.html

Both implementations are using java.util.Date and so are not usable for me (well you can of course use the Instant class to convert LocalDateTime to Date but I don't like that approach). 
So I converted the implementation from Christian Schudt (because it was the first I found on the web) to a version that takes java.time.LocalDateTime instead of java.util.Date.
I focused really on getting things to work and it might be that the result is not 100% bullet proof, so feel free to test it, fork it or submit patches.
The next little problem I ran into was the missing StringConverter that can convert java.time.LocalDateTime values into a String...so I created one :)
With this you can now define the format of the date axis labels which is really useful.

For those of you who can't wait to get the code...please find a little repository on bitbucket here which contains the sources and a little demo:

https://bitbucket.org/hansolo/dateaxis310

Now there's not much more to say than thanx to Pedro and Christian for their work and to show you a little screenshot of the DateAxis310 in action...


If you would like to see some code...here you go...

// Use a special StringConverter to format axis labels
StringConverter<LocalDateTime> stringConverter = 
  new StringConverter<LocalDateTime>() {
    @Override public String toString(LocalDateTime localDateTime) {
      DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd.MM.yy\nHH:mm:ss");
      return dtf.format(localDateTime);
    }
    @Override public LocalDateTime fromString(String s) {
      return LocalDateTime.parse(s);
    }

};

// Create a new DateAxis
DateAxis310 dateAxis = new DateAxis310();    
dateAxis.setTickLabelFormatter(stringConverter);

// Create a new NumberAxis
NumberAxis numberAxis = new NumberAxis();
numberAxis.setLabel("Temperature [°C]");

// Create a data series
XYChart.Series series = new XYChart.Series<LocalDateTime, Number>();

series.setName("Temperature [°C]");

// Now add some data to the series
List<XYChart.Data<LocalDateTime, Number>> data = new ArrayList<>();
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 1, 13, 0, 0, 0), 8));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 2, 27, 0, 0, 0), 4));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 3, 27, 0, 0, 0), 1));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 4, 27, 0, 0, 0), 7));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 5, 27, 0, 0, 0), 5));
data.add(new XYChart.Data<>(LocalDateTime.of(2013, 6, 27, 0, 0, 0), 3));

series.getData().setAll(data);        

// Create the LineChart
LineChart<LocalDateTime, Number> lineChart = 
  new LineChart<>(dateAxis, numberAxis);
lineChart.setTitle("Temperature Chart");
lineChart.getData().add(series);

lineChart.setAnimated(false);
...

As you can see the DateAxis310 can be used in the same way as the other axis of the JavaFX chart api.

And that's it for today...keep coding...

Friday, December 6, 2013

Enzo moved to Bitbucket

This is just a short blogpost about some modifications to the Enzo project. 

First of all I changed the build from one monolithic project to a multi project gradle setup.
With this approach each package will now be created as a single jar which makes it possible to use only parts of the library (e.g. only the Led). 
When you build the library it will also create the single jar file that contains all controls like before.
This is something that was on my to do list for some time and today I finally did the conversion.

And because I was changing the whole setup I decided to change the repository hosting from github to bitbucket.

At the moment you will find the "old" version on github and the new version on bitbucket but I will remove the repo from github in the near future.

Here is the link to the new repository on bitbucket:

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

This was the first time I setup a multi project build with gradle in IntelliJ 13 and I hope everything works like expected, so if you have problems with building the project, please let me know.

That's it for today...so enjoy the upcoming weekend and keep coding...