Friday 4 April 2014

Quick swing by JavaFX

Had a chance to poke around a small JavaFX application for the customer for a couple of days. Unfortunately i've been 'booked' for other work for the next few months so I'm still not getting as much of a chance to play with JavaFX as i'd hoped. Might be the last too (on that s/w) as this new work thrust on me is basically an unrelated graduate-level task in a graduate-level work environment, and that's the least of the issues with it (not too happy right now but i'll have to see how it transpires).

Anyway ... I'm still having issues with layouts although in my particular problem I think it came down to not realising that the scale pivot point is the centre of objects. I had inconsistent/jumping ui's as things changed so it just looked like a layout bug.

I had a few hours left after adding the required functionality so I thought i'd tart it up a bit with clipboard and then drag and drop support. Nice ... it's nice. Just simple and hides all the data-type negotiation and whatnot; something that made sense in 90s era computers without the memory (and also high hopes of extensive functionality) but now there's no real need for it (and dnd is mostly used for stupid things like editing text where it doesn't make sense because of it's clumsiness, and not for file opening where it does). One of those things were a really good style guide might have helped rather than a free-for-all.

As an example this function pointer (or method handle, or whatever it is) can just be added to any ImageView to make it draggable as a picture - e.g. to drop into a picture editor.

    static EventHandler<MouseEvent> dragImageView = (MouseEvent event) -> {
        ImageView iv = (ImageView) event.getSource();
        Image im = iv.getImage();
                
        if (im != null && im.getProgress() == 1) {
            Dragboard db = iv.startDragAndDrop(TransferMode.COPY);
            ClipboardContent cc = new ClipboardContent();

            cc.putImage(im);
            db.setContent(cc);
            event.consume();
        }
    };

    // any image view not in a list:
    iv.setOnDragDetected(dragImageView);

Dragging from lists has to go on the list not the imageview, though isn't much more work.

The clipboard is even a bit easier although I did some strange behaviour with it losing track of the content of the clipboard from another application if it the copy was done when the JavaFX application wasn't already running.

It doesn't seem to support the primary selection though which is a bit of a bummer. Not that most applications that use it do it properly any more :( You do have to stop highlighting the selection when you lose it!

I realised the last time I properly looked at cut and paste was about 15 years ago with gnome-terminal ... hmm.

Compositing

I'm still needing to use BufferedImage for I/O but one of the things I was worried about was whether I would still need to use it for composition. Looks like I don't and depending on how one feels about the javafx layout and blending stuff it offers "all the power" of that - as well as CSS. You just set up an off-screen scene and either snapshot that or one of it's components.

    Scene s = new Scene(root);
    WritableImage wi = s.snapshot(null);

If you want alpha to make it through to the output:

    s.setFill(Color.TRANSPARENT);
    root.setBackground(Background.EMPTY);

(actually that is pretty nice, and about time you're able to unify off-screen and on-screen layout and composition. And the api doesn't prevent the implementation using hardware to speed it up either).

One thing I found a little frustrating is the fact that none of the layout objects clip their content. This makes sense but it ended up not quite working properly when I added it to what I thought was the right place - suddenly all my alpha compositing simply stopped working. I had to wrap the container inside another one and just set the clip on the outer container that then when into a BorderPane or whatever it was. Around this time was when I was also having the strange jumping layout issues so that artificially inflated the frustration level.

So just as i'm starting to get the feel of it after a few short hours ... i'm pulled away again.

(Not that I can't work on something at home ... which i probably will once this parallella has run it's course).

Update: So the "real" customer had a look-see this week and apparently were pretty impressed. Not that the JavaFX had much to do with it but it didn't hurt i'm sure. As I said to the PM afterwards and I quote "they're probably used to seeing some matlab piece of shit that takes days to run" ... anyway I guess we'll see if any more money comes along. If so it could be quite interesting indeed - although again, not particularly for JavaFX related reasons.

No comments: