UIThread abstraction

UIThread abstraction

Administrator

Hello everyone,

The topic of abstracting over the UI thread has surfaced a couple of times. Allow me to share my thoughts on the matter.

I think we can agree there are 3 major UI toolkits in the JVM: Swing, JavaFX and SWT. These are the toolkits that most developers are familiar with, their quirks are well understood and their communities are big enough. Next we have the lesser used/known toolkits that still deliver some punch: Apache Pivot, Lanterna and Qt (yes, Qt is well known outside of the JVM but not so much inside it). These six toolkits can be used in all major desktop platforms; I believe JavaFX and Lanterna are the only choices in embedded Java at the moment (Swing on a Raspberry Pi perhaps?). Finally we've got jGTK which runs on Linux only. There are other UI toolkits (mostly coming form the gaming community) but their usage is very limited.

All these toolkits follow simple rules:

there's a dedicated thread (the UI thread) where painting operations must happen.

widgets must be created inside the UI thread.

widget properties must be accessed and mutated inside the UI thread.

non-UI related operations must happen outside of the UI thread.

Almost all of them provide the facilities to run code inside their UI thread in a synchronous/asynchronous manner. They can identify the UI thread too. Here's the breakdown

For some odd reason JavaFX chose not to provide a sync version, however it can be implemented using a FutureTask. This leaves Lanterna as the other odd toolkit that does not deliver async, but given its inherent nature this operation can be delivered over sync as is. I'm not counting Qt as its JVM support (Qtjambi) is lagging behind and it does not make releases so often these days.

This leads us with very good chances of defining a base abstraction over the UI thread, no matter the UI toolkit. Sven pointed out on another thread that there may be a problem with mixed toolkits as each one will use its own UI thread. Well, this is not a problem in Java8 as Swing and JavaFX can share the same thread. Turns out JavaFX and SWT can share the same thread too. Thus all 3 toolkits can share the same thread. Win! In a mixed environment one of the toolkits has to take the lead, that is, Swing components are embedded in JavaFX or viceversa. One of these toolkits initializes the UI environment and the other submits to its will.

Re: UIThread abstraction

Generally speaking I'm not sure you should add synchronous/blocking APIs they should be avoided at all cost. Synchronous APIs can easily lead to deadlocks (that's the reason the JavaFX lacks this API) and blocking APIs are bad as well because they are hard to implement in Browser JavaScripts envs (yes I know we talk about Desktop & Mobile) who are async.

So whenever you design an API like this int state = window.open(); think twice if you would not be better of with window.open(Function<Integer,Boolean> handlerFunction);

Re: UIThread abstraction

Tom Schindl wrote

Generally speaking I'm not sure you should add synchronous/blocking APIs they should be avoided at all cost. Synchronous APIs can easily lead to deadlocks (that's the reason the JavaFX lacks this API) and blocking APIs are bad as well because they are hard to implement in Browser JavaScripts envs (yes I know we talk about Desktop & Mobile) who are async.

I think it's important to define a sync call because some toolkits and frameworks depend on it. I'm with you that developers should try to use callbacks instead of blocking calls.

Tom Schindl wrote

So whenever you design an API like this int state = window.open(); think twice if you would not be better of with window.open(Function<Integer,Boolean> handlerFunction);

I think we should use callbacks and non blocking calls in the JSR for example when loading or storing application states.

Mostly all toolkits define the 3 base methods and most frameworks (like e4) defines more than only the 3 methods. Maybe we can split the concurrency definition of the JSR in 2 parts: Toolkit concurrency and framework concurrency. Toolkit concurrency is defined by an interface that only contains the 3 core methods. Based on this methods the framework concurrency defines some util methods that are based on the toolkit concurrency by using default implementations.

Re: UIThread abstraction

Administrator

As Hendrik notes, keeping the sync option allows full access to the underlying toolkit's UI thread. The fact that JavaFX (1 of the 6 considered toolkits) decided against this behavior should IMHO not weight too much in favor of removing said method. Sync calls are terrible in the hands of an inexpert developer, and so are async calls. I think sync calls are well understood by power developers and as such I wouldn't take it away.

It's like running with scissors; you know you'll get hurt if you do, so simply don't run or leave the scissors behind. Protecting people against running with scissors is a matter of education, not banning the usage of scissors or running ;-)

Re: UIThread abstraction

I'm not in favor.

It is much easier to add a call to the spec later than to remove a call.

As for the sync option: it is possible to do this yourself (e.g. using a Future) without it being in the spec. So it's not that you don't allow people to use this weird thing, you simply don't encourage it via the shared API.

I agree with your statement that inexpert developers can ruin everything even with async calls (also expert developers btw), but you shouldn't make it too easy to fail :)

As Hendrik notes, keeping the sync option allows full access to the underlying toolkit's UI thread. The fact that JavaFX (1 of the 6 considered toolkits) decided against this behavior should IMHO not weight too much in favor of removing said method. Sync calls are terrible in the hands of an inexpert developer, and so are async calls. I think sync calls are well understood by power developers and as such I wouldn't take it away.

It's like running with scissors; you know you'll get hurt if you do, so simply don't run or leave the scissors behind. Protecting people against running with scissors is a matter of education, not banning the usage of scissors or running ;-)

If you reply to this email, your message will be added to the discussion below:

Re: UIThread abstraction

I agree with Johan - as long as there's the async one available one can implement a sync one, e.g. by providing an additional library outside the JSR scope people can make use of, similar to what Hendrik did for javafx and we did as well as part of e(fx)clipse.

Re: UIThread abstraction

Administrator

Fair enough. I think we can begin fleshing out thew API without a sync abstraction and see how far we go.
I still think there will be cases where a developer really needs to issue a sync call, in which case he or she will have to either

I agree with Johan - as long as there's the async one available one can implement a sync one, e.g. by providing an additional library outside the JSR scope people can make use of, similar to what Hendrik did for javafx and we did as well as part of e(fx)clipse.

If you reply to this email, your message will be added to the discussion below: