2011-09-13 16 views
9

El siguiente código de oscilación no funciona correctamente en mi máquina o máquinas de mis compañeros de trabajo (todos los Windows XP & Java 6):¿JFrame.setExtendedState (MAXIMIZED_BOTH) funciona con marcos sin decoración?

public class Test { 
    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(800, 600); 
     frame.setLayout(new FlowLayout()); 
     frame.add(new JButton(new AbstractAction("Maximize") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
      } 
     })); 
     frame.setUndecorated(true); 
     frame.setVisible(true); 
    } 
} 

Maximiza la ventana, pero no tiene en cuenta la tarea de las ventanas barra (llena la pantalla). Si comenta "frame.setUndecorated (true);" parece funcionar correctamente

El Javadoc parece implicar que esto debería funcionar. ¿Es esto un error en Java? ¿Está limitado a una versión específica o versión de Windows? ¿Hay alguna solución?

He visto un few workarounds, pero parecen incompletos. No puedo ser la primera persona en codificar mis propias decoraciones de marcos en Java.

EDIT: Después de descargar el OpenJDK y la excavación a través del código nativo, encontré que Java está llamando a la función Win32 SetWindowPlacement y bajo ciertas condiciones alterar MINMAXINFO para obtener el tamaño de la ventana derecha. Creo que lo que estaba viendo era el comportamiento de Windows predeterminado para una ventana sin título o borde (aunque no puedo encontrar eso documentado en ningún lugar). Descubrí que llamar a JFrame.setMaximizedBounds() proporciona los límites utilizados para modificar la estructura de win32 MINMAXINFO. Por lo tanto, alterando mi acción realizada y con el tamaño de la ventana sugerido por camickr como mis MaximizedBounds, me sale un poco más cerca:

GraphicsConfiguration graphicsConfiguration = frame.getGraphicsConfiguration(); 
frame.setMaximizedBounds(graphicsConfiguration.getBounds()); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 

Ahora el maximizar la ventana ya no se oculta la barra de menú. Pero ... ahora tengo otro problema. No puedo maximizar desde un monitor secundario. El marco simplemente desaparece.

Estoy agregando algunas etiquetas win32 con la esperanza de conseguir un programador C++ que reconozca este problema.

SOLUCIÓN: Parece que todavía no puedo responder mi propia pregunta, así que voy a poner mi solución aquí. Tuve que usar una clase Sol, y no he probado en ningún plataformas que no sean Windows, pero hasta ahora esto parece estar funcionando bien con múltiples monitores, y múltiples configuraciones de la barra de tareas:

GraphicsConfiguration config = frame.getGraphicsConfiguration(); 
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice()); 
frame.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, usableBounds.height)); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
+0

hay muchos hilos sobre, http://download.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html, en este foro – mKorbel

+0

Gracias, pero no estoy tratando de hacer una aplicación de pantalla completa . Probablemente debería haber sido más claro acerca de mis objetivos, pero estoy tratando de reemplazar la barra de título del sistema operativo y los controles con los míos (como Google Chrome, Microsoft Office, etc.). Sun incluso intentó hacerlo de la caja una vez, pero tienen el mismo problema que yo: 'frame.getRootPane(). SetWindowDecorationStyle (JRootPane.FRAME);' –

Respuesta

4

interesante. Cuando lo intento parece suceder en dos pasos. Primero se expande para llenar el espacio sobre la barra de tareas, luego una fracción de segundo más tarde cubre la barra de tareas. No tengo ni idea de porqué.

De todos modos para una solución que puede utilizar:

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
Rectangle bounds = env.getMaximumWindowBounds(); 
System.out.println("Screen Bounds: " + bounds); 

para establecer manualmente los límites de su marco cuando se desea maximizar la misma.

+0

Eso parece acercarme más, pero estableciendo los límites de la frame restablece el estado extendido a 'normal'. Podría crear mi propia subclase de trama y realizar un seguimiento de mis propios límites de estado extendido y anteriores, pero el sistema operativo no está al tanto de este estado simulado, y me traicionaría de maneras sutilmente pequeñas.Además, necesitaría encontrar la forma de obtener los límites de ventana en múltiples monitores. –

+0

Esa fue la idea para rastrear los límites y establecerse usted mismo. No sé cuáles podrían ser los problemas sutiles. No puedo ofrecer más consejos allí. Nunca he jugado con él, pero para múltiples monitores puedes mirar la clase 'GraphicsDevice'. – camickr