Wie zentriere ich ein Fenster in Java?

113

Was ist der einfachste Weg, um a zu zentrieren java.awt.Window, z. B. a JFrameoder a JDialog?

Andrew Swan
quelle
2
Der Titel sollte "in Swing" sein, nicht "in Java", so wäre es klarer.
Joe Skora
6
@ Joe setLocation(), setLocationRelativeTo()und setLocationByPlatform()oder alle AWT, nicht schwingen. ;)
Andrew Thompson

Antworten:

244

Von diesem Link

Wenn Sie Java 1.4 oder höher verwenden, können Sie die einfache Methode setLocationRelativeTo (null) im Dialogfeld, Frame oder Fenster verwenden, um es zu zentrieren.

Andrew Swan
quelle
9
Wie @kleopatra in einer anderen Antwort sagte, muss setLocationRelativeTo (null) nach pack () aufgerufen werden, um zu funktionieren.
Eusebius
5
Wie unten erläutert, muss setLocationRelativeTo (null) nach jedem Aufruf von pack () oder setSize () aufgerufen werden.
Arnaud P
1
@Eusebius Seltsam, ich folgte einem Tutorial, das mich dazu brachte, es vorher einzustellen, pack()und es platzierte die obere linke Ecke des Rahmens in der Mitte meines Bildschirms. Nachdem die Linie nach unten pack()verschoben wurde, wurde sie richtig zentriert.
user1433479
2
Nun, pack () legt die richtige Größe basierend auf Inhalt und Layout fest, und Sie können etwas nur zentrieren, wenn Sie seine Größe kennen. Es ist also seltsam, dass Sie es im Tutorial nach dem Zentrieren gepackt haben.
Andrew Swan
65

Dies sollte in allen Java-Versionen funktionieren

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
quelle
Ich weiß, dass dies ziemlich alt ist, aber dies funktioniert gut, vorausgesetzt, die Rahmengröße wird eingestellt, bevor diese Funktion
aufgerufen wird
1
Ja, stellen Sie sicher, dass die Größe vorher angewendet wird (zum Beispiel mit pack ())
Myoch
27

setLocationRelativeTo(null)sollte aufgerufen werden, nachdem Sie entweder verwenden setSize(x,y)oder verwenden pack().

Dzmitry Sevkovich
quelle
Du hast recht. SetSize () muss zuvor aufgerufen werden.
Sai Dubbaka
26

Beachten Sie, dass sowohl die Techniken setLocationRelativeTo (null) als auch Tookit.getDefaultToolkit (). GetScreenSize () nur für den primären Monitor funktionieren. Wenn Sie sich in einer Umgebung mit mehreren Monitoren befinden, müssen Sie möglicherweise Informationen zu dem bestimmten Monitor abrufen, auf dem sich das Fenster befindet, bevor Sie diese Art der Berechnung durchführen können.

Manchmal wichtig, manchmal nicht ...

Siehe GraphicsEnvironment javadocs für weitere Informationen darüber , wie diese zu erhalten.

Kevin Day
quelle
17

Unter Linux der Code

setLocationRelativeTo(null)

Stellen Sie mein Fenster bei jedem Start in einer Umgebung mit mehreren Anzeigen an einen zufälligen Ort. Und der Code

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

"Schneiden" Sie das Fenster in zwei Hälften, indem Sie es genau in der Mitte platzieren, die sich zwischen meinen beiden Displays befindet. Ich habe die folgende Methode verwendet, um es zu zentrieren:

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

Lässt das Fenster genau in der Mitte der ersten Anzeige erscheinen. Dies ist wahrscheinlich nicht die einfachste Lösung.

Funktioniert ordnungsgemäß unter Linux, Windows und Mac.

Peter Szabo
quelle
Die Berücksichtigung von Umgebungen mit mehreren Bildschirmen ist die einzig richtige Antwort. Andernfalls kann der Bildschirm, auf dem das Fenster angezeigt wird, zufällig sein oder das Fenster wird zwischen beiden Bildschirmen zentriert.
Stephan
6

Ich habe endlich diese Reihe von Codes in NetBeans mithilfe von Swing-GUI-Formularen erhalten, um den Haupt-jFrame zu zentrieren:

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

}

ODER

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

}

ODER

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

Folgendes funktioniert für JDK 1.7.0.07 nicht:

frame.setLocationRelativeTo(null);

Es platziert die obere linke Ecke in der Mitte - nicht dasselbe wie das Zentrieren des Fensters. Der andere funktioniert ebenfalls nicht und beinhaltet frame.getSize () und 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);

