Johan's blog
JavaFX 1.2 asynchronous chat client
A couple of months ago, I wrote a JavaFX chat client using JavaFX 1.1 --- see my previous blog entry. The article below describes the changes that are needed to port this chat client to JavaFX 1.2.The main difficulty in the JavaFX 1.1 chat client was to get the asynchronous stuff working: we have an open connection towards the chatserver, and new chatentries from all clients are pushed through this connection to the JavaFX client. Clearly, we cannot block the Event Dispatching Thread for achieving this. Starting a new Thread in JavaFX and realizing a non-blocking communication between this thread and the EDT was not trivial in JavaFX 1.1, but the chat client that was discussed in my old blog entry did the job.
The changes between JavaFX 1.1 and JavaFX 1.2 are described here and indeed, the asynchronous functionality has changed considerably.
Some general information about the JavaFX 1.2 Async model can be found in this blog entry from Baechul. In short, the most important changes are:
- javafx.async.AbstractAsyncOperation disappeared, and javafx.async.JavaTaskBase is introduced
- a RunnableFuture interface is introduced.
The architecture
The core idea that I used in the ChatClient, is still valid in JavaFX 1.2: a JavaFX class is used to create an instance of a Java thread, and this thread contains a backpointer to the JavaFX model.The following diagram is therefore still valid in JavaFX 1.2:
The code
The chatclient code that works in JavaFX 1.2 is available as a NetBeans project file here.Remember that you need to run a chat-server as well, if you want to run the example. The dummy server we are using is the same as the one we use in the JavaFX 1.1 example. You can get this chatserver as a NetBeans project file as well here.
The changes
Below are the changes I had to make to my previous version of the JavaFX Chat Client in order to make it compile and run in JavaFX 1.2- The
AsyncReaderclass extendedcom.sun.javafx.runtime.async.AbstractAsyncOperationin the 1. 1 version. That concept is being replaced by thejavafx.async.RunnableFutureinterface. Hence, we havepublic class AsyncReader implements RunnableFuture
TheRunnableFutureinterface has apublic void run()method that we should implement. In the oldAbstractAsyncOperationclass, the run-logic was in thecallmethod. Instead ofpublic Object call() throws Exception
we now havepublic void run() throws Exception
- We don't have the
com.sun.javafx.runtime.async.AsyncOperationListenerclass anymore, so the constructor for the AsyncReader simply becomespublic AsyncReader(ChatInput callback) {this.callback = callback;
}
Note that the callback parameter is a Java interface that is implemented by theChatHistoryBox.fxclass. This allows the java classAsyncReaderto call into the JavaFX classChatHistoryBox. - Since
javafx.async.AbstractAsyncOperationis more or less replaced byJavaTaskBase, theChatReader.fxclass now extendsJavaTaskBase JavaTaskBaserequires a create-method. This method is called by the start() method, and it should return aRunnableFutureinstance. This is more or less what we did before in the start() method of theAbstractAsyncOperation, hence we transformed the behavior of old start() method into the new create() method. The create() method creates anAsyncReaderinstance (a Java object implementingRunnableFuture) and returns this.- The same changes should be applied to
AsyncWriterandChatWriter - When a new textentry is received by the
AsyncReader, we used the invokeLater() Swing method for notifying the EDT of changes that should be made. It is recommended to use theJavaFX.deferActionfor this, though:javafx.lang.FX.deferAction(new Function0() {public Void invoke() {callback.gotText(oneline);
return null;
}
});
- We have to start the
ChatReaderby calling the start method. This is done in Main.fx, after the ChatReader has been created. - Similarly, when a new text-entry has been submitted by the user, a
ChatWriterinstance needs to be created and started.Conclusion
The JavaFX 1.2 asynchronous model is not completely different from the JavaFX 1.1 model. Somecom.sunspecific classes have been replaced byjavafxclasses, which is good of course. The communication from the Java class back into the javaFX EDT, usingFX.deferActioncan probably be simplified in future releases.

