0

I am not sure what I am doing wrong in the following code. The alert box does not render about 1 in 5 times when I click the "PRESS ME!" for the first time after I run the code. It renders fine every time I click the button after that. To test the code you may have to run this code multiple times. Can someone please go through the code and spot as to why this is happening.

I am using: java version "1.8.0_101" Java(TM) SE Runtime Environment (build 1.8.0_101-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

OS: ubuntu 16.04 LTS

Here is the code:

package javaapplication;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class JavaApplication extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Font font = new Font(40);
        Text helloWorldText1 = new Text("Hello World from ");
        Text helloWorldText2 = new Text("JavaFX!!");
        helloWorldText1.setFont(font);
        helloWorldText2.setFont(font);
        helloWorldText2.setFill(Color.RED);
        HBox hBox1 = new HBox(helloWorldText1, helloWorldText2);

        HBox hBox2 = new HBox(20);
        Button okButton = new Button("PRESS ME!");
        okButton.setOnAction(e -> {
            Platform.runLater(() -> {
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setContentText("You pressed OK!");
                alert.showAndWait();
            });
        });

        Button cancelButton = new Button("CANCEL!!");
        cancelButton.setOnAction(e -> System.exit(0));
        hBox2.getChildren().addAll(okButton, cancelButton);
        hBox2.setAlignment(Pos.BOTTOM_RIGHT);

        VBox vBox = new VBox(10);
        vBox.getChildren().addAll(hBox1, hBox2);
        vBox.setAlignment(Pos.CENTER);
        vBox.setPadding(new Insets(20));
        primaryStage.setScene(new Scene(vBox));
        primaryStage.show();
    }
}

Thanks for all your suggestions in advance.

Edit:

I have uploaded a video at youtube video which shows the behavior. Please see if you observe the same. In this video I have also removed the Platform.runLater(...) to show that the rendering issue does not go away!

Sourabh Bhat
  • 1,793
  • 16
  • 21
  • 1
    It shouldn't make any difference, but why are you using `Platform.runLater(...)` inside an event handler? – James_D Aug 10 '16 at 19:27
  • Actually I tried it without the `Platform.runLater()` first but I started having this problem. So I thought that it may be because the rendering engine is being blocked. So I added it in the debugging process. – Sourabh Bhat Aug 10 '16 at 19:49
  • 1
    `Platform.runLater(...)` submits code to execute on the FX Application Thread, so if your code were blocking rendering, that wouldn't help at all (if anything, it would make it worse). Since you're inside an event handler, it's already being executed on the FX Application thread. You should remove the call to `Platform.runLater(...)` if it's not making any improvement; it makes no sense in this context. – James_D Aug 10 '16 at 20:12
  • Thank you. I have uploaded a video at [youtube video](https://youtu.be/j27RraUzHQw) which shows the behavior. Please see if you observe the same. Thanks. – Sourabh Bhat Aug 11 '16 at 11:09
  • @James_D Thanks for the explanation. I used to think that runLater() will create a new thread for a particular piece of code and run it independently later. – Sourabh Bhat Aug 11 '16 at 11:26

2 Answers2

0

Iv tested the application on both windows, manjaro linux and lubuntu but not ubuntu itself and iv had no issue...that being said sometimes i experience weird issues with linux and javafx, particularly around the graphics aspect such as fullscreen view etc.

However taking a guess since i cant recreate the issue on any OS i have tried this far:

The method Platform.runLater(java.lang.Runnable runnable) runs the specified Runnable on the JavaFX Application Thread at some unspecified time in the future.

So thenless theres a reason you need a delay on the window appearing such as loading something in the background whilst the window loads then maybe just try this event instead :

okButton.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
         Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setContentText("You pressed OK!");
        alert.showAndWait();
    }
});

To give a bit more information theres another post here describing in some detail what happens but ill quote here anyway:

Keep in mind that the button's onAction is called on the JavaFX thread, therefore you are effectively halting your UI thread for 5 seconds.

They also provide a work around for if you really need the event to be called on the Javafx thread. Hope this helps and good luck with your project!

Community
  • 1
  • 1
D3181
  • 2,037
  • 5
  • 19
  • 44
  • 1
    The reason the code in the linked question halts the FX Application Thread for 5 seconds is that it explicitly pauses for 5 seconds (`Thread.sleep(5000)`). The code here doesn't do that, so it won't have the same problem. Using `Platform.runLater(...)` will not cause any delay that is noticeable to the user, it will effectively just delay it until the next rendering frame (so 1/60 second, in normal circumstances), but *since event handlers are already invoked on the FX Application Thread*, using it here is redundant. So your code block makes sense, though your description is a bit odd. – James_D Aug 10 '16 at 20:08
  • ah right, valid point about the javafx application thread, though makes the problem slightly more obscure. – D3181 Aug 10 '16 at 20:17
  • Thank you. I have uploaded a video at [youtube video](https://youtu.be/j27RraUzHQw) which shows the behavior. Can you please see if you observe the same. Thanks. – Sourabh Bhat Aug 11 '16 at 10:59
0

I got to run your program.Your program does not have any problems. Your computer is cause of delay.

yousef
  • 92
  • 1
  • 10
  • Thank you for trying. I have run this code on two machines with Ubuntu 14.04 and 16.04. Both the machines show similar behavior. Configuration of the computers is good, so that does not seem to be the problem. I have tried running this code on CentOS and it runs perfectly. And as per comments above it runs fine on Windows. So I guess Ubuntu could be the problem. All other programs run fine on these machines, I don't know why such a simple program behaves differently!! – Sourabh Bhat Aug 13 '16 at 20:14