วิธีตั้งศูนย์หน้าต่างใน Java


113

เป็นวิธีที่ง่ายที่สุดในการศูนย์java.awt.Windowเช่นJFrameหรือJDialog?


3
ชื่อควรเป็น "ใน Swing" ไม่ใช่ "ใน Java" ซึ่งจะชัดเจนกว่าในลักษณะนั้น
Joe Skora

6
@ Joe setLocation(), setLocationRelativeTo()และsetLocationByPlatform()หรือ AWT ทั้งหมดไม่แกว่ง ;)
Andrew Thompson

คำตอบ:


244

จากลิงค์นี้

หากคุณใช้ Java 1.4 หรือใหม่กว่าคุณสามารถใช้เมธอดง่ายๆ setLocationRelativeTo (null) บนไดอะล็อกบ็อกซ์เฟรมหรือหน้าต่างเพื่อจัดกึ่งกลาง


9
ดังที่ @kleopatra กล่าวในคำตอบอื่น setLocationRelativeTo (null) จะต้องถูกเรียกหลังจาก pack () เพื่อให้ทำงานได้
Eusebius

6
ตามที่อธิบายไว้ด้านล่าง setLocationRelativeTo (null) จะต้องถูกเรียกหลังจากการเรียกใช้ pack () หรือ setSize ()
Arnaud P

2
@Eusebius Odd ฉันทำตามแบบฝึกหัดที่ทำให้ฉันตั้งค่าไว้ก่อนหน้านี้pack()และวางมุมด้านบนสุดของเฟรมไว้ตรงกลางหน้าจอ หลังจากเลื่อนเส้นไปด้านล่างpack()แล้วมันก็อยู่กึ่งกลางอย่างถูกต้อง
user1433479

2
Well pack () กำหนดขนาดที่ถูกต้องตามเนื้อหาและเค้าโครงและคุณไม่สามารถจัดกึ่งกลางบางสิ่งบางอย่างได้เว้นแต่คุณจะรู้ขนาดของมันดังนั้นจึงเป็นเรื่องแปลกที่บทช่วยสอนให้คุณบรรจุมันหลังจากจัดกึ่งกลาง
Andrew Swan

65

สิ่งนี้ควรใช้ได้กับ 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);
}

ฉันรู้ว่ามันค่อนข้างเก่า แต่ก็ใช้ได้ดีหากตั้งขนาดเฟรมไว้ก่อนที่จะเรียกใช้ฟังก์ชันนี้
S.Krishna

1
ใช่ตรวจสอบให้แน่ใจว่าใช้ขนาดก่อน (ใช้แพ็ค () เช่น)
Myoch

27

setLocationRelativeTo(null)ควรจะเรียกว่าหลังจากที่คุณใช้อย่างใดอย่างหนึ่งหรือการใช้งานsetSize(x,y)pack()


คุณถูก. จำเป็นต้องมีการเรียก setSize () มาก่อน
Sai Dubbaka

26

โปรดสังเกตว่าทั้งเทคนิค setLocationRelativeTo (null) และ Tookit.getDefaultToolkit () getScreenSize () ใช้ได้กับจอภาพหลักเท่านั้น หากคุณอยู่ในสภาพแวดล้อมแบบหลายจอภาพคุณอาจต้องได้รับข้อมูลเกี่ยวกับจอภาพเฉพาะที่หน้าต่างเปิดอยู่ก่อนที่จะทำการคำนวณประเภทนี้

บางครั้งสำคัญบางครั้งก็ไม่ ...

โปรดดูJavadocs GraphicsEnvironmentสำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีรับสิ่งนี้


17

บน Linux รหัส

setLocationRelativeTo(null)

วางหน้าต่างของฉันไว้ในตำแหน่งแบบสุ่มทุกครั้งที่เปิดใช้งานในสภาพแวดล้อมการแสดงผลหลายจอ และรหัส

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

"ตัด" หน้าต่างลงครึ่งหนึ่งโดยวางไว้ตรงกลางซึ่งอยู่ระหว่างจอแสดงผลสองจอของฉัน ฉันใช้วิธีการต่อไปนี้เพื่อจัดกึ่งกลาง:

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

ทำให้หน้าต่างปรากฏตรงกลางของจอแสดงผลแรก นี่อาจไม่ใช่วิธีแก้ปัญหาที่ง่ายที่สุด

ทำงานได้อย่างถูกต้องบน Linux, Windows และ Mac


การพิจารณาสภาพแวดล้อมหลายหน้าจอเป็นคำตอบที่ถูกต้องเท่านั้นมิฉะนั้นหน้าจอที่หน้าต่างปรากฏขึ้นอาจเป็นแบบสุ่มหรือหน้าต่างอยู่ตรงกลางระหว่างหน้าจอทั้งสอง
Stephan

6

ในที่สุดฉันก็ได้รหัสจำนวนมากเพื่อใช้งานใน NetBeans โดยใช้ Swing GUI Forms เพื่อให้ศูนย์กลาง jFrame หลัก:

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

}

หรือ

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

}

หรือ

    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

สิ่งต่อไปนี้ใช้ไม่ได้กับ JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

วางมุมซ้ายบนไว้ตรงกลาง - ไม่เหมือนกับการวางตรงกลางหน้าต่าง อันอื่นใช้ไม่ได้เช่นกันซึ่งเกี่ยวข้องกับ frame.getSize () และ 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);

