Search code examples
javagenericsjavafxclasscastexception

JavaFX Dialog getResult() method not returning the right generic type


I'm facing a problem dealing with JavaFX Dialog<R> class. I created a dialog with a custom type parameter, say String for simplicity. Now whenever I try to acquire the result of the dialog I get a ClassCastException.

Take this simple JavaFX application:

@Override
public void start(Stage primaryStage) {
    Dialog<String> dialog = new Dialog<>();
    dialog.getDialogPane().getButtonTypes().setAll(ButtonType.OK);
    String result = dialog.showAndWait().orElse(null);
}

Once I hit the OK button, I have an error stack that leads to:

Caused by: java.lang.ClassCastException: javafx.scene.control.ButtonType cannot be cast to java.lang.String

Needless to say, the code compiles perfectly. It seems that whenever the OK button is triggered, the value of the dialog box is forced to something of type ButtonType. Not the type you'd be expecting knowing the method signature.

This is also true if I use the method getResult() after having shown the dialog.

I use Oracle's JVM 1.8.0_151.

Thanks for any insights.


Solution

  • The Dialog API requires you to set a result converter callback if the type is not Void or ButtonType. To get your example running:

    @Override
    public void start(Stage primaryStage) {
        Dialog<String> dialog = new Dialog<>();
        dialog.getDialogPane().getButtonTypes().setAll(ButtonType.OK);
        dialog.setResultConverter(ButtonType::getText);
        String result = dialog.showAndWait().orElse(null);
        System.out.println(result);
    }
    

    In the snippet above, result holds the value OK. This is hardly more useful than having ButtonType as a type argument. If you want to obtain a domain object from the Dialog, a more idiomatic approach is to attach an event to the OK button, perform a validation on the input and calculate the result object in the event handler. The documentation lists three ways to achieve that.