Làm thế nào để căn giữa một Cửa sổ trong Java?


113

Cách dễ nhất để căn giữa a java.awt.Window, chẳng hạn như a JFramehoặc a là JDialoggì?


2
Tiêu đề nên là "trong Swing" chứ không phải "trong Java", theo cách đó sẽ rõ ràng hơn.
Joe Skora 28/09/08

6
@Joe setLocation(), setLocationRelativeTo()setLocationByPlatform()hoặc tất cả AWT, không phải Swing. ;)
Andrew Thompson

Câu trả lời:


244

Từ liên kết này

Nếu bạn đang sử dụng Java 1.4 hoặc mới hơn, bạn có thể sử dụng phương pháp đơn giản setLocationRelativeTo (null) trên hộp thoại, khung hoặc cửa sổ để căn giữa nó.


9
Như @kleopatra đã nói trong một câu trả lời khác, setLocationRelativeTo (null) phải được gọi sau pack () để hoạt động.
Eusebius

6
Như được giải thích bên dưới, setLocationRelativeTo (null) phải được gọi sau bất kỳ lệnh gọi pack () hoặc setSize () nào.
Arnaud P

2
@Eusebius Odd, tôi đã làm theo một hướng dẫn mà tôi đã đặt nó trước đó pack()và nó đặt góc trên cùng của khung ở giữa màn hình của tôi. Sau khi di chuyển dòng xuống dưới, pack()nó đã được căn giữa đúng cách.
user1433479

2
Well pack () đặt kích thước chính xác dựa trên nội dung và bố cục, và bạn không thể căn giữa thứ gì đó trừ khi bạn biết kích thước của nó, vì vậy thực sự là kỳ lạ khi hướng dẫn lại cho bạn đóng gói nó sau khi căn giữa nó.
Andrew Swan

65

Điều này sẽ hoạt động trong tất cả các phiên bản 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);
}

Tôi biết rằng cái này khá cũ nhưng cái này hoạt động tốt, miễn là kích thước khung hình được đặt trước khi gọi hàm này
S.Krishna

1
Yep, đảm bảo kích thước được áp dụng trước (sử dụng gói () ví dụ)
Myoch

27

setLocationRelativeTo(null)nên được gọi sau khi bạn sử dụng setSize(x,y)hoặc sử dụng pack().


Bạn đúng. Nó cần phải có lệnh gọi setSize () trước đó.
Sai Dubbaka

26

Lưu ý rằng cả kỹ thuật setLocationRelativeTo (null) và Tookit.getDefaultToolkit (). GetScreenSize () chỉ hoạt động cho màn hình chính. Nếu bạn đang ở trong môi trường nhiều màn hình, bạn có thể cần lấy thông tin về màn hình cụ thể mà cửa sổ đang bật trước khi thực hiện loại tính toán này.

Đôi khi quan trọng, đôi khi không ...

Xem javadocs GraphicsEnosystem để biết thêm thông tin về cách nhận được điều này.


17

Trên Linux, mã

setLocationRelativeTo(null)

Đặt cửa sổ của tôi đến vị trí ngẫu nhiên mỗi khi tôi khởi chạy nó, trong một môi trường nhiều màn hình. Và mã

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

"cắt" cửa sổ làm đôi bằng cách đặt nó vào chính giữa, nằm giữa hai màn hình của tôi. Tôi đã sử dụng phương pháp sau để căn giữa nó:

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àm cho cửa sổ xuất hiện ngay giữa màn hình đầu tiên. Đây có lẽ không phải là giải pháp dễ dàng nhất.

Hoạt động bình thường trên Linux, Windows và Mac.


Tính đến môi trường nhiều màn hình là câu trả lời đúng duy nhất, nếu không thì màn hình nơi cửa sổ xuất hiện có thể là ngẫu nhiên nào đó hoặc cửa sổ được căn giữa giữa cả hai màn hình.
Stephan

6

Cuối cùng tôi đã nhận được loạt mã này để hoạt động trong NetBeans bằng cách sử dụng Biểu mẫu Swing GUI để căn giữa jFrame chính:

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

}

HOẶC LÀ

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

}

HOẶC LÀ

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

3

Điều sau không hoạt động cho JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Nó đặt góc trên cùng bên trái ở giữa - không giống như căn giữa cửa sổ. Cái còn lại cũng không hoạt động, liên quan đến frame.getSize () vàmens.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);

