¿Cómo centrar una ventana en Java?

113

¿Cuál es la forma más sencilla de centrar a java.awt.Window, como a JFrameo a JDialog?

Andrew Swan
fuente
2
El título debería estar "en Swing" no "en Java", sería más claro de esa manera.
Joe Skora
6
@ Joe setLocation(), setLocationRelativeTo()y setLocationByPlatform()todos o AWT, no swing. ;)
Andrew Thompson

Respuestas:

244

De este enlace

Si está usando Java 1.4 o más reciente, puede usar el método simple setLocationRelativeTo (null) en el cuadro de diálogo, marco o ventana para centrarlo.

Andrew Swan
fuente
9
Como dijo @kleopatra en otra respuesta, setLocationRelativeTo (null) debe llamarse después de pack () para que funcione.
Eusebio
6
Como se explica a continuación, setLocationRelativeTo (null) debe llamarse después de cualquier llamada de pack () o setSize ().
Arnaud P
2
@Eusebius Odd, seguí un tutorial que me hizo configurarlo antes pack()y puso la esquina superior izquierda del marco en el centro de mi pantalla. Después de mover la línea hacia abajo pack(), se centró correctamente.
user1433479
2
Bueno, pack () establece el tamaño correcto según el contenido y el diseño, y no puede centrar algo a menos que sepa su tamaño, por lo que es realmente extraño que el tutorial lo haya empacado después de centrarlo.
Andrew Swan
65

Esto debería funcionar en todas las versiones de Java

public static void centreWindow(Window frame) {
    Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
    int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
    frame.setLocation(x, y);
}
Dónal
fuente
Sé que esto es bastante antiguo, pero funciona bien, siempre que el tamaño del marco se establezca antes de llamar a esta función
S. Krishna
1
Sí, asegúrese de que el tamaño se aplique antes (usando pack () por ejemplo)
Myoch
27

setLocationRelativeTo(null)debe llamarse después de usar setSize(x,y)o usar pack().

Dzmitry Sevkovich
fuente
Tienes razón. Necesita haber llamado setSize () antes.
Sai Dubbaka
26

Tenga en cuenta que las técnicas setLocationRelativeTo (null) y Tookit.getDefaultToolkit (). GetScreenSize () funcionan solo para el monitor principal. Si se encuentra en un entorno de varios monitores, es posible que deba obtener información sobre el monitor específico en el que se encuentra la ventana antes de realizar este tipo de cálculo.

A veces importante, a veces no ...

Consulte los javadocs GraphicsEnvironment para obtener más información sobre cómo obtener esto.

Kevin Day
fuente
17

En Linux el código

setLocationRelativeTo(null)

Coloque mi ventana en una ubicación aleatoria cada vez que la inicie, en un entorno de múltiples pantallas. Y el codigo

setLocation((Toolkit.getDefaultToolkit().getScreenSize().width  - getSize().width) / 2, (Toolkit.getDefaultToolkit().getScreenSize().height - getSize().height) / 2);

"Cortar" la ventana por la mitad colocándola en el centro exacto, que está entre mis dos pantallas. Usé el siguiente método para centrarlo:

private void setWindowPosition(JFrame window, int screen)
{        
    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] allDevices = env.getScreenDevices();
    int topLeftX, topLeftY, screenX, screenY, windowPosX, windowPosY;

    if (screen < allDevices.length && screen > -1)
    {
        topLeftX = allDevices[screen].getDefaultConfiguration().getBounds().x;
        topLeftY = allDevices[screen].getDefaultConfiguration().getBounds().y;

        screenX  = allDevices[screen].getDefaultConfiguration().getBounds().width;
        screenY  = allDevices[screen].getDefaultConfiguration().getBounds().height;
    }
    else
    {
        topLeftX = allDevices[0].getDefaultConfiguration().getBounds().x;
        topLeftY = allDevices[0].getDefaultConfiguration().getBounds().y;

        screenX  = allDevices[0].getDefaultConfiguration().getBounds().width;
        screenY  = allDevices[0].getDefaultConfiguration().getBounds().height;
    }

    windowPosX = ((screenX - window.getWidth())  / 2) + topLeftX;
    windowPosY = ((screenY - window.getHeight()) / 2) + topLeftY;

    window.setLocation(windowPosX, windowPosY);
}

