¿Cómo posicionar mejor las GUI de Swing?
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é?
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.
(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();
}
});
}
}
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);