¿Cómo posicionar mejor las GUI de Swing?

Resuelto Hovercraft Full Of Eels asked hace 13 años • 2 respuestas

En otro hilo dije que me gustaba centrar mis GUI haciendo algo como esto:

JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new HexagonGrid());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

Pero Andrew Thompson tenía una opinión diferente y, en cambio, llamó

frame.pack();
frame.setLocationByPlatform(true);

y las mentes inquisitivas quieren saber ¿por qué?

Hovercraft Full Of Eels avatar Aug 22 '11 11:08 Hovercraft Full Of Eels
Aceptado

En mi opinión, una GUI en el medio de la pantalla se ve tan... "como una pantalla de presentación". ¡Sigo esperando a que desaparezcan y aparezca la GUI real !

Desde Java 1.5 hemos tenido acceso a Window.setLocationByPlatform(boolean). cual..

Establece si esta ventana debe aparecer en la ubicación predeterminada para el sistema de ventanas nativo o en la ubicación actual (devuelta por getLocation) la próxima vez que la ventana se haga visible. Este comportamiento se asemeja a una ventana nativa que se muestra sin establecer su ubicación mediante programación. La mayoría de los sistemas de ventanas colocan ventanas en cascada si sus ubicaciones no están establecidas explícitamente. La ubicación real se determina una vez que se muestra la ventana en la pantalla.

Eche un vistazo al efecto de este ejemplo que coloca 3 GUI en las posiciones predeterminadas elegidas por el sistema operativo: en Windows 7, Linux con Gnome y Mac OS X.

Ventanas apiladas en Windows 7 ingrese la descripción de la imagen aquí Ventanas apiladas en Mac OS X

(3 lotes de) 3 GUI cuidadosamente apiladas. Esto representa "el camino de menor sorpresa" para el usuario final, ya que es la forma en que el sistema operativo podría posicionar 3 instancias del editor de texto sin formato predeterminado (o cualquier otra cosa, de hecho). Mi agradecimiento a trashgod por Linux y Mac. imágenes.

Aquí está el código simple utilizado:

import javax.swing.*;

class WhereToPutTheGui {

    public static void initGui() {
        for (int ii=1; ii<4; ii++) {
            JFrame f = new JFrame("Frame " + ii);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            String s =
                "os.name: " + System.getProperty("os.name") +
                "\nos.version: " + System.getProperty("os.version");
            f.add(new JTextArea(s,3,28));  // suggest a size
            f.pack();
            // Let the OS handle the positioning!
            f.setLocationByPlatform(true);
            f.setVisible(true);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {}
                initGui();
            }
        });
    }
}
Andrew Thompson avatar Aug 22 '2011 05:08 Andrew Thompson

Estoy totalmente de acuerdo en que setLocationByPlatform(true)es la mejor manera de especificar la posición de un nuevo JFrame, pero en una configuración de monitor dual puedes tener problemas. En mi caso, el JFrame secundario se genera en "el otro" monitor. Ejemplo: tengo mi GUI principal en la Pantalla 2, inicio un nuevo JFrame setLocationByPlatform(true)y se abre en la Pantalla 1. Así que aquí hay una solución más completa, creo:

...
// Let the OS try to handle the positioning!
f.setLocationByPlatform(true);
if (!f.getBounds().intersects(MyApp.getMainFrame().getBounds())) {
    // non-cascading, but centered on the Main GUI
    f.setLocationRelativeTo(MyApp.getMainFrame()); 
}
f.setVisible(true);
Axel Podehl avatar Sep 19 '2017 11:09 Axel Podehl