Die Methode getSize () wird von der Component-Klasse geerbt, und daher gibt frame.getSize auch die Größe des Fensters zurück. Wenn Sie also die Hälfte der vertikalen und horizontalen Abmessungen von den vertikalen und horizontalen Abmessungen abziehen, um die x- und y-Koordinaten für die Platzierung der oberen linken Ecke zu ermitteln, erhalten Sie die Position des Mittelpunkts, der auch das Fenster zentriert. Die erste Zeile des obigen Codes ist jedoch nützlich, "Dimension ...". Tun Sie dies einfach, um es zu zentrieren:

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

Das JLabel legt die Bildschirmgröße fest. Es befindet sich in FrameDemo.java und ist in den Java-Tutorials auf der Oracle / Sun-Site verfügbar. Ich habe es auf die Hälfte der Höhe / Breite der Bildschirmgröße eingestellt. Dann habe ich es zentriert, indem ich oben links 1/4 der Abmessung der Bildschirmgröße von links und 1/4 der Abmessung der Bildschirmgröße von oben platziert habe. Sie können ein ähnliches Konzept verwenden.

Jonathan Caraballo
quelle
1
Der andere auch nicht. Diese Codes platzieren die obere linke Ecke des Bildschirms in der Mitte.
Jonathan Caraballo
7
-1 kann nicht reproduziert werden - oder genauer: tritt nur auf, wenn setLocationRelative vor der Größenänderung des Frames aufgerufen wird (per Pack oder manuell setSize). Bei einem Rahmen mit der Größe Null befindet sich die obere linke Ecke an derselben Stelle wie die Mitte :-)
Kleopatra
3

Unten finden Sie einen Code zum Anzeigen eines Rahmens in der oberen Mitte des vorhandenen Fensters.

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öst eine Ausnahme aus {

new SwingContainerDemo().showJFrameDemo();

}}

Unten ist die Ausgabe des obigen Code-Snippets:Geben Sie hier die Bildbeschreibung ein

Aman Goel
quelle
1
frame.setLocation(x, 0);scheint falsch zu sein - sollte es nicht frame.setLocation(x, y);stattdessen sein?
erachten
x bezeichnet die Länge der x-Achse und y bezeichnet die Länge der y-Achse. Wenn Sie also y = 0 machen, sollte nur es oben sein.
Aman Goel
Gibt int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);es also nur Code, um zu zeigen, dass Sie auch in der vertikalen Achse zentrieren können? Ok, ich dachte du hast nur vergessen es zu benutzen, entschuldige den Ärger.
erachten
Kein Problem. Deem! Es ist großartig, mit Ihnen zu sprechen.
Aman Goel
2

Es gibt etwas wirklich Einfaches, das Sie möglicherweise übersehen, nachdem Sie versucht haben, das Fenster mit entweder setLocationRelativeTo(null)oder zu zentrieren, setLocation(x,y)und es endet etwas außerhalb der Mitte.

Stellen Sie sicher, dass Sie nach dem Aufruf eine dieser Methoden verwenden , pack()da Sie am Ende die Abmessungen des Fensters selbst verwenden, um zu berechnen, wo es auf dem Bildschirm platziert werden soll. Bis pack()es aufgerufen wird, sind die Dimensionen nicht das, was Sie denken würden, und werfen daher die Berechnungen ab, um das Fenster zu zentrieren. Hoffe das hilft.

Clay Ellis
quelle
2

Beispiel: In myWindow () in Zeile 3 befindet sich der Code, den Sie benötigen, um das Fenster in der Mitte des Bildschirms festzulegen.

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

frame.setLocationRelativeTo (null);

Vollständiges Beispiel:

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

Der folgende Code zentriert sich Windowin der Mitte des aktuellen Monitors (dh wo sich der Mauszeiger befindet).

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

Sie können dies auch versuchen.

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
quelle
1
Was ist mit mehreren Monitoren?
Supuhstar
0

Tatsächlich rahmen .getHeight()und geben getwidth()keine Werte zurück. Überprüfen Sie dies, indem Sie System.out.println(frame.getHeight());die Werte für Breite und Höhe direkt eingeben. Dann funktioniert es in der Mitte einwandfrei . zB: wie unten

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

beide 450 ist meine rahmenbreite n höhe

Viswanath Lekshmanan
quelle
1
-1 Die Größe eines Frames ist Null, bevor ... die Größe angepasst wird :-) Vorzugsweise durch Packen oder zumindest durch manuelles Einstellen der Größe auf etwas anderes als Null vor dem Aufruf von setLocationRelative ermöglicht die interne korrekte Berechnung
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
quelle