Hace que la ventana aparezca justo en el centro de la primera pantalla. Probablemente esta no sea la solución más sencilla.

Funciona correctamente en Linux, Windows y Mac.

Peter Szabo
fuente
Tener en cuenta los entornos multipantalla es la única respuesta correcta; de lo contrario, la pantalla donde aparece la ventana podría ser algo aleatoria o la ventana estaría centrada entre ambas pantallas.
Stephan
6

Finalmente conseguí que este montón de códigos funcionara en NetBeans usando Swing GUI Forms para centrar el jFrame principal:

package my.SampleUIdemo;
import java.awt.*;

public class classSampleUIdemo extends javax.swing.JFrame {
    /// 
    public classSampleUIdemo() {
        initComponents();
        CenteredFrame(this);  // <--- Here ya go.
    }
    // ...
    // void main() and other public method declarations here...

    ///  modular approach
    public void CenteredFrame(javax.swing.JFrame objFrame){
        Dimension objDimension = Toolkit.getDefaultToolkit().getScreenSize();
        int iCoordX = (objDimension.width - objFrame.getWidth()) / 2;
        int iCoordY = (objDimension.height - objFrame.getHeight()) / 2;
        objFrame.setLocation(iCoordX, iCoordY); 
    } 

}

O

package my.SampleUIdemo;
import java.awt.*;

public class classSampleUIdemo extends javax.swing.JFrame {
        /// 
        public classSampleUIdemo() {
            initComponents(); 
            //------>> Insert your code here to center main jFrame.
            Dimension objDimension = Toolkit.getDefaultToolkit().getScreenSize();
            int iCoordX = (objDimension.width - this.getWidth()) / 2;
            int iCoordY = (objDimension.height - this.getHeight()) / 2;
            this.setLocation(iCoordX, iCoordY); 
            //------>> 
        } 
        // ...
        // void main() and other public method declarations here...

}

O

    package my.SampleUIdemo;
    import java.awt.*;
    public class classSampleUIdemo extends javax.swing.JFrame {
         /// 
         public classSampleUIdemo() {
             initComponents();
             this.setLocationRelativeTo(null);  // <<--- plain and simple
         }
         // ...
         // void main() and other public method declarations here...
   }
TheLooker
fuente
3

Lo siguiente no funciona para JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Coloca la esquina superior izquierda en el centro, no lo mismo que centrar la ventana. El otro tampoco funciona, involucrando frame.getSize () y dimension.getSize ():

Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
frame.setLocation(x, y);

El método getSize () se hereda de la clase Component y, por lo tanto, frame.getSize también devuelve el tamaño de la ventana. Por lo tanto, restando la mitad de las dimensiones vertical y horizontal de las dimensiones vertical y horizontal, para encontrar las coordenadas x, y de dónde colocar la esquina superior izquierda, obtiene la ubicación del punto central, que termina centrando la ventana también. Sin embargo, la primera línea del código anterior es útil, "Dimensión ...". Solo haz esto para centrarlo:

Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension( (int)dimension.getWidth() / 2, (int)dimension.getHeight()/2 ));
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
frame.setLocation((int)dimension.getWidth()/4, (int)dimension.getHeight()/4);

JLabel establece el tamaño de la pantalla. Está en FrameDemo.java disponible en los tutoriales de Java en el sitio de Oracle / Sun. Lo configuré a la mitad del alto / ancho del tamaño de la pantalla. Luego, lo centré colocando la parte superior izquierda en 1/4 de la dimensión del tamaño de la pantalla desde la izquierda, y 1/4 de la dimensión del tamaño de la pantalla desde la parte superior. Puede utilizar un concepto similar.

