FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

JavaFX links of the week, February 1

I know I say this often – but we’re already a month down into 2016. Where does time go!?! Well, obviously a lot of it goes into what people are doing in the links below, so we really owe them all a debt of gratitude and a little of our time to read what they’re up to. Enjoy 🙂

JavaFX links of the week, January 25

Half a day late, but it was a public holiday today, so I was out enjoying the sun! 🙂 On with the links…

JavaFX links of the week, January 18

JavaFX links of the week, January 11

January 11, 2016 – the day before my birthday! 🙂 I hope everyone had a great festive break and took the opportunity to recharge their batteries. I know I did! However, because I was away from the web (and literally without access for a number of days), I’ve certainly failed to capture all links over the last few weeks. If I missed anything ping me to let me know, and I’ll include it next week. Let’s get on with the links – enjoy 🙂

  • One of the big things to happen over the holidays was the announcement that Android is moving away from Apache Harmony and will be switching to OpenJDK. Many posts about this topic managed to get a lot of the concepts muddled. The Gluon blog has a summary that appears fairly accurate, given the fact that a lot remains unknown about the likely outcomes of this change.
  • Speaking of Gluon, there is an interview on their website with Neil Matatall about Brakeman Pro 1.0 being released. Interestingly it is a commercial JavaFX application built with JRuby.
  • I did a blog post about node picking in JavaFX. This is a topic I see asked about very frequently, and I had just recently written some code to do this. Hopefully it is helpful for someone else – although hopefully most people will have managed to write it themselves – it isn’t very complex! 🙂
  • Voxxed posted a short video with Johan Vos from Gluon about ‘Reasons to Get Excited About Java on Mobile‘.
  • Dirk Lemmermann has posted about the power of CSS in JavaFX. He has also created a YouTube playlist of JavaFX applications in the ‘real world’. It’s great to see some JavaFX applications coming out from behind the curtains – I see some really great stuff in my travels, and it is a shame that not more of it is shown publicly. These kinds of efforts are great!
  • Gerrit Grunwald has been busy working on (yet another!) gauge library, this time called Medusa. As always they look excellent, so take a look if you are wanting to put some gauges in your applications.
  • Jens Deters has released FontAwesomeFX 8.8, which fixes a few issues and adds a number of weather icons to the mix.
  • Speaking of icon packs, Andres Almiray has also released an API for using them, which he calls Ikonli.
  • Recently I was notified of TuioFX by a few of the developers. This is a project that ‘simplifies the development of cross-platform applications for multi-touch, multi-user interactive tabletops and surfaces.’
  • Robert Ladstätter has posted about fx-tictactoe – A TicTacToe application built using JavaFX and Scala.
  • Carl has posted about ‘Ground Floor or Ground Zero? Why I’m Bullish on JavaFX in 2016‘.

Node Picking in JavaFX

This is a little bit novel – using FXExperience for a post that isn’t the weekly links! 🙂 I wish I could post here more often, but time constraints pretty much stop that in its tracks (even the weekly links take longer than I would like). Anyway, I often get asked about node picking in JavaFX, and if the Node.impl_pickNode(...) API will ever lose the ‘impl’ and become proper API.

The answer is: I don’t know – picking API is not ‘mine’ to worry about. Frankly, I’m barely qualified to discuss picking in any depth, as it is not something I use. Despite this, I will give my unqualified summary for those of you who are unfamiliar with what picking is: it is basically about getting the best matching (i.e. top-most) Node under a given x, y coordinate.

A few months back I was working in the Scene Builder code base to remove dependencies on these impl methods (and to generally clean it up to work on JDK 9 given all the changes due to project Jigsaw (i.e. modularity) and new APIs in JavaFX 9). One thing I had to replace was the use of Node.impl_pickNode(...). I ended up writing the code below, and given that I’m asked about this functionality a lot, I thought I would post it here in case others found it useful.

I should be very clear that this is not a performant implementation, and it is built with my naivety regarding picking (so I am happy to be sent suggestions for improving it). Nevertheless, I hope it helps.

public static Node pick(Node node, double sceneX, double sceneY) {
    Point2D p = node.sceneToLocal(sceneX, sceneY, true /* rootScene */);

    // check if the given node has the point inside it, or else we drop out
    if (!node.contains(p)) return null;

    // at this point we know that _at least_ the given node is a valid
    // answer to the given point, so we will return that if we don't find
    // a better child option
    if (node instanceof Parent) {
        // we iterate through all children in reverse order, and stop when we find a match.
        // We do this as we know the elements at the end of the list have a higher
        // z-order, and are therefore the better match, compared to children that
        // might also intersect (but that would be underneath the element).
        Node bestMatchingChild = null;
        List<Node> children = ((Parent)node).getChildrenUnmodifiable();
        for (int i = children.size() - 1; i >= 0; i--) {
            Node child = children.get(i);
            p = child.sceneToLocal(sceneX, sceneY, true /* rootScene */);
            if (child.isVisible() && !child.isMouseTransparent() && child.contains(p)) {
                bestMatchingChild = child;
                break;
            }
        }

        if (bestMatchingChild != null) {
            return pick(bestMatchingChild, sceneX, sceneY);
        }
    }

    return node;
}