Re: Is it possible to disable JavaFX shutdown hook?

2024-07-26 Thread Jurgen Doll

Hi Pavel

Not sure if this will help in your situation but you can try using  
"primaryStage.setOnCloseRequest" where you can run any cleanup code needed.


If you want to cancel the close request completely then just consume the  
WindowEvent and then later issue Platform.exit() when ready.


Regards
Jurgen


On Thu, 25 Jul 2024 17:43:25 +0200, PavelTurk   
wrote:



Hello all.

JavaFX adds its own shutdown hook. That gives many problems when it is  
necessary to work with application,
when system is shutting down, for example, if user presses CTRL+C. The  
first problem I described here -

https://bugs.openjdk.org/browse/JDK-8320923

Another problem is that after pressing CTRL+C JavaFX seems not to  
respond anymore. For example I've
observed that if after that we try to do Platform.runLater(() -> myCode  
is here), then myCode will never execute.
So, it is necessary to check in system, how it is shutting down, if it  
is. And this problem creates other problems.


Before opening a feature request, I decided to ask JavaFX developers, if  
it possible to disable JavaFX shutdown hook.
I mean, if there is no system property (something like  
javafx.shutdownhook.disabled), it will be added, but if I want
to call Platform.exit() manually I want to be able to disable JavaFX  
shutdown hook.


Best regards, Pavel


Re: RFR: 8289115: Touch events is not dispatched after upgrade to JAVAFX17+

2024-07-01 Thread Jurgen Doll

Thank you Michael, Jose, Florian, and Markus

