On Fri, 17 Apr 2026 10:12:22 GMT, Marius Hanl <[email protected]> wrote:
>> Hi,
>>
>> From what I can see this type of behavior is inherent for an implementation
>> in which when event is "fired" it is delivered right in place to listeners
>> like in below pseudo code:
>>
>> fireXXX()...
>> {
>> for each listener invoke onXXX(....)
>> }
>>
>> It is common for all awt and swing listeners and may, in plenty of
>> conditions when nested firing occurs, lead to change in ordering of events.
>> Yet, as far as I investigated it, and I did put a lot of work into it more
>> than decade ago, it is a nature of in-place events firing.
>>
>> As I do see it, the very crucial assumption behind in-place firing is:
>> _"when fireXXX returns, all listeners are notified"_. This is a strong
>> indication of state and data consistency and only in-place firing may do it.
>> Like in this pseudo code:
>>
>> my_function()
>> {
>> fireXXX()
>> _here I can assume that all listeners reacted to XXX_
>> fireYYY()
>> _here I can assume that all listeners reacted to XXX and YYY_
>> }
>>
>> I can assume it regardless if `my_function()` was invoked in response to
>> event or not.
>>
>> This assumption is in a strict and conceptual conflict with _"when fireXXX
>> is invoked the events reach all listeners in the same order as in which
>> events were fired even if events are fired from inside of listener event
>> handler"_.
>>
>> Because now if my example function is invoked inside a listener those
>> assumptions may be false.
>>
>> Any attempt to achieve the goal of delivering events in their order of
>> appearance will break the first assumption and it will lead to corruption of
>> existing programs. In many, many funny ways.
>>
>> Also any reliance on _"if listener A was registered before listener B, then
>> A will get called before B"_ is a horribly bad idea. Please, do not even try
>> to suggest it. Simply do not. There is no way to ensure that ordering in any
>> system of some major complexity.
>>
>> Any removing of "not necessary changes" in notification process is begging
>> for troubles. It did change, and it did changed again. Preventing that first
>> change from reaching the listeners is horrible idea, as listener is by
>> definition getting every change, not just "some".
>>
>> In my practice, if I am worried about nested events and ordering problem, I
>> do consciously decide to "decouple" them. Instead of firing an event in
>> place I do, consciously, wrap them and delegate to the event pump (in case
>> of awt - with invokeLater). Then I do know that they will reach the
>> destination in order of firing, but I also do now that at...
>
>> Also any reliance on _"if listener A was registered before listener B, then
>> A will get called before B"_ is a horribly bad idea. Please, do not even try
>> to suggest it. Simply do not. There is no way to ensure that ordering in any
>> system of some major complexity.
>
> This is the case right now and will be after this PR.
>
>> My recommendation is: if You really plan to change in-place firing to some
>> more sophisticated algorithm **do not do it**. Not in a stable production
>> code. Recommend, inform, educate about possible side effect, alternatively
>> add like "orderedFireXXX" methods or something, but do not change such an
>> essential algorithm. As you can see above delegation is a simple method
>> which allows programmers using the library to decide what is important from
>> them and what is not. If they see problems with ordering delegation solves
>> it. If however you will build it in, they will have no way to ensure that if
>> they have problems with:
>
> I still don't get your point. This is about nested changes and that the old
> value is misleading or simply incorrect. You talked about state consistency,
> but currently, this can happen:
>
>
> myProperty.addListener((_, oldValue, newValue) -> {
> // Here, oldValue MIGHT not be the last set value, but the value before
> that.
> // Instead of A -> B -> C
> // oldValue can be A and newValue be C. Which is very bad when you want
> to remove/unregister the old value.
> }
>
> This PR corrects that to BE consistent, so the `oldValue` will be B in this
> example. This is consistency for me.
@Maran23
Thanks for through consideration.
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1081#issuecomment-4295832153