Pregunta

Estoy escribiendo una aplicación Java (Swing GUI) que periódicamente aparece un JFrame.

Es posible de alguna manera para traer la ventana al frente (foo.setAlwaysOnTop(true) sería aún mejor) pero sin tener el foco?

Algunas personas mover sus ojos de la pantalla de vez en cuando para mirar el teclado mientras escribe, y estoy seguro de que si esta ventana siempre se captura el foco del teclado personas podrían obtener muy molesto, ya que es causante de la pérdida de un buen par de pulsaciones de teclas cada vez que aparece desapercibido.

En otros casos, incluso cuando el usuario está realmente capaz de escribir sin mirar el teclado todo el tiempo, tener una ventana pop-up y obtener el enfoque podría causar que las acciones no deseadas en el menú emergente de la ventana (algunos Tab+Enter combinación por ejemplo, donde el usuario accidentalmente se selecciona una opción que ella realmente no había seleccionado de otra manera).

Gracias de antemano!

Actualización

Como Jonas sugiere, foo.setFocusableWindowState(false); parece que funciona, si llama después de que la ventana ha sido prestados (probado en Gnome solamente).

Esto no funciona:

foo.setFocusableWindowState(false);
foo.setVisible(true);
foo.setFocusableWindowState(true);

Sin embargo, este ¿:

foo.setFocusableWindowState(false);
foo.setVisible(true);
Thread.sleep(1000);
foo.setFocusableWindowState(true);

Voy a tener que ver si hay un evento que puede coger/escuchar que me permite hacer foo.setFocusableWindowStatue(true); cuando sea apropiado.

Considero que mi problema se resuelva.

¿Fue útil?

Solución

Esto puede funcionar:

foo.setFocusableWindowState(false);

Otros consejos

A partir de Java 1.7 puedes llamar

frame.setAutoRequestFocus(false);

Hace poco me encontré con el mismo problema, y la solución tentativa ha sido:

JFrame frame = ...;
frame.setExtendedState(JFrame.NORMAL);
frame.setAlwaysOnTop(true);
frame.requestFocus();
frame.setAlwaysOnTop(false);

Sugerencia: en el componente GUI que crea el marco, ponga 2 llamadas consecutivas:

frameJustCreated.requestFocus();
this.requestFocus();

El primero trae la ventana del nuevo Jframe a la parte superior, el segundo mantiene la ventana donde el usuario está escribiendo en la parte superior.

Si desea llamar a SetFocusableWindowState (verdadero) en un evento (por lo tanto, para no esperar, por ejemplo, 1 segundo), puede agregar un WindowListener (por ejemplo, derivado de WindowAdapter) que cambia la propiedad:

    appFrame.addWindowListener(new WindowAdapter() {
        @Override
        public void windowOpened(WindowEvent e) {
            super.windowOpened(e);
            e.getWindow().setFocusableWindowState(true);
        }
    });

    appFrame.setFocusableWindowState(false);
    appFrame.setVisible(true);

JinternalFrame toFront() llamadas a moveToFront()

Anular moveToFront()

public void moveToFront() {
        Window window = SwingUtilities.getWindowAncestor(this);
        Component focusOwner = (window != null) ? window.getFocusOwner() :
                                null;
        boolean descendant = false;

        if (window != null && focusOwner != null &&
                      SwingUtilities.isDescendingFrom(focusOwner, this)) {
            descendant = true;
            requestFocus();
        }

        super.moveToFront();

        if (descendant) {
            focusOwner.requestFocus();
        }
    }

La solución está en MovetoFront para verificar si un niño tiene enfoque, si lo hace, entonces solicite temporalmente el enfoque en el marco interno. Después de que el marco interno tiene el traslado al frente, luego solicite el enfoque nuevamente en el componente previamente enfocado. Esto asegurará que se generen los eventos apropiados.

referirsehttps://bugs.openjdk.java.net/browse/jdk-4309079

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top