gui create java windows swing awt

java - create - ¿Cómo llevar una ventana al frente?



swing windows java (11)

Tenemos una aplicación Java que debe ponerse en primer plano cuando un mecanismo de telecontrol activa algo en la aplicación.

Para obtener esto, nos hemos dado cuenta en el método llamado de la Clase que representa el Marco de nuestra aplicación (extensión de un JFrame) después de la implementación:

setVisible(true); toFront();

En Windows XP, esto funciona la primera vez que se llama, en la segunda vez que solo parpadea la pestaña en la barra de tareas, el marco ya no se pone al frente. Lo mismo ocurre con Win2k. En Vista, parece funcionar bien.

¿Alguien tiene ideas?


Hay numerosas advertencias en el javadoc para el método toFront () que pueden estar causando su problema.

Pero voy a adivinar de todos modos, cuando "solo parpadea la pestaña en la barra de tareas", ¿se ha minimizado la aplicación? De ser así, la siguiente línea del javadoc puede aplicarse:

"Si esta ventana está visible, trae esta ventana al frente y puede convertirla en la ventana enfocada".


La forma más simple que he encontrado es que no tiene inconsistencia en todas las plataformas:

setVisible (falso); setVisible (verdadero);


Este sencillo método funcionó perfectamente para mí en Windows 7:

private void BringToFront() { java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { if(jFrame != null) { jFrame.toFront(); jFrame.repaint(); } } }); }


Las reglas que rigen lo que sucede cuando usted .toFront () un JFrame son iguales en Windows y en Linux:

-> si una ventana de la aplicación existente es actualmente la ventana enfocada, entonces el foco cambia a la ventana solicitada -> si no, la ventana simplemente parpadea en la barra de tareas

PERO :

-> las nuevas ventanas se enfocan automáticamente

¡Explotémoslo! ¿Quieres traer una ventana al frente, cómo hacerlo? Bien :

  1. Crea una ventana vacía sin propósito
  2. Enséñalo
  3. Espere a que aparezca en la pantalla (setVisible lo hace)
  4. Cuando se muestre, solicite enfoque para la ventana en la que realmente desea enfocar
  5. esconde la ventana vacía, destrúyela

O bien, en código Java:

// unminimize if necessary this.setExtendedState(this.getExtendedState() & ~JFrame.ICONIFIED); // don''t blame me, blame my upbringing // or better yet, blame java ! final JFrame newFrame = new JFrame(); newFrame.add(new JLabel("boembabies, is this in front ?")); newFrame.pack(); newFrame.setVisible(true); newFrame.toFront(); this.toFront(); this.requestFocus(); // I''m not 100% positive invokeLater is necessary, but it seems to be on // WinXP. I''d be lying if I said I understand why SwingUtilities.invokeLater(new Runnable() { @Override public void run() { newFrame.setVisible(false); } });


Hj, todos los métodos tuyos no funcionan para mí, en Fedora KDE 14. Tengo una manera sucia de traer una ventana al frente, mientras esperamos que Oracle resuelva este problema.

import java.awt.MouseInfo; import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; public class FrameMain extends javax.swing.JFrame { //... private final javax.swing.JFrame mainFrame = this; private void toggleVisible() { setVisible(!isVisible()); if (isVisible()) { toFront(); requestFocus(); setAlwaysOnTop(true); try { //remember the last location of mouse final Point oldMouseLocation = MouseInfo.getPointerInfo().getLocation(); //simulate a mouse click on title bar of window Robot robot = new Robot(); robot.mouseMove(mainFrame.getX() + 100, mainFrame.getY() + 5); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); //move mouse to old location robot.mouseMove((int) oldMouseLocation.getX(), (int) oldMouseLocation.getY()); } catch (Exception ex) { //just ignore exception, or you can handle it as you want } finally { setAlwaysOnTop(false); } } } //... }

Y esto funciona perfectamente en mi Fedora KDE 14 :-)


Aquí hay un método que REALMENTE funciona (probado en Windows Vista): D

frame.setExtendedState(JFrame.ICONIFIED); frame.setExtendedState(fullscreen ? JFrame.MAXIMIZED_BOTH : JFrame.NORMAL);

La variable de pantalla completa indica si desea que la aplicación se ejecute en pantalla completa o en una ventana.

Esto no muestra la barra de tareas, pero lleva la ventana al frente de manera confiable.


Una posible solución es:

java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { myFrame.toFront(); myFrame.repaint(); } });


