Me and Oscar is currently working on a small project, just to learn JavaFX.
We stumbled on some nasty crashes which we at first did not understand.
ArrayIndexOutOfBoundsException? Is there a bug in JavaFX?
It turned out to be a callback from Java. Let us see how we got there.
The application we are doing is based on Crisp’s famous planning poker cards. They are great but you need to be in the same room. So we thought, why not do an online version for those teams that are geographically disperse?
The table has room for you and 8 other players. As you see from the picture, there is also a text chat to the right. At the same time, a small bubble appears by the card of the player that wrote in the chat. The bubble fades away after a ten seconds, unless the player makes another comment within that time. In that case, the latter comment is added to the bubble and it was here our problems showed up.
The chat is using a standard protocol, XMPP, to talk to the server. We don’t have to provide our own server, any chat server that speaks XMPP will do, e.g. jabber.org. Of course, all players need to have an account there.
Here is a strength that JavaFX has as newcomer, you can use existing Java libraries.
We found Smack that talks XMPP and did a small test in Java to see that we had understood it.
Now, how do one provide a JavaFX class that receives callbacks from Java? Each time there is a message from the chat, Smack will call your PacketListener. That is an interface and JavaFX does not have interfaces. It turned out to be so straightforward, however. Just extend the PacketListener interface as if it had been a class.
Here is a code snippet:
So we override the function that gives us the packet. Now comes the crucial part, the callback is done on its own thread. JavaFX has a single thread model for everything in the GUI and that code is not thread safe.
In our case we wished to display a bubble if there was none, or add to an existing one.
You should not do that. You should wait in line for your turn. Or something nasty may happen.
Remember Swing’s invokeLater? Here we need to say FX.deferAction. But in JavaFX we can pass functions as arguments. So here goes that part of the code.
You may also note that we use the chat channel to send commands.
So if you remember the threads, it is safe to have a callback from Java to your JavaFX code.