No se puede cambiar initModality de una ventana de alerta en JavaFX

zjeffer:

En JavaFX (11), que estoy tratando de mostrar una ventana de alerta por encima de la ventana principal, pero no quiero que la ventana principal para hacer clic. Para ello, pensé que tenía que cambiar el initModality de esa ventana de alerta ( https://docs.oracle.com/javafx/2/api/javafx/stage/Stage.html ver 'Modalidad'). Por qué no funciona debido a que el propietario de la ventana de alerta es nulo?

Aquí está mi clase controlador. La clase principal es simplemente la clase JavaFX principal predeterminado generado por IntelliJ IDEA y el archivo .fxml es sólo un anchorpane con un botón para propósitos de prueba.

package sample;

import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.stage.Modality;

public class Controller {

    public Button button;

    public void initialize(){
        Alert alert = new Alert(Alert.AlertType.ERROR);
        System.out.println(alert.getOwner());             //output: null
        alert.initModality(Modality.APPLICATION_MODAL);
        alert.setHeight(200);
        alert.setWidth(300);
        alert.show();
        button.setOnAction(push -> System.out.println("button pressed")); //button is still pressable
    }
}

El botón de la ventana principal sigue siendo prensada, por lo que el initModality no funcionaba. También he probado con Modality.WINDOW_MODALy Modality.NONE, no hay cambio.

Estoy en Linux con bspwm si lo que importa.

repollo:

Creo que el problema es el orden se muestran las ventanas. Prueba de esto con la siguiente reproducido el problema en Windows 10 (utilizando JavaFX 12.0.1):

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        var alert = new Alert(AlertType.INFORMATION);
        alert.initModality(Modality.APPLICATION_MODAL);
        alert.setHeaderText(null);
        alert.setContentText("This is a test of application modality.");
        alert.show();

        primaryStage.setScene(new Scene(new StackPane(new Label("Hello, World!")), 500, 300));
        primaryStage.show();
    }

}

Los resultados anteriores en una ventana de diálogo que no es propiamente modal. Sin embargo, si se muda alert.show()a después de primaryStage.show() todo funciona como se esperaba.

Puesto que usted está mostrando su Alertinterior el initialize()método de un controlador de FXML, lo más probable es que el código se ejecuta antes de mostrar la ventana principal. Si desea visualizar la Alertderecha en el comienzo de su aplicación existen al menos dos opciones:

  1. Llamar show()dentro de una Platform.runLaterllamada, como lo hace en su respuesta .

    • La desventaja de esto es que hace que el código dependiente de código aparentemente sin relación altamente. Por ejemplo, si por cualquier razón usted cambia cómo y cuando se muestra la ventana principal, esta opción puede romper.
  2. Agregue un método a su Controllerclase y Invóquelo después de mostrar su otra ventana.

    @Override
    public void start(Stage primaryStage) throws IOException {
        FXMLLoader loader = new FXMLLoader(/*location*/);
        primaryStage.setScene(new Scene(loader.load()));
        primaryStage.show();
        loader.<Controller>getController().showMyAwesomeAlert();
    }
    

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=206755&siteId=1
Recomendado
Clasificación