JFXMobile – first attempt

Who would not like to be able to write a single code base for desktop and mobile? I know I want to, and the applet I’m using for time registration is getting into a pinch with all the browsers dropping support for applets, so why not give JavaFX a try? And see if things go as smoothly as Gluon’s tweets make it sound?

HelloWorld
So, first things first and setup a nice virtual machine for this project with Java and Eclipse, hookup the old 1st gen Nexus 7, then download the HelloWorld demo project from Gluon. Finally a “gradlew androidInstall” should do the trick… (more…)

Continue ReadingJFXMobile – first attempt

Enzo’s simple gauge in JFXtras

Gerrit Grunwald is an enspiring internet of things (IoT) evangelist and his JavaFX library ‘Enzo’ contains many visually attractive controls, well suited for IoT but also many other JavaFX applications. Gerrit used to be an active contributor to JFXtras, but he decided to move his work to his Enzo library. Why? Because the scope of JFXtras did not fit his needs.

As an IoT evangelist he develops many JavaFX controls for his demos, and he wants to get results fast; there is always that next conference in a few days.  JFXtras on the other hand tries to uphold a certain quality by a.o. requiring tests to prevent regression. This is not something a roaming evangelist wants to invest his time in. So we end up with an interesting situation; great but risky controls! Examples of this are all the gauges that are part of JFXtras-labs 2.x: they were never ported to 8.x and thus all their users have a problem there. This of course is the risk of using anything from JFXtras-labs, it is after all JFXtras’ playground, with no guarantee what-so-ever.

So what now? Great controls but too risky to touch? For Enzo that may be the case, as Gerrit states on his blog; “Please keep in mind that all controls in that library are made for my personal demos and are not production ready”. However, Gerrit and I have an agreement that I’m allowed to become ‘inspired’ by (aka blatantly copy) his demos. This already happened with CornerMenu, which was inspired by one of Gerrit demo’s and spawned CircularPane and CirclePopupMenu. The next inspiration Gerrit gave me was his SimpleGauge.

metroArcGauge

(more…)

Continue ReadingEnzo’s simple gauge in JFXtras

corner menu

A few months back I had the pleasure of attending the multidevice presentation by Gerrit Grunwald (@hansolo_). In this presentation he demonstrated how easy it was to port a single JavaFX code base to several devices, including Android, iOS, RasberryPi, and a few more. One of the UI elements he showed on each device was a corner menu; circular icons appearing from the corner of a window. This was visually a great UI component, and Gerrit told me it was part of his Enzo library. The Enzo library is full of such visually appealing JavaFX controls and components, and freely available to everyone who wants to use them, but it is also the case that Enzo mainly exists to support Gerrit in his presentations and demonstrations. And there is a difference between a control intended for public use and one that is a result of a demonstration. So when I asked Gerrit if I could take his control and move it over to JFXtras, he agreed immediately.

The first order of business was to layout stuff in a 90 degree arc. And I could have just copied Gerrit’s code, but as things go in a hobby project I decided that this should be something reusable, so CircularPane was born.

CircularPaneRectanglesAndCircles

It took some time to get it working correctly; creating a general purpose pane for laying out stuff in a circle dynamically is not as trivial as it seems. But after a few weeks it got to the point where CircularPane was mature enough, a demo was available, and it was unit tested. After that, work could finally start on one of the primary things it was created for: CornerMenu. (Although the fact that a round shaped Android watch will come out soon, may turn out to be a nice coincidence.)

So CornerMenu is exactly what it says: a menu that is located in any of the four corners of a window. The menu can be static, but usually it will show the items when the mouse comes close to the corner, like so:

cornerMenu-fromOrigin (more…)

Continue Readingcorner menu

Java 8 method references

Java 8 is finally out officially and it brings probably the biggest change to the Java platform ever; lambda’s. Lambda’s are a very powerful technology which will have major influence on the way API’s in Java will be written, but the first critical sounds also are heard already.

Lambda’s in Java have two main aspects; one is the powerful stream API, where all kinds of processing is chained and in that way multicore processing is easily made possible. The other aspect is the replacement of the anonymous inner classes scaffolding, and that is probably the thing people are exited about first, when discovering lambda’s in Java 8. Let’s take a peek using my latest hobby project as an example.

In the previous blog I’ve written about CircularPane; a way to layout nodes in JavaFX in a circle. Below is an example of how some tests in CircularPane look (the green circles are debugging hints):

CircularPaneRectanglesAndCirclesDebug

One of the latest additions is that nodes can be animated into their positions. The example below shows that the left two CircularPanes animate their nodes into place “over the arc”, the right two “from origin”.
circularPaneAnimation (more…)