Jonathan Caraballo
fuente
1
Tampoco el otro. Estos códigos colocan la esquina superior izquierda de la pantalla en el centro.
Jonathan Caraballo
7
-1 no se puede reproducir, o más precisamente: ocurre solo si se llama a setLocationRelative antes de dimensionar el marco (por paquete o setSize manual). Para un marco de tamaño cero, la esquina superior izquierda es la misma ubicación que ... su centro :-)
kleopatra
3

a continuación se muestra el código para mostrar un marco en la parte superior central de la ventana existente.

public class SwingContainerDemo {

private JFrame mainFrame;

private JPanel controlPanel;

private JLabel msglabel;

Frame.setLayout(new FlowLayout());

  mainFrame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent windowEvent){
        System.exit(0);
     }        
  });    
  //headerLabel = new JLabel("", JLabel.CENTER);        
 /* statusLabel = new JLabel("",JLabel.CENTER);    
  statusLabel.setSize(350,100);
 */ msglabel = new JLabel("Welcome to TutorialsPoint SWING Tutorial.", JLabel.CENTER);

  controlPanel = new JPanel();
  controlPanel.setLayout(new FlowLayout());

  //mainFrame.add(headerLabel);
  mainFrame.add(controlPanel);
 // mainFrame.add(statusLabel);

  mainFrame.setUndecorated(true);
  mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  mainFrame.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
  mainFrame.setVisible(true);  

  centreWindow(mainFrame);

}

public static void centreWindow(Window frame) {
    Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
    int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
    frame.setLocation(x, 0);
}


public void showJFrameDemo(){
 /* headerLabel.setText("Container in action: JFrame");   */
  final JFrame frame = new JFrame();
  frame.setSize(300, 300);
  frame.setLayout(new FlowLayout());       
  frame.add(msglabel);

  frame.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent windowEvent){
        frame.dispose();
     }        
  });    



  JButton okButton = new JButton("Capture");
  okButton.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
  //      statusLabel.setText("A Frame shown to the user.");
      //  frame.setVisible(true);
        mainFrame.setState(Frame.ICONIFIED);
        Robot robot = null;
        try {
            robot = new Robot();
        } catch (AWTException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        final Dimension screenSize = Toolkit.getDefaultToolkit().
                getScreenSize();
        final BufferedImage screen = robot.createScreenCapture(
                new Rectangle(screenSize));

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ScreenCaptureRectangle(screen);
            }
        });
        mainFrame.setState(Frame.NORMAL);
     }
  });
  controlPanel.add(okButton);
  mainFrame.setVisible(true);  

} public static void main (String [] args) arroja Exception {

new SwingContainerDemo().showJFrameDemo();

}

A continuación se muestra el resultado del fragmento de código anterior:ingrese la descripción de la imagen aquí

Aman Goel
fuente
1
frame.setLocation(x, 0);parece estar mal, ¿no debería ser frame.setLocation(x, y);en su lugar?
Considere el
x denota la longitud del eje x e y denota la longitud del eje y. Entonces, si hace y = 0, solo debería estar en la parte superior.
Aman Goel
Entonces int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);, ¿ existe en el código solo para mostrar que también puede centrarse en el eje vertical? Ok, pensé que te habías olvidado de usarlo, perdón por los problemas.
Considere el
No hay problema. ¡Considerar! Es genial hablar contigo.
Aman Goel
2

Hay algo realmente simple que podrías estar pasando por alto después de intentar centrar la ventana usando setLocationRelativeTo(null)o setLocation(x,y)y termina estando un poco descentrado.

Asegúrese de usar cualquiera de estos métodos después de llamar pack()porque terminará usando las dimensiones de la ventana para calcular dónde colocarla en la pantalla. Hasta que pack()se llame, las dimensiones no son lo que pensaría, por lo tanto, descarta los cálculos para centrar la ventana. Espero que esto ayude.

Clay Ellis
fuente
2

Ejemplo: Dentro de myWindow () en la línea 3 está el código que necesita para configurar la ventana en el centro de la pantalla.

JFrame window;

