es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Implementar el comportamiento de ocultar al salir de la aplicación en macOS con JFrame/Swing.

Estoy intentando implementar un comportamiento de “iconificar al salir” en mi aplicación Java JFrame, como la mayoría de las aplicaciones nativas de macOS tienen, pero estoy bastante atascado.

He intentado hacer lo siguiente:

Ventana.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent Event) {
        System.out.println("Cerrado en macOS, iconificando");
        Ventana.setExtendedState(Frame.ICONIFIED);
    }
});

y cerrando la ventana al salir con (además de agregar un WindowListener que llama a setVisible(false)):

Ventana.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

Lo primero no funcionó porque parece que se minimiza y crea 2 iconos separados. Lo segundo no funcionó porque no pude encontrar una forma de detectar cuando se hace clic en el ícono de la barra de tareas para mostrar la ventana nuevamente. Preferiría este método si pudiera descubrir cómo hacerlo. ¿Alguien sabe cómo?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como experto en Java y Swing, JFrame, Taskbar y Dock, te sugeriría utilizar el siguiente código para implementar el comportamiento de “iconify on quit” en una aplicación de Java JFrame:

    frame.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent e) {
        if (SystemTray.isSupported()) { // comprueba si el system tray está soportado
          try {
            TrayIcon trayIcon = new TrayIcon(new ImageIcon("yourIcon.png").getImage());
            trayIcon.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                frame.setVisible(true);
                frame.setExtendedState(JFrame.NORMAL);
                SystemTray.getSystemTray().remove(trayIcon);
              }
            });
            SystemTray.getSystemTray().add(trayIcon);
            frame.setVisible(false);
            frame.setExtendedState(JFrame.ICONIFIED); // iconifica el marco
          } catch (Exception ex) {
            ex.printStackTrace();
          }
        } else {
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // cierra la aplicación
        }
      }
    });
    

    Este código agrega un “window listener” al JFrame, el cual escucha el evento de cierre de la ventana. Cuando ocurre el evento, verifica si el “system tray” es soportado por el sistema operativo. Si es soportado, el código crea un nuevo TrayIcon con la imagen especificada y lo agrega al “system tray”. El ActionListener del TrayIcon escucha un clic en el icono, y cuando ocurre, establece el JFrame como visible y en estado normal, y elimina el TrayIcon del “system tray”. Antes de agregar el TrayIcon, el código establece el JFrame como invisible y en estado iconificado.

    Si el “system tray” no es soportado por el sistema operativo, el código cierra la aplicación estableciendo la operación de cierre predeterminada en EXIT_ON_CLOSE.

    Espero que esto te ayude a implementar el comportamiento deseado en tu aplicación de Java JFrame.

Comments are closed.