Comment centrer une fenêtre en Java?

113

Quelle est la façon la plus simple de centrer un java.awt.Window, comme un JFrameou un JDialog?

Andrew Swan
la source
2
Le titre devrait être "in Swing" et non "in Java", ce serait plus clair ainsi.
Joe Skora
6
@Joe setLocation(), setLocationRelativeTo()et setLocationByPlatform()ou tout AWT, pas Swing. ;)
Andrew Thompson

Réponses:

244

À partir de ce lien

Si vous utilisez Java 1.4 ou plus récent, vous pouvez utiliser la méthode simple setLocationRelativeTo (null) sur la boîte de dialogue, le cadre ou la fenêtre pour le centrer.

Andrew Swan
la source
9
Comme @kleopatra l'a dit sur une autre réponse, setLocationRelativeTo (null) doit être appelé après pack () pour fonctionner.
Eusebius
6
Comme expliqué ci-dessous, setLocationRelativeTo (null) doit être appelé après tout appel de pack () ou setSize ().
Arnaud P
2
@Eusebius Odd, j'ai suivi un tutoriel qui m'avait pack()amené à le définir avant et il a mis le coin supérieur du cadre au centre de mon écran. Après avoir déplacé la ligne en dessous, pack()elle a été correctement centrée.
user1433479
2
Eh bien pack () définit la taille correcte en fonction du contenu et de la mise en page, et vous ne pouvez pas centrer quelque chose à moins de connaître sa taille, il est donc étrange que le tutoriel vous ait fait emballer après l'avoir centré.
Andrew Swan
65

Cela devrait fonctionner dans toutes les versions 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
la source
Je sais que c'est assez vieux mais cela fonctionne bien, à condition que la taille du cadre soit définie avant d'appeler cette fonction
S.Krishna
1
Oui, assurez-vous que la taille est appliquée avant (en utilisant pack () par exemple)
Myoch
27

setLocationRelativeTo(null)doit être appelé après avoir utilisé setSize(x,y)ou utilisé pack().

Dzmitry Sevkovich
la source
Vous avez raison. Il doit avoir un appel setSize () avant.
Sai Dubbaka
26

Notez que les techniques setLocationRelativeTo (null) et Tookit.getDefaultToolkit (). GetScreenSize () ne fonctionnent que pour le moniteur principal. Si vous êtes dans un environnement à plusieurs moniteurs, vous devrez peut-être obtenir des informations sur le moniteur spécifique sur lequel se trouve la fenêtre avant de faire ce type de calcul.

Parfois important, parfois pas ...

Voir les javadocs GraphicsEnvironment pour plus d'informations sur la façon d'obtenir cela.

Kevin Day
la source
17

Sous Linux, le code

setLocationRelativeTo(null)

Mettez ma fenêtre à un emplacement aléatoire à chaque fois que je l'ai lancée, dans un environnement multi-affichage. Et le code

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

"couper" la fenêtre en deux en la plaçant au centre exact, qui est entre mes deux écrans. J'ai utilisé la méthode suivante pour le centrer:

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

Fait apparaître la fenêtre juste au centre du premier affichage. Ce n'est probablement pas la solution la plus simple.

Fonctionne correctement sur Linux, Windows et Mac.

Peter Szabo
la source
Prendre en compte les environnements multi-écrans est la seule bonne réponse, sinon l'écran où la fenêtre apparaît pourrait être quelque peu aléatoire ou la fenêtre est centrée entre les deux écrans.
Stephan
6

J'ai finalement fait fonctionner ce tas de codes dans NetBeans en utilisant Swing GUI Forms afin de centrer le 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
la source
3

Ce qui suit ne fonctionne pas pour JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Il place le coin supérieur gauche au centre - pas la même chose que le centrage de la fenêtre. L'autre ne fonctionne pas non plus, impliquant frame.getSize () et 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);

