Bug: Not on FX application thread exception is inconsistent

Ty Young youngty1997 at gmail.com
Tue Nov 13 11:05:54 UTC 2018


On 11/13/18 12:12 AM, Tom Schindl wrote:
> I'm sorry that I'm the one to bring you the bad news that you need to do
> the work and can't offload multi-threading to JavaFX.
>
> I already explain why it *seems* to work one some elements (until it
> breaks like shown in the bug-report I referenced) and for others it
> breaks immediately because they somehow call out to native APIs (like
> win32, ...) and hence are guarded with checks.
>
> I can simply say it won't work and it won't change (well I'm not the one
> in charge of such a decision but I frankly can't believe it will). You
> are the one supposed to deal with this like you have to deal with that
> in Swing, Qt, WPF, Win32-API, Cocoa-API, Gtk, ... - you need to sync
> yourself back to the UI-Thread if you want to access resources.
>
> You are right. If there are many updates from the backend-system you
> would queue a lot of Runnables using Platform.runLater() who can get you
> in trouble.
>
> There are others ways to sync back to the JavaFX UI-Thread but
> Platform.runLater() is the simplest with the least amount of work and
> until you run into problems you should stick to that.


Because everything is ran in different places and there is no built-in 
way to wait for the runnable to finish, some GUI code that notifies the 
user of an API object's change breaks because the object hasn't been 
updated yet.


>
> This is my last reply in this thread, as there's nothing more to say on
> this topic from my side, there are many resources out there discussing
> Platform.runLater and friends but that's something you can (and could
> have) googled for and anyways looks like you don't want to listen.


All Google turns up is Platform.runLater and Platform.runAndWait. 
Platform.runAndWait isn't even publicly usable unless I edit the source 
and make it public. I knew using Platform.runLater was going to cause 
problems which is why I really didn't want to use it to begin with.


This isn't me not doing my research, this is objectively JavaFX not 
providing the functionality that is necessary to do something rather 
trivial: update an API object and provide information from that API 
object right after it's updated to the user(without ChangeListener).


I understand that there may be very technical reasons for not making it 
public, however it is still *majorly* problematic that it doesn't exist. 
Not being able to tell when a runnable has finished executing(besides 
ChangeListeners) is a big deal.

>
> Tom