เมธอด getSize () สืบทอดมาจากคลาสคอมโพเนนต์ดังนั้น frame.getSize จะส่งกลับขนาดของหน้าต่างด้วย ดังนั้นการลบครึ่งมิติแนวตั้งและแนวนอนออกจากขนาดแนวตั้งและแนวนอนเพื่อค้นหาพิกัด x, y ของตำแหน่งที่จะวางมุมซ้ายบนจะทำให้คุณได้ตำแหน่งของจุดศูนย์กลางซึ่งจะสิ้นสุดลงตรงกลางของหน้าต่างด้วย อย่างไรก็ตามบรรทัดแรกของโค้ดด้านบนมีประโยชน์ "มิติข้อมูล ... " เพียงทำสิ่งนี้เพื่อจัดกึ่งกลาง:

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 กำหนดขนาดหน้าจอ อยู่ใน FrameDemo.java ที่มีอยู่ในบทเรียน java ที่เว็บไซต์ Oracle / Sun ฉันตั้งค่าเป็นครึ่งหนึ่งของความสูง / ความกว้างของขนาดหน้าจอ จากนั้นฉันจัดกึ่งกลางโดยวางด้านบนซ้ายไว้ที่ 1/4 ของมิติขนาดหน้าจอจากด้านซ้ายและ 1/4 ของมิติขนาดหน้าจอจากด้านบน คุณสามารถใช้แนวคิดที่คล้ายกัน


1
อีกคนหนึ่งไม่เหมือนกัน รหัสเหล่านี้ทำให้มุมบนซ้ายของหน้าจออยู่ตรงกลาง
Jonathan Caraballo

7
-1 ไม่สามารถทำซ้ำ - หรือแม่นยำกว่า: เกิดขึ้นเฉพาะในกรณีที่เรียกใช้ setLocationRelative ก่อนที่จะปรับขนาดเฟรม (ตามแพ็คหรือ setSize ด้วยตนเอง) สำหรับเฟรมขนาดศูนย์มุมซ้ายบนคือตำแหน่งเดียวกับ .. ศูนย์กลาง :-)
คลีโอพัตรา

3

ด้านล่างนี้คือรหัสสำหรับแสดงกรอบที่กึ่งกลางด้านบนของหน้าต่างที่มีอยู่

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) พ่น Exception {

new SwingContainerDemo().showJFrameDemo();

}

ด้านล่างนี้คือผลลัพธ์ของข้อมูลโค้ดด้านบน:ใส่คำอธิบายภาพที่นี่


1
frame.setLocation(x, 0);ดูเหมือนจะผิด - ไม่ควรเป็นอย่างนั้นframe.setLocation(x, y);หรือ?
เห็นว่า

x หมายถึงความยาวของแกน x และ y หมายถึงความยาวของแกน y ดังนั้นถ้าคุณสร้าง y = 0 มันควรจะอยู่บนสุดเท่านั้น
Aman Goel

ดังนั้นจึงint y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);มีอยู่ในโค้ดเพื่อแสดงว่าคุณสามารถจัดกึ่งกลางในแกนแนวตั้งได้ด้วย? โอเคฉันคิดว่าคุณลืมใช้ขอโทษสำหรับปัญหา
ถือว่า

ไม่มีปัญหา. เดม! มันเยี่ยมมากที่ได้คุยกับคุณ
Aman Goel

2

มีบางอย่างที่ง่ายมากที่คุณอาจมองข้ามไปหลังจากพยายามจัดกึ่งกลางหน้าต่างโดยใช้setLocationRelativeTo(null)หรือsetLocation(x,y)แล้วก็จบลงด้วยการอยู่ตรงกลางเล็กน้อย

ตรวจสอบให้แน่ใจว่าคุณใช้วิธีใดวิธีหนึ่งต่อไปนี้หลังจากโทรpack()เพราะคุณจะใช้ขนาดของหน้าต่างเพื่อคำนวณตำแหน่งที่จะวางบนหน้าจอ จนกว่าpack()จะมีการเรียกขนาดไม่ใช่สิ่งที่คุณคิดจึงทิ้งการคำนวณเพื่อจัดกึ่งกลางหน้าต่าง หวังว่านี่จะช่วยได้


2

ตัวอย่าง: Inside myWindow () ในบรรทัดที่ 3 คือรหัสที่คุณต้องใช้เพื่อตั้งค่าหน้าต่างตรงกลางหน้าจอ

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

ตัวอย่างเต็ม:

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

รหัสต่อไปนี้จะจัดกึ่งกลางที่Windowกึ่งกลางของจอภาพปัจจุบัน (เช่นตำแหน่งของตัวชี้เมาส์)

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

คุณสามารถลองสิ่งนี้ได้เช่นกัน

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
แล้วจอภาพหลายจอล่ะ?
Supuhstar

0

กรอบจริง.getHeight()และgetwidth()ไม่ส่งคืนค่าตรวจสอบโดยSystem.out.println(frame.getHeight());ใส่ค่าสำหรับความกว้างและความสูงโดยตรงจากนั้นจะทำงานได้ดีอยู่ตรงกลาง เช่น: ดังต่อไปนี้

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

ทั้ง 450 คือความกว้างเฟรม n ความสูงของฉัน


1
-1 ขนาดของเฟรมเป็นศูนย์ก่อน ... ปรับขนาด :-) โดยเฉพาะอย่างยิ่งเป็นแพ็คหรืออย่างน้อยก็โดยการตั้งค่าขนาดของมันด้วยตนเองเป็นอย่างอื่นที่ไม่ใช่ศูนย์ก่อนที่จะเรียกใช้ setLocationRelative จะช่วยให้การคำนวณที่ถูกต้องภายใน
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

ลำดับการโทรมีความสำคัญ:

อันดับแรก -

pack();

วินาที -

setLocationRelativeTo(null);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.