Phương thức getSize () được kế thừa từ lớp Thành phần và do đó frame.getSize cũng trả về kích thước của cửa sổ. Do đó, trừ đi một nửa kích thước dọc và ngang cho các kích thước dọc và ngang, để tìm tọa độ x, y của vị trí đặt góc trên cùng bên trái, cung cấp cho bạn vị trí của điểm trung tâm, điểm này cũng sẽ căn giữa cửa sổ. Tuy nhiên, dòng đầu tiên của đoạn mã trên rất hữu ích, "Thứ nguyên ...". Chỉ cần làm điều này để căn giữa nó:

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 đặt kích thước màn hình. Nó có trong FrameDemo.java có sẵn trên các hướng dẫn java tại trang web Oracle / Sun. Tôi đặt nó thành một nửa chiều cao / chiều rộng của kích thước màn hình. Sau đó, tôi căn giữa nó bằng cách đặt trên cùng bên trái bằng 1/4 kích thước màn hình từ bên trái và 1/4 kích thước màn hình từ trên xuống. Bạn có thể sử dụng một khái niệm tương tự.


1
Cái khác cũng vậy. Các mã này đặt góc trên cùng bên trái của màn hình ở trung tâm.
Jonathan Caraballo,

7
-1 không thể tái tạo - hay chính xác hơn: chỉ xảy ra nếu setLocationRelative được gọi trước khi định cỡ khung (theo pack hoặc setSize thủ công). Đối với khung có kích thước bằng 0, góc trên cùng bên trái có cùng vị trí với .. trung tâm của nó :-)
kleopatra

3

dưới đây là mã để hiển thị khung ở trên cùng giữa cửa sổ hiện có.

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) ném Exception {

new SwingContainerDemo().showJFrameDemo();

}

Dưới đây là phần bổ sung của đoạn mã trên:nhập mô tả hình ảnh ở đây


1
frame.setLocation(x, 0);dường như là sai - không nên frame.setLocation(x, y);thay thế?
coi như

x biểu thị độ dài trục x và y biểu thị độ dài trục y. Vì vậy, nếu bạn làm cho y = 0 thì chỉ nó nên ở trên cùng.
Aman Goel

Vì vậy, int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);tồn tại trong mã chỉ để cho thấy rằng bạn cũng có thể căn giữa theo trục dọc? Ok, tôi nghĩ bạn quên sử dụng nó, xin lỗi vì sự cố.
coi như

Không vấn đề gì. Coi như! Thật tuyệt khi nói chuyện với bạn.
Aman Goel

2

Có một cái gì đó thực sự đơn giản mà bạn có thể nhìn ra sau khi cố gắng căn giữa cửa sổ bằng cách sử dụng một trong hai setLocationRelativeTo(null)hoặc setLocation(x,y)và cuối cùng nó hơi lệch giữa.

Đảm bảo rằng bạn sử dụng một trong các phương pháp này sau khi gọi pack()vì cuối cùng bạn sẽ sử dụng các kích thước của chính cửa sổ để tính toán vị trí đặt nó trên màn hình. Cho đến khi pack()được gọi, các kích thước không như bạn nghĩ, do đó loại bỏ các tính toán để căn giữa cửa sổ. Hi vọng điêu nay co ich.


2

Ví dụ: Bên trong myWindow () trên dòng 3 là mã bạn cần để đặt cửa sổ ở giữa màn hình.

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

2

frame.setLocationRelativeTo (null);

Ví dụ đầy đủ:

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

1

Đoạn mã sau tập trung Windowvào chính giữa màn hình hiện tại (tức là nơi đặt con trỏ chuột).

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

1

Bạn cũng có thể thử điều này.

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

1
Điều gì về nhiều màn hình?
Supuhstar

0

Trên thực tế khung .getHeight()getwidth()không trả về giá trị, hãy kiểm tra nó bằng cách System.out.println(frame.getHeight());đặt trực tiếp các giá trị cho chiều rộng và chiều cao, sau đó nó sẽ hoạt động tốt ở giữa. ví dụ: như bên dưới

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

cả 450 là chiều rộng khung hình của tôi n chiều cao


1
-1 kích thước của một khung là zero trước ... kích thước nó :-) Tốt bởi gói, hoặc ít nhất là bằng cách tự thiết lập kích thước của nó để bất cứ điều gì khác hơn không trước khi gọi setLocationRelative sẽ cho phép đúng tính nội bộ của mình
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);
    }
}

0

Thứ tự của các cuộc gọi là quan trọng:

đầu tiên -

pack();

thứ hai -

setLocationRelativeTo(null);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.