Como centralizar uma janela em Java?

113

Qual é a maneira mais fácil de centralizar a java.awt.Window, como a JFrameou a JDialog?

Andrew Swan
fonte
2
O título deve ser "em Swing" e não "em Java", ficaria mais claro dessa forma.
Joe Skora
6
@Joe setLocation(), setLocationRelativeTo()e setLocationByPlatform()ou todos AWT, não Swing. ;)
Andrew Thompson,

Respostas:

244

Deste link

Se estiver usando Java 1.4 ou mais recente, você pode usar o método simples setLocationRelativeTo (null) na caixa de diálogo, quadro ou janela para centralizá-lo.

Andrew Swan
fonte
9
Como @kleopatra disse em outra resposta, setLocationRelativeTo (null) deve ser chamado após pack () para funcionar.
Eusébio de
6
Conforme explicado abaixo, setLocationRelativeTo (null) deve ser chamado após qualquer chamada de pack () ou setSize ().
Arnaud P
2
@Eusebius Odd, segui um tutorial que me fez configurá-lo antes pack()e colocou o canto superior esquerdo do quadro no centro da tela. Depois de mover a linha para baixo, pack()ela ficou devidamente centralizada.
user1433479
2
Bem, pack () define o tamanho correto com base no conteúdo e no layout, e você não pode centralizar algo a menos que saiba seu tamanho, então é realmente estranho que o tutorial o tenha empacotado depois de centralizado.
Andrew Swan
65

Isso deve funcionar em todas as versões do 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
fonte
Eu sei que isso é muito antigo, mas funciona bem, desde que o tamanho do quadro seja definido antes de chamar esta função
S.Krishna
1
Sim, certifique-se de que o tamanho seja aplicado antes (usando pack () por exemplo)
Myoch
27

setLocationRelativeTo(null)deve ser chamado depois de usar setSize(x,y)ou usar pack().

Dzmitry Sevkovich
fonte
Você está certo. Ele precisa ter a chamada setSize () antes.
Sai Dubbaka de
26

Observe que as técnicas setLocationRelativeTo (null) e Tookit.getDefaultToolkit (). GetScreenSize () funcionam apenas para o monitor principal. Se você estiver em um ambiente de vários monitores, pode ser necessário obter informações sobre o monitor específico em que a janela está antes de fazer esse tipo de cálculo.

Às vezes importante, às vezes não ...

Consulte GraphicsEnvironment javadocs para obter mais informações sobre como fazer isso.

Kevin Day
fonte
17

No Linux, o código

setLocationRelativeTo(null)

Colocar minha janela em um local aleatório sempre que a iniciar, em um ambiente com vários monitores. E o código

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

"corte" a janela ao meio colocando-a exatamente no centro, que fica entre meus dois monitores. Usei o seguinte método para centralizá-lo:

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);
}

Faz a janela aparecer bem no centro da primeira tela. Esta provavelmente não é a solução mais fácil.

Funciona corretamente em Linux, Windows e Mac.

Peter Szabo
fonte
Levar em consideração os ambientes de várias telas é a única resposta correta, caso contrário, a tela onde a janela aparece pode ser aleatória ou a janela está centralizada entre as duas telas.
Stephan
6

Finalmente consegui que esse monte de códigos funcionasse no NetBeans usando Swing GUI Forms para centralizar o 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); 
    } 

}

OU

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...

}

OU

    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
fonte
3

O seguinte não funciona para JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Ele coloca o canto superior esquerdo no centro - não o mesmo que centralizar a janela. O outro também não funciona, envolvendo frame.getSize () e 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);

O método getSize () é herdado da classe Component e, portanto, frame.getSize retorna o tamanho da janela também. Assim, subtraindo metade das dimensões vertical e horizontal das dimensões vertical e horizontal, para encontrar as coordenadas x, y de onde colocar o canto superior esquerdo, você obtém a localização do ponto central, que acaba centralizando a janela também. No entanto, a primeira linha do código acima é útil, "Dimensão ...". Basta fazer isso para centralizá-lo:

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);

O JLabel define o tamanho da tela. Está em FrameDemo.java disponível nos tutoriais java no site Oracle / Sun. Eu o defini para a metade da altura / largura do tamanho da tela. Em seguida, centrei-o colocando o canto superior esquerdo em 1/4 da dimensão do tamanho da tela a partir da esquerda e 1/4 da dimensão do tamanho da tela a partir do topo. Você pode usar um conceito semelhante.

Jonathan Caraballo
fonte
1
Nem o outro. Esses códigos colocam o canto superior esquerdo da tela no centro.
Jonathan Caraballo
7
-1 não pode reproduzir - ou mais precisamente: acontece apenas se setLocationRelative for chamado antes do dimensionamento do quadro (por pacote ou setSize manual). Para um quadro de tamanho zero, seu canto superior esquerdo é o mesmo local ... seu centro :-)
kleopatra
3

abaixo está o código para exibir um quadro na parte superior central da janela 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) lança Exception {

new SwingContainerDemo().showJFrameDemo();

}

Abaixo está a saída do snippet de código acima:insira a descrição da imagem aqui

Aman Goel
fonte
1
frame.setLocation(x, 0);parece estar errado - não deveria estar frame.setLocation(x, y);?
julgue
x denota o comprimento do eixo x ey denota o comprimento do eixo y. Portanto, se você fizer y = 0, apenas ele deve estar no topo.
Aman Goel de
Então int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);existe no código apenas para mostrar que você também pode centralizar no eixo vertical? Ok, pensei que você simplesmente esqueceu de usar, desculpe pelo problema.
julgue
Sem problemas. Deem! É ótimo falar com você.
Aman Goel
2

Há algo realmente simples que você pode estar esquecendo depois de tentar centralizar a janela usando setLocationRelativeTo(null)ou setLocation(x,y)e acaba ficando um pouco fora do centro.

Certifique-se de usar qualquer um desses métodos após a chamada, pack()porque você acabará usando as dimensões da própria janela para calcular onde colocá-la na tela. Até que pack()seja chamado, as dimensões não são o que você pensaria, descartando assim os cálculos para centralizar a janela. Espero que isto ajude.

Clay Ellis
fonte
2

Exemplo: Dentro de myWindow () na linha 3 está o código de que você precisa para definir a janela no centro da tela.

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
fonte
2

frame.setLocationRelativeTo (null);

Exemplo 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
fonte
1

O código a seguir é centralizado Windowno centro do monitor atual (ou seja, onde o ponteiro do mouse está localizado).

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
fonte
1

Você também pode tentar isso.

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
fonte
1
E quanto a vários monitores?
Supuhstar
0

Na verdade enquadra .getHeight()e getwidth()não retorna valores, verifique System.out.println(frame.getHeight());colocando diretamente os valores de largura e altura, então funcionará bem no centro. por exemplo: como abaixo

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 são a largura e a altura do meu quadro

Viswanath Lekshmanan
fonte
1
-1 o tamanho de um quadro é zero antes de ... dimensioná-lo :-) De preferência por pacote, ou pelo menos definindo manualmente seu tamanho para qualquer coisa diferente de zero antes de chamar setLocationRelative permitirá seu cálculo interno correto
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
fonte
0

A ordem das chamadas é importante:

primeiro -

pack();

segundo -

setLocationRelativeTo(null);
Adir D
fonte