Para evitar que la ventana pierda el foco cuando vuelve a ser visible después de ocultarse, todo lo que se necesita es:

setExtendedState(JFrame.NORMAL);

Al igual que:

defaultItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showWindow(); setExtendedState(JFrame.NORMAL); } });


Windows tiene la capacidad de evitar que Windows se robe el foco; en su lugar, muestra el ícono de la barra de tareas. En XP está activado por defecto (el único lugar que he visto para cambiarlo es usando TweakUI, pero hay una configuración de registro en algún lugar). En Vista, es posible que hayan cambiado el valor predeterminado y / o lo hayan expuesto como una configuración accesible para el usuario con la interfaz de usuario lista para usar.

Evitar que Windows se fuerce al frente y se enfoquen es una característica desde Windows 2K (y yo, por mi parte, estoy agradecido por ello).

Dicho esto, tengo una pequeña aplicación Java que uso para recordarme que grabe mis actividades mientras trabajo, y se convierte en la ventana activa cada 30 minutos (configurable, por supuesto). Siempre funciona de manera consistente en Windows XP y nunca parpadea la ventana de la barra de título. Utiliza el siguiente código, llamado en el subproceso de UI como resultado de un disparo de evento de temporizador:

if(getState()!=Frame.NORMAL) { setState(Frame.NORMAL); } toFront(); repaint();

(la primera línea se restablece si se minimiza ... en realidad la restauraría si se maximiza también, pero nunca la tengo).

Aunque generalmente tengo esta aplicación minimizada, con frecuencia simplemente está detrás de mi editor de texto. Y, como dije, siempre funciona.

Tengo una idea sobre cuál podría ser tu problema: quizás tengas una condición de carrera con la llamada a setVisible (). toFront () puede no ser válido a menos que la ventana se muestre realmente cuando se invoca; He tenido este problema con requestFocus () antes. Es posible que deba colocar la llamada toFront () en un escucha UI en un evento activado por ventana.

2014-09-07: En algún punto en el tiempo, el código anterior dejó de funcionar, tal vez en Java 6 o 7. Después de un poco de investigación y experimentación, tuve que actualizar el código para reemplazar el método toFront la ventana, hacer esto (junto con el código modificado de lo que está arriba):

setVisible(true); toFront(); requestFocus(); repaint(); ... public @Override void toFront() { int sta = super.getExtendedState() & ~JFrame.ICONIFIED & JFrame.NORMAL; super.setExtendedState(sta); super.setAlwaysOnTop(true); super.toFront(); super.requestFocus(); super.setAlwaysOnTop(false); }

A partir de Java 8_20, este código parece estar funcionando bien.


Tuve el mismo problema al llevar un JFrame al frente en Ubuntu (Java 1.6.0_10). Y la única forma en que puedo resolverlo es proporcionando un WindowListener . Específicamente, tuve que configurar mi JFrame para que siempre permanezca en la cima siempre que toFront() y proporcione el controlador de eventos setAlwaysOnTop(false) a setAlwaysOnTop(false) .

Entonces, aquí está el código que podría colocarse en un JFrame base, que se usa para derivar todos los marcos de la aplicación.

@Override public void setVisible(final boolean visible) { // make sure that frame is marked as not disposed if it is asked to be visible if (visible) { setDisposed(false); } // let''s handle visibility... if (!visible || !isVisible()) { // have to check this condition simply because super.setVisible(true) invokes toFront if frame was already visible super.setVisible(visible); } // ...and bring frame to the front.. in a strange and weird way if (visible) { toFront(); } } @Override public void toFront() { super.setVisible(true); int state = super.getExtendedState(); state &= ~JFrame.ICONIFIED; super.setExtendedState(state); super.setAlwaysOnTop(true); super.toFront(); super.requestFocus(); super.setAlwaysOnTop(false); }

Siempre que su marco se muestre o se llame al frente, llame a frame.setVisible(true) .

Desde que me mudé a Ubuntu 9.04 no parece haber necesidad de tener un WindowListener para invocar a super.setAlwaysOnTop(false) - como se puede observar; este código se movió a los métodos toFront() y setVisible() .

Tenga en cuenta que el método setVisible() siempre debe invocarse en EDT.


Probé tus respuestas y solo la de Stefan Reich funcionó para mí. Aunque no logré restaurar la ventana a su estado anterior (maximizado / normal). Encontré esta mutación mejor:

view.setState(java.awt.Frame.ICONIFIED); view.setState(java.awt.Frame.NORMAL);

Eso es setState lugar de setExtendedState .