In my mind the "Too many touch points reported" exception fix (#394)  
appears to not be the correct fix for that issue and is what caused this  
regression.


There seems to be two possible paths forward, either revert #394 or  
integrate this. In both cases the "Too many touch points reported" issue  
will need to be readdressed.


It would be nice to see this move forward somehow.

Thanks again,
Jurgen


On Tue, 04 Jun 2024 18:28:47 +0200, Markus Mack  wrote:

On Tue, 21 May 2024 14:25:51 GMT, Michael Strauß   
wrote:


This PR fixes a bug  
([JDK-8289115](https://bugs.openjdk.org/browse/JDK-8289115)) that was  
introduced with #394, which changed the following line in the  
`NotifyTouchInput` function (ViewContainer.cpp):


- const bool isDirect = true;
+ const bool isDirect = IsTouchEvent();


`IsTouchEvent` is a small utility function that uses the Windows SDK  
function `GetMessageExtraInfo` to distinguish between mouse events and  
pen events as described in this article:  
https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages


I think that using this function to distinguish between touchscreen  
events and pen events is erroneous. The linked article states:
_"When your application receives a **mouse message** (such as  
WM_LBUTTONDOWN) [...]"_


But we are not receiving a mouse message in `NotifyTouchInput`, we are  
receiving a `WM_TOUCH` message.
I couldn't find any information on whether this API usage is also  
supported for `WM_TOUCH` messages, but my testing shows that that's  
probably not the case (I tested this with a XPS 15 touchscreen laptop,  
where `GetMessageExtraInfo` returns 0 for `WM_TOUCH` messages).


My suggestion is to check the `TOUCHEVENTF_PEN` flag of the  
`TOUCHINPUT` structure instead:


const bool isDirect = (ti->dwFlags & TOUCHEVENTF_PEN) == 0;


I attempted to test this with the sample app in  
[JDK-8249737](https://bugs.openjdk.org/browse/JDK-8249737) and  
[Microsoft.Windows.Simulator](https://stackoverflow.com/questions/40274660/windows-10-how-do-i-test-touch-events-without-a-touchscreen)

using the simulator's "Basic touch mode".

The "Too many touch points reported" exception seems to be thrown  
consistently with

`const bool isDirect = true;` (original before #394)
and `const bool isDirect = (ti->dwFlags & TOUCHEVENTF_PEN) == 0;` (this  
PR)


I didn't see the exception with `const bool isDirect = IsTouchEvent();`  
(#394)
and `const bool isDirect = false` (which is probably what IsTouchEvent()  
returns here).


Not sure what this simulator actually sends, but someone more  
knowledgeable might want to have a look at what's happening.


-

PR Comment: https://git.openjdk.org/jfx/pull/1459#issuecomment-2147933056


Touch events are not dispatched after upgrade to JavaFX 17

2024-05-21 Thread Jurgen Doll

Hi All

Can JDK-8289115  (Touch events are not dispatched after upgrade to JavaFX  
17) please get some attention again for the next release.


Thanks, regards
Jurgen

Re: Integrated: 8324658: Allow animation play/start/stop/pause methods to be called on any thread

2024-02-01 Thread Jurgen Doll



A big THANK YOU to everybody that was part of this process.
It's very much appreciated !

Regards
Jurgen


On Tue, 30 Jan 2024 11:27:44 +0200, Nir Lisker  wrote:


On Fri, 26 Jan 2024 23:59:50 GMT, Nir Lisker  wrote:

Added a utility method to run code on the FX thread if it's not  
already, and changed the animation methods to use it.


This pull request has now been integrated.

Changeset: c5ab220b
Author:Nir Lisker 
URL:
https://git.openjdk.org/jfx/commit/c5ab220bbc885f2aa99d8c1d5ed8f1753e39251f

Stats: 422 lines in 7 files changed: 225 ins; 148 del; 49 mod

8324658: Allow animation play/start/stop/pause methods to be called on  
any thread


Reviewed-by: kcr, jpereda

-

PR: https://git.openjdk.org/jfx/pull/1352


Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE

2024-01-24 Thread Jurgen Doll

Hi Kevin

If I may make one more final appeal then to an alternative solution please.

Could we then instead of throwing an Exception rather invoke runLater if  
needed inside play, stop, and resume.


Putting the onus on the developer is fine if it is the developer that is  
invoking the call, but if it's in a library then it's a no go.


In my application I have two libraries that I know of where this happens.  
The major problem is that with FX22 as it now stands my application just  
crashes because play() does an FX thread check and throws an Exception  
which it never did before. There are bound to be other applications out  
there that are going to find themselves in a similar position.


PLEASE !

Regards
Jurgen



On Wed, 24 Jan 2024 15:15:31 +0200, Kevin Rushforth  
 wrote:


Thank you to Jurgen for raising the question and to Nir, John, and  
Michael for evaluating it.


I conclude that there is insufficient motivation to revert the change in  
behavior implemented by JDK-8159048 to allow calling the  
play/>pause/stop methods of Animation on a background thread. Doing so  
without making it fully multi-thread-safe would be asking for problems,  
>and making it fully multi-thread-safe would be a fair bit of work to do  
it right without a clear benefit.


We will proceed with the current approach and let JDK-8159048 stand.  
Further, we will proceed with  
https://bugs.openjdk.org/browse/>JDK-8324219 which is under review in  
https://github.com/openjdk/jfx/pull/1342


-- Kevin

On 1/24/2024 12:30 AM, Nir Lisker wrote:
After playing around with the code sample, I think that this is not the  
right way to use the animation. The reason is that there is >>no point  
in starting the animation before the control is attached to the  
scenegraph, or even made visible. A small refactoring >>where, e.g.,  
the controller class exposes a method to start the animation in  
onSucceeded or just calls it on the FX thread is >>enough. I never  
start an animation as part of the construction because it's not the  
right time. John suggested tying the lifecycle >>of the animation to  
the showing of the node, which also solves the problem.  
There are animations like PauseTransition or other non-interfering  
Timelines that could reasonably be run on a background >>thread. Or  
maybe just on an unconnected control. This could be a reason to not  
limit animation methods to the FX thread at >>the expense of possible  
user errors, but document the pitfall.


I don't see a good use case for modifying controls in a background  
thread while still interacting with the scenegraph, hence for >>adding  
multithread support.

- Nir

On Mon, Jan 22, 2024, 12:59 Jurgen Doll  wrote:

Here's an example as requested by Nir:


public class FxTimeLineTest extends Application


{

   private BorderPane bp = new BorderPane( new Label("Loading") );



   public static void main( String[] args ) {

   launch( FxTimeLineTest.class, args );

   }



   @Override

   public void start( Stage primaryStage ) throws Exception {

   new Thread( new LoadScene() ).start();

   primaryStage.setScene(new Scene( bp, 300, 200 ) );

   primaryStage.setTitle( "Memory Usage" );

   primaryStage.show();

   }



   private class LoadScene extends Task {

   @Override protected Parent call() throws Exception {

   Parent p = FXMLLoader.load( getClass(
).getResource("TestView.fxml") );

   Thread.sleep( 1000 );

   return p;

   }



   @Override protected void succeeded() {

   bp.setCenter( getValue() );

   }



   @Override protected void failed() {

   getException().printStackTrace();

   }

   }

}


--


public class TestView

{

   @FXML private Label memory;



   private static final double  MEGABYTE = 1024 * 1024;



   @FXML private void initialize()

   {

   var updater = new Timeline

   (

   new K
eyFrame( Duration.seconds(2.5), event ->

   {

   var runtime = Runtime.getRuntime();

   double maxMemory = runtime.maxMemory() / MEGABYTE;

   double usedMemory = (runtime.totalMemory() -  
runtime.freeMemory()) / MEGABYTE;


   memory.setText( (int) usedMemory + " MB / " + (int)  
maxMemory +" MB" );


   })

   );



   updater.setCycleCount(Animation.INDEFINITE);
   // This FXML is being loaded on a background thread

   updater.play();

   }

}


--

TestView.fxml











http://javafx.com/fxml/1";  
fx:controller="TestView">


  

 



 

  





On Sat, 20 Jan 2024 17:08:41 +0200, Nir Li

Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE

2024-01-24 Thread Jurgen Doll

Hi John

Thank you for the hypothetical receivers array scenario, I think it  
explains the problem exactly and is why replacing the array with  
CopyOnWriteArrayList removes the NPE.


Your perspective then is that AbstractPrimaryTimer is designed for single  
threaded use only. If that is indeed so, then could you please explain the  
purpose of the receiversLocked and animationTimersLocked flags, as well as  
the point of receivers.clone() and animationTimers.clone() all of which  
indicate to the contrary.


Thanks, regards
Jurgen


On Tue, 23 Jan 2024 18:36:16 +0200, John Hendrikx  
 wrote:



On 23/01/2024 16:56, Jurgen Doll wrote:

Hi John and others,

I don't think we are entirely on the same page, so here's the  
objective.


The Goal: To determine if the FX animation thread and a SINGLE other  
thread can access Animation in a >>safe manner wrt play, stop, and  
resume.
The number of threads is irrelevant really, it's either thread safe or  
it isn't.


Non Goal: Multi-threaded access of Animation play, stop, and resume  
is NOT a goal.


Wrt play() and resume(), it is ALWAYS safe to call them on a background  
thread because at this point the >>Animation isn't being processed by  
the FX thread as the "Animation" isn't contained in the  
>>AbstractPrimaryTimer receivers array.


I'm afraid that is incorrect.  The fact that your animation is not  
running doesn't mean that AbstractPrimaryTimer isn't in use by other  
>animations that are running.  These other animations are using the  
receivers array, and may be modifying it or reading from it from the FX  
>thread.


When you start your animation on a different thread, you are accessing  
these fields with a different thread, and modifying them.  Since the  
>JVM is free to cache values and do other fancy things (like reordering  
read/writes) in the absence of synchronized/locking, there is no  
>guarantee that the FX thread will see those modifications until these  
are flushed to main memory (or caches are synced).  Even then, the FX  
>thread may have these values cached somewhere, and so it may not go all  
the way to main memory to see if its assumptions are now >incorrect.   
The only way to ensure this is with proper use of synchronization.


So a hypothetical scenario:

- AbstractPrimaryTimer has no receivers
- A receiver is added via the FX thread, slot 0 is now filled and  
receiversLength is now 1.  Due to cache lines being large, it also read  
slot 1 >(which is null)
- You start your animation on another thread.  Since you didn't see the  
receivers array yet, you may see one of these states:
   - The change from the FX thread was flushed to main memory, and you  
see [X, null] and receiversLength = 1
   - The change from the FX thread was partially flushed, and you see  
[X, null]  and receiversLength = 0 (!!)
   - Nothing was flushed yet, and you see [null, null] and  
receiversLength = 0


Now, you can see that it would be very dangerous to proceed to modify  
the array based on half flushed information.  Something similar >happens  
when you are the first to start an animation, and then another is  
started later.  If the changes of your thread are not flushed yet (or  
>partially) then the FX thread will act on partially flushed data, or  
even see no receivers yet at all...


--John

Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE

2024-01-23 Thread Jurgen Doll

Hi John and others,

I don't think we are entirely on the same page, so here's the objective.

The Goal: To determine if the FX animation thread and a SINGLE other  
thread can access Animation in a safe manner wrt play, stop, and resume.


Non Goal: Multi-threaded access of Animation play, stop, and resume is NOT  
a goal.


Wrt play() and resume(), it is ALWAYS safe to call them on a background  
thread because at this point the Animation isn't being processed by the FX  
thread as the "Animation" isn't contained in the AbstractPrimaryTimer  
receivers array.


Wrt stop() from what I can tell there are no shared method calls that need  
synchronization (see audit below), however the following two boolean flags  
should be marked as volatile in order to ensure that animation is cut  
short if executing:


TimelineClipCore.abort
ClipEnvelope.abort

This is simple enough to add to my original proposal of replacing the  
arrays in AbstractPrimaryTimer with CopyOnWriteArrayList which is thread  
safe and replicates the intended behavior in a clear and concise way.


Here are the methods that are called when stop() is invoked:


Timeline.stop()

   getStatus()

   clipCore.abort()

   isStopped()

   clipEnvelope.abortCurrentPulse()

   doStop()

  timer.removePulseReceiver(pulseReceiver);

  // After this point it doesn't matter
  setStatus(Status.STOPPED)

  doSetCurrentRate(0.0)

  jumpTo(Duration.ZERO)

And for AbstractPrimaryTimer.timePulseImpl:


AbstractPrimaryTimer.timePulseImpl

   Animation.PulseReceiver.timePulse

  Animation.doTimePulse

 clipEnvelope.timePulse

 animation.doPlayTo

clipCore.playTo

   visitKeyFrame

  setTime

 animation.setCurrentTicks

  clipInterpolator.interpolate

 animation.doJumpTo

sync(false)

setCurrentTicks

clipCore.jumpTo

   timeline.getStatus()

   clipInterpolator.interpolate

Regards
Jurgen


On Tue, 23 Jan 2024 01:52:42 +0200, John Hendrikx  
 wrote:


This is not a good idea, the NPE is a symptom of the problem, but there  
can be many more subtler problems (and new ones may surface after  
>fixing the NPE) that can affect other animations making use of the  
shared structures involved.  For one thing, absent a method of  
>synchronization, Java doesn't even guarantee that fields (or arrays)  
contain the same value for all threads.  So your thread may modify some  
>state, but the FX thread wouldn't even know about it (or only  
partially), and may make assumptions about an incorrect state, and then  
make >further changes based on incorrect assumptions.


A good example is that even a much simpler class like HashMap when  
accessed by multiple threads can get into a really bad state.  It will  
>usually throw a "ConcurrentModificationException" (or perhaps a weird  
NPE or IllegalStateException) to alert you that you're using it wrong  
>-- but those are the **best** case scenarios... In the worst case  
scenario, modifying a HashMap on multiple threads can result in an  
infinite >loop -- this can happen when two modifications occur, both  
updating the same bucket, and the threads end up changing things in such  
a way >that the entries point to each other.  Iterating it then (or  
accessing the wrong key) will cause an infinite loop (not hypothetical,  
I've had this >happen).


I'm afraid that even the synchronization option I proposed is not very  
realistic due to the amount of work it will entail.  We'd need to trace  
all >code paths that a call to play or stop could get to, and all those  
code paths would need to be made thread safe.


--John

Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced

2024-01-23 Thread Jurgen Doll

Hi Michael


starting an animation on a background thread would only be safe if the
object graph affected by the animation is not accessed on the
background thread after calling the play() method. Any access may
potentially corrupt internal state.


Agreed. Actually we should drive this further and say that "No changes  
should be made to properties that are being 'animated' while animation is  
in progress regardless of whether you're on the FX thread or not, or if  
the object is in the scene graph or not".


updater.play();
memoryLabel.setStyle( "-fx-text-fill: green" );  // This is OK
memoryLabel.setText( "This is NOT okay" );  // This is NOT, move  
to before play


Interesting API idea, however I don't think it's really needed for  
sensible developers.


Regards
Jurgen


On Mon, 22 Jan 2024 22:53:48 +0200, Michael Strauß  
 wrote:



Hi Jurgen,

starting an animation on a background thread would only be safe if the
object graph affected by the animation is not accessed on the
background thread after calling the play() method. Any access may
potentially corrupt internal state.

From what I can see in your example, you're not doing anything with
TestView after starting the animation, so you should be good here.

From an API perspective, I wonder if that makes it too easy to
introduce subtle bugs into an application. As a general principle, I
think an API should make it easy to do the right thing, and hard to do
the wrong thing. Allowing potentially unsafe method calls without some
explicit procedure (like wrapping the call in Platform.runLater) might
not be a good idea.

Maybe we should provide an API that allows developers to safely modify
an object graph on a background thread and call Platform.runLater
without worrying about concurrent modifications.

Something like this:

try (var scope = Platform.deferredScope()) {
var updater = new Timeline(
   new KeyFrame(Duration.seconds(2.5), event ->
   {
  int maxMemory = ;
  int usedMemory = ;
  memoryLabel.setText(usedMemory + " MB / "+ maxMemory +" MB");
   })
);

// This call will only be dispatched after the deferred scope is  
closed:

scope.runLater(updater::play);

// Still safe to call in the deferred scope, wouldn't be safe if
// Platform.runLater had been called before:
memoryLabel.setText("N/A");
}


Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE

2024-01-22 Thread Jurgen Doll
I've been delving into the usage of `aborted` and `inTimePulse` as  
mentioned by John and gleaned the following:


1. stop makes a best effort to abort the 'animation' if it is in the  
process of execution.

2. `aborted` and `inTimePulse` are reset with every pulse.

As to the options that John mentioned there's also a fourth:

Accept my original proposal of fixing the NPE which is a known problem and  
not worry about potential synchronization issues. I mean does it really  
matter if play, stop, or pause miss a beat due to synchronization, as the  
API does say this could happen. Furthermore it doesn't appear as though  
the animation code can be left in some strange inconsistent state as a  
result of this.


Jurgen


On Mon, 22 Jan 2024 17:58:20 +0200, John Hendrikx  
 wrote:




This seems like a reasonable use case, and perhaps this was the original  
intent of the "asynchronous call" documentation.


The problem though is that the play/stop code does not seem to take into  
account being called from a different thread (there are several  
>synchronization issues when I delved into that code).


So then there's a choice to make I think, either:

- Disallow it completely, and have users wrap it into Platform.runLater()
- Have play/stop do the wrapping itself
- Make the methods thread safe by fixing the synchronization issues

--John

HEADS-UP: Threading restriction for Animation play, pause, stop now enforced USE CASE

2024-01-22 Thread Jurgen Doll

Here's an example as requested by Nir:

public class FxTimeLineTest extends Application

{

private BorderPane bp = new BorderPane( new Label("Loading") );



public static void main( String[] args ) {

launch( FxTimeLineTest.class, args );

}



@Override

public void start( Stage primaryStage ) throws Exception {

new Thread( new LoadScene() ).start();

primaryStage.setScene( new Scene( bp, 300, 200 ) );

primaryStage.setTitle( "Memory Usage" );

primaryStage.show();

}



private class LoadScene extends Task {

@Override protected Parent call() throws Exception {

Parent p = FXMLLoader.load(  
getClass().getResource("TestView.fxml") );


Thread.sleep( 1000 );

return p;

}



@Override protected void succeeded() {

bp.setCenter( getValue() );

}



@Override protected void failed() {

getException().printStackTrace();

}

}

}


--


public class TestView

{

@FXML private Label memory;



private static final double  MEGABYTE = 1024 * 1024;



@FXML private void initialize()

{

var updater = new Timeline

(

new KeyFrame( Duration.seconds(2.5), event ->

{

var runtime = Runtime.getRuntime();

double maxMemory = runtime.maxMemory() / MEGABYTE;

double usedMemory = (runtime.totalMemory() -  
runtime.freeMemory()) / MEGABYTE;


memory.setText( (int) usedMemory + " MB / " + (int)  
maxMemory +" MB" );


})

);



updater.setCycleCount(Animation.INDEFINITE);
// This FXML is being loaded on a background thread

updater.play();

}

}


--

TestView.fxml













http://javafx.com/fxml/1"; fx:controller="TestView">

   

  

 

  

   






On Sat, 20 Jan 2024 17:08:41 +0200, Nir Lisker  wrote:


Hi Jurgen,

What I'm confused about the most is what it is you are actually trying  
to do that necessitates the use of animations outside of the FX thread.  
>You said that you need to initialize controls on another thread, and  
that you are using Task (both of which are fine), but how does playing  
>animations relate? Playing an animation is something that is done  
explicitly, usually in order to manipulate data. Can you give a real use  
>case, like a minimized version of what you're doing?


- Nir

Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced

2024-01-22 Thread Jurgen Doll

Hi Michael

It seems we are misunderstanding one another.

Firstly I agree that the animation code itself must and always has run  
only on the FX thread.


So for example in the following code:

   new KeyFrame( Duration.seconds(2.5), event ->
   {
  int maxMemory = ;
  int usedMemory = ;
  memoryLabel.setText( usedMemory +" MB / "+ maxMemory +" MB" );
   })

The lambda part ALWAYS executes on the FX thread by default, no matter on  
which thread this KeyFrame is created.



And we all agree that the following is ILLEGAL:

   new KeyFrame( Duration.seconds(2.5), event ->
   {
  new Thread( () -> memoryLabel.setText( usedMemory +" MB / "+  
maxMemory +" MB" ) ).start();

   })


With the above clarified, what I'm contending is that the following can be  
excuted on any thread:


   var updater = new Timeline
   (
  new KeyFrame( Duration.seconds(2.5), event ->
  {
 int maxMemory = ;
 int usedMemory = ;
 memoryLabel.setText( usedMemory +" MB / "+ maxMemory +" MB" );
  })
   );
   updater.setCycleCount(Animation.INDEFINITE);
   updater.play();


The reason is because play, stop, and pause simply causes the Timeline to  
be added too or removed from an array in AbstractPrimaryTimer. If a pulse  
is busy executing so that the array is currently being accessed by the FX  
thread then a copy of the array is made and the addition/removal is made  
to the copy. (However there is a bug in this code that causes an NPE under  
certain conditions.)


So when the API documentation says that it's asynchronous it means that  
the 'animation' execution may not yet have started/stopped when the call  
returns depending on when during the pulse the method was invoked. If play  
is invoked just before the next pulse then the 'animation' could be  
running, or if stop is invoked just as a pulse completes then it will not  
be executing. Otherwise the 'animation' will only actually be (not)  
executing in the next pulse.


Hope this clarifies things.

Regards
Jurgen


Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced

2024-01-19 Thread Jurgen Doll

Hi Kevin

I was hoping that others would way in on this fix (PR #1167), but now that  
we're in RDP1 with no other input coming in I decided to looked into this  
matter again and have found that this is not the correct solution for the  
following two reasons:


1. The current solution doesn't actually fix the bug, but merely avoids it:

Specifically with regards to bug JDK-8159048 which reports a NPE occuring  
under some conditions in AbstractMasterTimer (subsequently renamed to  
AbstractPrimaryTimer). The reporter suggests that this is as a result of  
some concurrent modification occurring and suggests a workaround of  
wrapping the start/stop animation code in a Platform.runLater() call.


Looking at the AbstractPrimaryTimer code it is apparent that the original  
author made an effort to isolate array modifications from  array access.  
However this code has a bug in it which then manifests as a NPE under the  
right timing conditions. So the correct solution is to make the array  
modification code more robust, as apposed to forcing changes to occur on a  
single thread.


The safest (and proper) solution is to convert the two arrays ("receivers"  
and "animationTimers") to be CopyOnWriteArrayList(s) which is an ideal JDK  
data structure for this use case as it replicates the intended behavior of  
the current implementation. (I've tried this out and it does solve the NPE  
problem.)


2. The current solution is based on the misconception that start, stop,  
and pause must occur on the FX thread:


Specifically with regards to the CSR JDK-8313378 which makes this claim.

Firstly the Animation API says explicitly that these methods are  
asynchronous, which means that the thread that invokes these methods and  
the actual execution of the animation occurs on different threads, and  
looking at AbstractPrimaryTimer code it can be seen that this is indeed  
the case.


Secondly JavaFX had tests, as noted in JDK-8314266, that have run reliably  
for years without invoking these methods on the FX thread. FWIW I've also  
had code and used libraries for years now, where these methods have been  
invoked on a background thread (for example while loading FXML) without  
issue.



In conclusion then I request permission to submit a new PR containing the  
following changes:


1. Revert PR #1167 (if this is the appropriate place, however the test  
case will require it)
2. Changing the arrays in AbstractPrimaryTimer to be  
CopyOnWriteArrayList(s) and removing previously supporting array code.
3. Adding a test based on the one supplied in JDK-8159048 to check that a  
NPE isn't thrown anymore.


Hope this meets with your approval.
Regards,
Jurgen



  On 8/18/2023 4:17 PM, Kevin Rushforth wrote:
As a heads-up for app developers who use JavaFX animation (including  
Animation, along with any subclasses, and AnimationTimer), a change went  
into the JavaFX 22+5 build to enforce that the play, pause, and stop  
methods must be called on the JavaFX Application thread. Applications  
should have been doing that all along (else they would have been subject  
to unpredictable errors), but for those who aren't sure, you might want  
to take 22+5 for a spin and see if you have any problems with your  
application. Please report them on the list if you do.


See JDK-8159048 [1] and CSR JDK-8313378 [2] for more information on this  
change.


Thanks.

-- Kevin

[1] https://bugs.openjdk.org/browse/JDK-8159048
[2] https://bugs.openjdk.org/browse/JDK-8313378


Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced

2023-08-29 Thread Jurgen Doll

Thanks for the heads-up Kevin,

I gave it a spin and found that generally because I use Task to load my  
fxml views I had problems.


Some of these I could resolve by wrapping the offending line with runlater  
in the fxml initialise method. This reminded me though of the days when  
Tooltips had to be wrapped as well and it felt wrong because generally a  
view may be constructed and modified on any thread as long as it's not yet  
attached to a Scene in a Window that is showing.


This is highlighted further because I also have some third party controls  
and libraries that are being initialized as part of the view, which now  
just crash my application. This means that I cannot instantiate these  
controls or libraries on any thread I want but have to make sure its done  
on the FX thread, even though they're not attached to a Scene yet.


As a possible solution I was wondering since the Animation API says that  
calls to play() and stop() are asynchronous if it wouldn't then be valid  
to instead of throwing an exception, if the call to it isn't being made on  
the FX thread, that it rather be delegated to the FX thread with for  
example something like:


public abstract class Animation {
public void play() {
if ( Platform.isFxApplicationThread() ) playFX();
else Platform.runLater( () -> playFX() );
}

private void playFX() {
// previous play() code
}
}

This would then prevent the NPE errors that sometimes occur but not put a  
burden on the existing code in the wild and allow views to be loaded with  
Task call() without worries.


Thanks, regards
Jurgen


 On 8/18/2023 4:17 PM, Kevin Rushforth wrote:
As a heads-up for app developers who use JavaFX animation (including  
Animation, along with any subclasses, and AnimationTimer), a change went  
into the JavaFX 22+5 build to enforce that the play, pause, and stop  
methods must be called on the JavaFX Application thread. Applications  
should have been doing that all along (else they would have been subject  
to unpredictable errors), but for those who aren't sure, you might want to  
take 22+5 for a spin and see if you have any problems with your  
application. Please report them on the list if you do.


See JDK-8159048 [1] and CSR JDK-8313378 [2] for more information on this  
change.


Thanks.

-- Kevin

[1] https://bugs.openjdk.org/browse/JDK-8159048
[2] https://bugs.openjdk.org/browse/JDK-8313378


Re: HEADS-UP: Threading restriction for Animation play, pause, stop now enforced

2023-08-22 Thread Jurgen Doll

Thanks for the heads-up Kevin,

I gave it a spin and found that generally because I use Task to load my
fxml views I had problems.

Some of these I could resolve by wrapping the offending line with runlater
in the fxml initialise method. This reminded me though of the days when
Tooltips had to be wrapped as well and it felt wrong because generally a
view may be constructed and modified on any thread as long as it's not yet
attached to a Scene in a Window that is showing.

This is highlighted further because I also have some third party controls
and libraries that are being initialized as part of the view, which now
just crash my application. This means that I cannot instantiate these
controls or libraries on any thread I want but have to make sure its done
on the FX thread, even though they're not attached to a Scene yet.

As a possible solution I was wondering since the Animation API says that
calls to play() and stop() are asynchronous if it wouldn't then be valid
to instead of throwing an exception, if the call to it isn't being made on
the FX thread, that it rather be delegated to the FX thread with for
example something like:

public abstract class Animation {
  public void play() {
  if ( Platform.isFxApplicationThread() ) playFX();
  else Platform.runLater( () -> playFX() );
  }

  private void playFX() {
  // previous play() code
  }
}

This would then prevent the NPE errors that sometimes occur but not put a
burden on the existing code in the wild and allow views to be loaded with
Task call() without worries.

Thanks, regards
Jurgen


   On 8/18/2023 4:17 PM, Kevin Rushforth wrote:
As a heads-up for app developers who use JavaFX animation (including  
Animation, along with any subclasses, and AnimationTimer), a change went  
into the JavaFX 22+5 build to enforce that the play, pause, and stop  
methods must be called on the JavaFX Application thread. Applications  
should have been doing that all along (else they would have been subject  
to unpredictable errors), but for those who aren't sure, you might want  
to take 22+5 for a spin and see if you have any problems with your  
application. Please report them on the list if you do.


See JDK-8159048 [1] and CSR JDK-8313378 [2] for more information on this  
change.


Thanks.

-- Kevin

[1] https://bugs.openjdk.org/browse/JDK-8159048
[2] https://bugs.openjdk.org/browse/JDK-8313378


Comment for JDK-8289115 - Touch events are not dispatched after upgrade to FX17

2023-06-23 Thread Jurgen Doll

Hi

Could someone please add the following lines as comment to the issue  
JDK-8289115 (https://bugs.openjdk.org/browse/JDK-8289115) Thank you very  
much.



@Praveen please have another look at Capture.pptx and you'll see that  
*ONLY* MouseEvents are being fired and NO TouchEvents. The test case  
illustrates exactly what the reporter describes as being the problem. So  
is reproducible.


Note that this appears to be device INdependent, so any TouchScreen  
running Windows with either touch or pen/stylus, will show no TouchEvents  
are fired after jfx17-ea+2-win.


This bug is a direct result of fixing JDK-8249737 RuntimeException: Too  
many touch points reported.  
(https://bugs.openjdk.java.net/browse/JDK-8249737)


Please reopen both of these issues.

Thanks, Jurgen

Comment for JDK-8289115 - Touch events are not dispatched after upgrade to FX17

2023-06-08 Thread Jurgen Doll

Hi

Could someone please add the following lines as comment to the issue  
JDK-8289115 (https://bugs.openjdk.org/browse/JDK-8289115)  Thank you very  
much.



@Praveen please have another look at Capture.pptx and you'll see that only  
MouseEvents are being fired and NO TouchEvents. The test case illustrates  
exactly what the reporter describes as being the problem.


Note that this appears to be device INdependent, so any TouchScreen  
running Windows with either touch or pen/stylus and no TouchEvents are  
fired after jfx17-ea+2-win.


This bug is a direct result of fixing JDK-8249737 RuntimeException: Too  
many touch points reported.

(https://bugs.openjdk.java.net/browse/JDK-8249737)

Please reopen both of these issues.

Thanks, Jurgen