> On 13.11.18 05:38, Ty Young wrote:
>> On 11/12/18 9:12 PM, Brian Hudson wrote:
>>> JavaFX like every other modern UI framework is single threaded.
>>
>> Which in itself is fine, running *just* the UI isn't much on modern
>> processors. Adding a bunch of API object updates that cause thread
>> slowdown to the mix that can cause UI stuttering is, again, asking for
>> trouble.
>>
>>
>> And how is TableView, Slider, TextField, etc all working just fine but
>> ComboBox freaks out? What's so special about ComboBox? Is there some
>> hack I can do to not trigger the exception?
>>
>>
>>> The updating of your “API objects” can and should remain on a
>>> background thread, however once updated the changes which trigger an
>>> update to your UI (changing a value in a bound property) should occur
>>> on the JavaFX thread via Platform.runLater for example.
>>>
>> Doing all this is just messy, inefficient, and duplicating code. It
>> would involve creating Runnable implementations that does about 10 lines
>> of code with objects that get updated as fast as they can be with
>> different object types, resulting in more threads and garbage being
>> created. Using generic magic isn't really a solution either because
>> different API objects convert data from String to some other type
>> depending on the implementation.
>>
>>
>> Would it not be possible to have a runPlatformListener method that just
>> runs the ChangeListener on the platform thread automatically? It would
>> reduce the amount of garbage dramatically since JavaFX only ever fires a
>> change event if the object is itself different(in other words, if the
>> current value is 0 and the new value is 0, there is no change) which is
>> nice and efficient.
>>
>>
>>> Also, take the attitude down a notch or two.
>>>
>>> Brian
>>>
>>>
>>> On Mon, Nov 12, 2018 at 10:02 PM Ty Young <youngty1997 at gmail.com
>>> <mailto:youngty1997 at gmail.com>> wrote:
>>>
>>>
>>>      On 11/12/18 5:39 PM, Tom Schindl wrote:
>>>      > Hi,
>>>      >
>>>      > You are supposed to interact with Nodes who are currently shown
>>>      in the
>>>      > SG only only the JavaFX Application Thread.
>>>
>>>
>>>      I never touch the GUI in my other threads, ever. The threads simply
>>>      change the value of a type stored in a property. The
>>>      ChangeListener that
>>>      is used is created in the GUI JavaFX thread.
>>>
>>>
>>>      >
>>>      > JavaFX although is not checking each and every property (change)
>>>      as this
>>>      > would be too resource intensive but at sensitive cases (eg when
>>>      > interacting with Glass) it does check that you run on the
>>>      correct thread.
>>>
>>>
>>>      The update process for updating my API objects is slow(for reasons
>>>      beyond my control), so even assuming I somehow manage to magically
>>>      update everything in the GUI thread, how the hell do you fix the GUI
>>>      stuttering at that point?
>>>
>>>
>>>      Really, having an entire application do all of it's processing on one
>>>      thread in 2018 is really just idiotic and asking for trouble.
>>>
>>>
>>>      >
>>>      > Even though your TableView, ... updates seem to work you can run
>>>      into
>>>      > disasterous states - see eg
>>>      https://bugs.openjdk.java.net/browse/JDK-8198577
>>>      >
>>>      > Tom
>>>
>>>
>>>      I'm not sure what the bug is about since the description really
>>>      doesn't
>>>      give much info however I really haven't noticed anything, even
>>>      long term
>>>      with it being open for 8+ hours. These objects are update very
>>>      frequently as well.
>>>
>>>
>>>      To be clear, this isn't some business application that gets info
>>>      from a
>>>      database or something.
>>>
>>>
>>>      > On 10.11.18 06:58, Ty Young wrote:
>>>      >> Hi,
>>>      >>
>>>      >>
>>>      >> My JavaFX program updates API objects in the background via a
>>>      non FX
>>>      >> thread that, when changed by another program, are reflected in
>>>      my JavaFX
>>>      >> GUI's controls by property binding, specifically TableView,
>>> Slider,
>>>      >> TextField, and ComboBox. Problem is, while JavaFX is OK with
>>>      this for
>>>      >> TableView, Slider, and TextField, it throws a Not on FX
>>> application
>>>      >> thread exception *only* for the ComboBox.
>>>      >>
>>>      >>
>>>      >> The code for the slider looks like this:
>>>      >>
>>>      >>      private class ValueListener implements
>>> ChangeListener<Integer>
>>>      >>      {
>>>      >>          @Override
>>>      >>          public void changed(ObservableValue<? extends Integer>
>>>      >> observable, Integer oldValue, Integer newValue)
>>>      >>          {
>>>      >>              slider.getSlider().setValue(newValue);
>>>      >> slider.getTextBox().setText(newValue.toString());
>>>      >>          }
>>>      >>      }
>>>      >>
>>>      >>
>>>      >> (the slider variable is misleading, it's actually a VBox that
>>>      contains a
>>>      >> Slider and a TextField. Need to change it but I digress.)
>>>      >>
>>>      >>
>>>      >> which works fine. However this:
>>>      >>
>>>      >>
>>>      >>      private class ValueListener implements ChangeListener<E>
>>>      >>      {
>>>      >>          @Override
>>>      >>          public void changed(ObservableValue<? extends E>
>>>      observable, E
>>>      >> oldValue, E newValue)
>>>      >>          {
>>>      >>              combo.setValue(newValue);
>>>      >>          }
>>>      >>      }
>>>      >>
>>>      >>
>>>      >> doesn't for the ComboBox.
>>>      >>
>>>      >>
>>>      >> Is this a bug or is there some legitimate invisible reason as
>>>      to why the
>>>      >> slider/textfield isn't throwing an error but the combobox one is?
>>>      >>
>>>      >>
>>>      >>
>>>


More information about the openjfx-dev mailing list