Continue ReadingJava 8 method references

Round and round she goes

JFXtras has a TimePicker that uses a number of Sliders to represent hours, minutes and seconds. And even though this is functionally an OK user interface, it is visually not very appealing.

TimePickerHM

Recently I upgraded to a new phone and ran into this Android TimePicker, which I liked better than my slider UI. So I figured I would try and create something similar.

android-calendar-time-control-1

The first thing that is needed to create a UI like this, is to layout nodes in a circle. That turned out not to be too difficult, but the implementation was very specific for the circular time picker I was working on. And I figured it would be nice if the circular layout was reusable, so I got side-tracked in creating CircularPane. (more…)

Continue ReadingRound and round she goes

Named queries are evil

  • Post category:JavaJEEJPA

The JPA specification has the concept of named queries which is an attempt to ‘Don’t Repeat Yourself’ (DRY), but in my opinion it is more a ‘Mistake By Specification’.

The fact that a query is written as a string, and therefore is not compiler checkable, is a missed chance (solutions like QueryDSL offer great alternatives here), but not the point I would like to make. My issue is with the ‘named’ part.

The link to named queries above has the following example:

@NamedQuery(
    name="findAllEmployeesByFirstName",
    queryString="SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = :firstname"
)

What you see here is that there is a definition of a query (usually located at the top of the Entity class) and somewhere else the query is used to read employees from the database, like so:

Query queryEmployeesByFirstName = em.createNamedQuery("findAllEmployeesByFirstName");
queryEmployeeByFirstName.setParameter("firstName", "John");
Collection employees = queryEmployeesByFirstName.getResultList();

The problem is that the named query in no way enforces or even specifies the parameters it requires. In this case it requires one, and its name of course suggest that, but this is a very thin and unstable relation, and not something I would like to base the stability of my code upon. After all, we all know how easy the name may go out-of-sync to the contents of the query. (more…)

Continue ReadingNamed queries are evil

The Java 9 named parameter pitch

  • Post category:Java

In the previous post Daan van Berkel again made clear that a fluent API is so much more readable than the “regular” API’s. Unfortunately a lot of projects do not have the luxury of being able to convert their code to the fluent paradigm. But there are some easy improvements possible, one of them would be the introduction of named parameters.

Let me first start with a simple example:

    component.show(false, true);

Well, there is nothing wrong with that code, except as an outsider you have no clue what it is doing exactly. What do the two booleans indicate? This can only be solved by a round trip to the documentation. A fluent API would fix this:

    component.modal(false).centered(true).show();

(more…)

Continue ReadingThe Java 9 named parameter pitch

To comment or not, that is the question

  • Post category:Javaunittest

Recently I worked my way through the “Effective Unit Testing” book. A nice read, nothing too complex or difficult, but it is always good to read the opinions of someone who really put some effort into a certain topic. One point was the question if code should contain comments or not, mainly because comments can have a negative impact because they can be incorrect and misleading. So the proposed solution was to write code that does not require comments at all; write “self documenting code”.

In my current project I run into similar situations on a daily basis; my idea on how code should look differs from the most of the other developers. I see people writing tons of code without a single comment in them and declare them “self documenting”. The problem is that for some reason I do not seem to be able to get comfortable with that code, and I’m really starting to wonder if I’m getting old, and am missing out on the “new and improved way” of doing things. But I’m not one to accept that without an effort, so I gave it a shot.

Below is an example of a simple unit test. Please do not spent too much time on this, because it is the “before” example. But the test is ok, there is nothing technically wrong with it, it just can be written better.

    public void testVerifyGroupThenAddClient() throws ValidateException {
        // group starts off not verified
        GroupCare assertGroupCare = groupCareManager.findByObjectId(groupCare.getObjectId());
        assertNull(assertGroupCare.getVerifiedAt());

        // add client
        groupCareManager.addClient(groupCare, client.getData(), groupActivity.getData(), user);

        // group is not yet verified
        assertGroupCare = groupCareManager.findByObjectId(groupCare.getObjectId());
        assertNull(assertGroupCare.getVerifiedAt());

        // verify the group
        groupCareManager.verifyGroupCare(user, groupCare);

        // assert that the group is verified
        assertGroupCare = groupCareManager.findByObjectId(groupCare.getObjectId());
        assertNotNull(assertGroupCare.getVerifiedAt());

        // add new client
        groupCareManager.addClient(groupCare, client2.getData(), groupActivity.getData(), user);

        // group is no longer verified
        assertGroupCare = groupCareManager.findByObjectId(groupCare.getObjectId());
        assertNull(assertGroupCare.getVerifiedAt());
    }

(more…)

Continue ReadingTo comment or not, that is the question