example - javafx scene builder
Prevenir/cancelar el cierre de la etapa primaria en JavaFX 2.2 (3)
Como dice el título, mi pregunta es, ¿cómo puedo evitar / cancelar el cierre de la etapa primaria en JavaFX 2.2? He investigado un poco en Google y los siguientes dos enlaces parecían abordar el problema:
Probé los métodos explicados por esos dos enlaces, pero lamentablemente para mí, ninguno de ellos funciona. Así que, sin más preámbulos, aquí está lo que había hecho.
En primer lugar, traté de adjuntar un OnCloseRequest
a OnCloseRequest
de la siguiente manera.
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
if (!canExit()) {
event.consume();
primaryStage.show(); // I tried without this line also.
}
}
});
Cuando canExit()
devuelve false
, intenté evitar que el evento se siguiera propagando y hacer que la aplicación event.consume()
llamando a event.consume()
. Pero el escenario se está cerrando / ocultando y recibí los siguientes mensajes de error en la ventana de salida de Netbeans. Sigue viniendo repetidamente hasta que fuerzo a cerrar la aplicación de Netbeans.
(java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)'' failed
(java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)'' failed
(java:6731): Gtk-CRITICAL **: IA__gtk_widget_get_visible: assertion `GTK_IS_WIDGET (widget)'' failed
Después de haber probado el fracaso en este intento, cambié OnCloseRequest
a OnHiding
con la expectativa de éxito.
primaryStage.setOnHiding(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
if (!canExit()) {
event.consume();
primaryStage.show(); // I tried without this line also.
}
}
});
Aunque también probé el fracaso en este intento, creo que he progresado. No hay mensajes de error esta vez, y no es necesario forzar el cierre de la aplicación desde Netbeans.
Luego leí acerca de un método mágico llamado setImplicitExit()
en la clase Platform
. Pensando que esto es lo que me faltaba, probé Platform.setImplicitExit(false);
con los dos métodos siguientes:
OnCloseRequest
versionPlatform.setImplicitExit(false); primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() { if (!canExit()) { // ... } else { Platform.exit(); } });
No hay diferencia, la etapa se cierra / oculta, y el mismo mensaje de error aparece repetidamente.
Versión
OnHiding
Platform.setImplicitExit(false); primaryStage.setOnHiding(new EventHandler<WindowEvent>() { if (!canExit()) { // ... } else { Platform.exit(); } });
Comenzando con una nota positiva, la aplicación no se cierra como antes. Pero, la nota negativa es que el escenario todavía se está cerrando / ocultando.
Ahora, me he quedado sin armas / equipos en mi arsenal para resolverlo, y por eso estoy aquí para solicitar la ayuda de sus héroes y campeones. Entonces, ¿cómo puedo resolver este problema o qué he hecho mal o qué me estoy perdiendo?
Creo que esto es un error con JavaFX para Linux. Me encontré con el mismo problema en Javafx 2.2.21-b11. Dependiendo del contexto, los errores de GTK pueden o no estar presentes, pero de cualquier manera el hecho de consumir el evento de solicitud de cierre no impidió que la ventana se cerrara (sin embargo, el proceso continúa ejecutándose). La misma aplicación en Windows se comportó como yo esperaría. Así que, en el mejor de los casos, tenemos una diferencia de comportamiento entre plataformas.
Presenté un informe de error que puedes votar si lo deseas: https://javafx-jira.kenai.com/browse/RT-33295
Aquí está la fuente de mi aplicación de prueba
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public class Boom extends Application {
@Override
public void start(final Stage primary) {
System.out.println(com.sun.javafx.runtime.VersionInfo.getRuntimeVersion());
primary.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent e) {
e.consume();
}
});
primary.show();
}
public static void main(String[] args) {
launch(args);
}
}
Creo que tienes el onCloseRequest()
mal. Si consumes el evento cancelas el cierre! Entonces funciona el otro por qué round, si canExit()
devuelve false, consumes el evento
He usado el siguiente código en mi aplicación y funciona perfectamente,
Platform.setImplicitExit(false);
primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
event.consume();
}
});