The task is to click on a specific program button (JavaFX GUI) to start a wait gif that will spin while the main code is filled. For this there is a separate method - showGif (), and its call through Platform.runLater as a separate stream (it starts when you click on the button).

The problem is that the gif still runs only after all the program code has been executed - i.e. not a separate thread at the beginning of the program, as I wanted.

In similar questions for people, everything works through Platform.runLater - what am I doing wrong?

Button action:

btn_find.setOnAction(new EventHandler<ActionEvent>() { public void handle(ActionEvent event) { // отправляСт Π²Π²Π΅Π΄Π΅Π½Π½ΡƒΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ ссылку Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π³ΠΈΡ„ΠΊΡƒ оТидания new Thread(new Runnable() { public void run() { Platform.runLater(new Runnable() { public void run() { showGif(); } }); } }).start(); 

ShowGif () method:

 private void showGif() { System.out.println("Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽ Π³ΠΈΡ„ΠΊΡƒ"); File file = new File("/Users/user/Desktop/cat-preloader.gif"); String localUrl = null; try { localUrl = file.toURI().toURL().toString(); } catch (MalformedURLException e) { e.printStackTrace(); } Image image = new Image(localUrl, 200,200, false, true); ImageView imageView = new ImageView(image); hb = new HBox(); hb.setStyle("-fx-background-color: lightgrey"); hb.setOpacity(0.7); hb.getChildren().add(imageView); HBox.setMargin(imageView, new Insets(300, 100, 60, 200)); BorderPane.setMargin(hb, new Insets(0, 0,600, 0)); MainView.pane.setCenter(hb); // здСсь Π·Π°ΠΌΠΈΠ½ΠΊΠ° - Π³ΠΈΡ„ отобраТаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ послС выполнСния всСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ System.out.println("Π³ΠΈΡ„ΠΊΠ° Π·Π°ΠΏΡƒΡ‰Π΅Π½Π°"); } 
  • And the flow with gif starts before starting the execution of the main code? - Z.John
  • @ Z.John no, after. - anabioze 7:03 pm
  • Try to start the stream with the gif before running the main code. As far as I understand the execution of the main code is in the main thread. - Z.John 7:07 pm
  • @ Z.John how, the flow with the gif is also tied to the press of a button? The button is created in the main Application thread. If only to put on the button the flag "press" and from the outside monitor it with an infinite loop? - anabioze 7:57 pm
  • one
    @anabioze run the task in the background in new Task<>() and the gif can also be run in the same way. - Tsyklop 8:19 pm

1 answer 1

Run the necessary code in the background so as not to occupy the main thread.

This can be done using Task :

 Task<Void> task = new Task<Void>() { @Override protected Integer call() throws Exception { System.out.println("Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽ Π³ΠΈΡ„ΠΊΡƒ"); File file = new File("/Users/user/Desktop/cat-preloader.gif"); String localUrl = null; try { localUrl = file.toURI().toURL().toString(); } catch (MalformedURLException e) { e.printStackTrace(); } Image image = new Image(localUrl, 200,200, false, true); ImageView imageView = new ImageView(image); hb = new HBox(); hb.setStyle("-fx-background-color: lightgrey"); hb.setOpacity(0.7); hb.getChildren().add(imageView); HBox.setMargin(imageView, new Insets(300, 100, 60, 200)); BorderPane.setMargin(hb, new Insets(0, 0,600, 0)); MainView.pane.setCenter(hb); System.out.println("Π³ΠΈΡ„ΠΊΠ° Π·Π°ΠΏΡƒΡ‰Π΅Π½Π°"); return null; } }; 

Well, the launch itself:

new Thread(task).start()

You can also run long operations in the same task.

  • Platform.runLater : If you need to update a GUI component from a stream other than the GUI, you can use this to put your update in the queue and it will be processed by the GUI thread as soon as possible.
  • Task implements the Worker interface, which is used when you need to run a long task outside the flow of the graphical interface (to avoid freezing your application), but still need to interact with the graphical interface at a certain stage.

A source