public myWindow() {

    window = new JFrame();
    window.setSize(1200,800);
    window.setLocationRelativeTo(null); // this line set the window in the center of thr screen
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setBackground(Color.BLACK);
    window.setLayout(null); // disable the default layout to use custom one.
    window.setVisible(true); // to show the window on the screen.
}
Marinel P
fuente
2

frame.setLocationRelativeTo (nulo);

Ejemplo completo:

public class BorderLayoutPanel {

    private JFrame mainFrame;
    private JButton btnLeft, btnRight, btnTop, btnBottom, btnCenter;

    public BorderLayoutPanel() {
        mainFrame = new JFrame("Border Layout Example");
        btnLeft = new JButton("LEFT");
        btnRight = new JButton("RIGHT");
        btnTop = new JButton("TOP");
        btnBottom = new JButton("BOTTOM");
        btnCenter = new JButton("CENTER");
    }

    public void SetLayout() {
        mainFrame.add(btnTop, BorderLayout.NORTH);
        mainFrame.add(btnBottom, BorderLayout.SOUTH);
        mainFrame.add(btnLeft, BorderLayout.EAST);
        mainFrame.add(btnRight, BorderLayout.WEST);
        mainFrame.add(btnCenter, BorderLayout.CENTER);
        //        mainFrame.setSize(200, 200);
        //        or
        mainFrame.pack();
        mainFrame.setVisible(true);

        //take up the default look and feel specified by windows themes
        mainFrame.setDefaultLookAndFeelDecorated(true);

        //make the window startup position be centered
        mainFrame.setLocationRelativeTo(null);

        mainFrame.setDefaultCloseOperation(mainFrame.EXIT_ON_CLOSE);
    }
}
Thulani Chivandikwa
fuente
1

El siguiente código centra el Windowen el centro del monitor actual (es decir, donde se encuentra el puntero del mouse).

public static final void centerWindow(final Window window) {
    GraphicsDevice screen = MouseInfo.getPointerInfo().getDevice();
    Rectangle r = screen.getDefaultConfiguration().getBounds();
    int x = (r.width - window.getWidth()) / 2 + r.x;
    int y = (r.height - window.getHeight()) / 2 + r.y;
    window.setLocation(x, y);
}
Julien
fuente
1

También puedes probar esto.

Frame frame = new Frame("Centered Frame");
Dimension dimemsion = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dimemsion.width/2-frame.getSize().width/2, dimemsion.height/2-frame.getSize().height/2);
manikant gautam
fuente
1
¿Qué pasa con varios monitores?
Supuhstar
0

En realidad, el marco .getHeight()y getwidth()no devuelve valores, verifíquelo colocando System.out.println(frame.getHeight());directamente los valores de ancho y alto, luego funcionará bien en el centro. por ejemplo: como a continuación

Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();      
int x=(int)((dimension.getWidth() - 450)/2);
int y=(int)((dimension.getHeight() - 450)/2);
jf.setLocation(x, y);  

ambos 450 es mi marco ancho y alto

Viswanath Lekshmanan
fuente
1
-1 el tamaño de un marco es cero antes ... dimensionarlo :-) Preferiblemente por paquete, o al menos configurando manualmente su tamaño en cualquier otro valor que no sea cero antes de llamar a setLocationRelative permitirá su cálculo interno correcto
kleopatra
0
public class SwingExample implements Runnable {

    @Override
    public void run() {
        // Create the window
        final JFrame f = new JFrame("Hello, World!");
        SwingExample.centerWindow(f);
        f.setPreferredSize(new Dimension(500, 250));
        f.setMaximumSize(new Dimension(10000, 200));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public static void centerWindow(JFrame frame) {
        Insets insets = frame.getInsets();
        frame.setSize(new Dimension(insets.left + insets.right + 500, insets.top + insets.bottom + 250));
        frame.setVisible(true);
        frame.setResizable(false);

        Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) ((dimension.getWidth() - frame.getWidth()) / 2);
        int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);
        frame.setLocation(x, y);
    }
}
borchvm
fuente
0

El orden de las llamadas es importante:

primero -

pack();

segundo -

setLocationRelativeTo(null);
Adir D
fuente