La méthode getSize () est héritée de la classe Component, et par conséquent frame.getSize renvoie également la taille de la fenêtre. Ainsi, en soustrayant la moitié des dimensions verticales et horizontales des dimensions verticales et horizontales, pour trouver les coordonnées x, y de l'endroit où placer le coin supérieur gauche, vous donne l'emplacement du point central, qui finit par centrer la fenêtre également. Cependant, la première ligne du code ci-dessus est utile, "Dimension ...". Faites ceci pour le centrer:

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

Le JLabel définit la taille de l'écran. Il est dans FrameDemo.java disponible sur les tutoriels java sur le site Oracle / Sun. Je l'ai mis à la moitié de la hauteur / largeur de la taille de l'écran. Ensuite, je l'ai centré en plaçant le coin supérieur gauche à 1/4 de la dimension de la taille de l'écran à partir de la gauche et à 1/4 de la dimension de la taille de l'écran à partir du haut. Vous pouvez utiliser un concept similaire.

Jonathan Caraballo
la source
1
Ni l'autre. Ces codes placent le coin supérieur gauche de l'écran au centre.
Jonathan Caraballo
7
-1 ne peut pas se reproduire - ou plus précisément: ne se produit que si le setLocationRelative est appelé avant de dimensionner le cadre (par pack ou setSize manuel). Pour un cadre de taille zéro, son coin supérieur gauche est au même endroit que .. son centre :-)
kleopatra
3

ci-dessous est le code pour afficher un cadre en haut au centre de la fenêtre existante.

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) lève l'exception {

new SwingContainerDemo().showJFrameDemo();

}

Vous trouverez ci-dessous la sortie de l'extrait de code ci-dessus:entrez la description de l'image ici

Aman Goel
la source
1
frame.setLocation(x, 0);semble être faux - ne devrait-il pas être à la frame.setLocation(x, y);place?
deem
x désigne la longueur de l'axe x et y désigne la longueur de l'axe y. Donc, si vous faites y = 0, alors seulement il devrait être en haut.
Aman Goel
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);Existe-t-il donc dans le code uniquement pour montrer que vous pouvez également centrer en axe vertical? Ok, je pensais que tu avais juste oublié de l'utiliser, désolé pour les ennuis.
deem le
Aucun problème. Considérer! C'est génial de vous parler.
Aman Goel le
2

Il y a quelque chose de vraiment simple que vous pourriez oublier après avoir essayé de centrer la fenêtre en utilisant soit setLocationRelativeTo(null)ou setLocation(x,y)et cela finit par être un peu décentré.

Assurez-vous d'utiliser l'une de ces méthodes après l' appel, pack()car vous finirez par utiliser les dimensions de la fenêtre elle-même pour calculer où la placer à l'écran. Jusqu'à ce que pack()soit appelé, les dimensions ne sont pas ce que vous penseriez, jetant ainsi les calculs pour centrer la fenêtre. J'espère que cela t'aides.

Clay Ellis
la source
2

Exemple: À l'intérieur de myWindow () sur la ligne 3 se trouve le code dont vous avez besoin pour définir la fenêtre au centre de l'écran.

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
la source
2

frame.setLocationRelativeTo (null);

Exemple complet:

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
la source
1

Le code suivant centre le Windowau centre du moniteur actuel (c'est-à-dire là où se trouve le pointeur de la souris).

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
la source
1

Vous pouvez également essayer ceci.

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);
mannequin gautam
la source
1
Qu'en est-il de plusieurs moniteurs?
Supuhstar
0

En fait, cadre .getHeight()et ne getwidth()renvoie pas de valeurs, vérifiez-le en System.out.println(frame.getHeight());mettant directement les valeurs de largeur et de hauteur, puis cela fonctionnera bien au centre. par exemple: comme ci-dessous

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

les deux 450 est ma largeur de cadre n hauteur

Viswanath Lekshmanan
la source
1
-1 la taille d'une image est zéro avant ... la dimensionner :-) De préférence par pack, ou du moins en définissant manuellement sa taille à autre chose que zéro avant d' appeler setLocationRelative permettra son calcul interne correct
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
la source
0

L'ordre des appels est important:

premier -

pack();

seconde -

setLocationRelativeTo(null);
Adir D
la source