Bagaimana cara memusatkan Jendela di Jawa?

113

Apa cara termudah untuk memusatkan a java.awt.Window, seperti a JFrameatau a JDialog?

Andrew Swan
sumber
2
Judulnya harus "di Swing" bukan "di Java", akan lebih jelas seperti itu.
Joe Skora
6
@ Joe setLocation(), setLocationRelativeTo()dan setLocationByPlatform()atau semua AWT, bukan Swing. ;)
Andrew Thompson

Jawaban:

244

Dari tautan ini

Jika Anda menggunakan Java 1.4 atau yang lebih baru, Anda dapat menggunakan metode setLocationRelativeTo (null) sederhana pada kotak dialog, bingkai, atau jendela untuk memusatkannya.

Andrew Swan
sumber
9
Seperti yang dikatakan @kleopatra pada jawaban lain, setLocationRelativeTo (null) harus dipanggil setelah pack () agar berfungsi.
Eusebius
6
Seperti dijelaskan di bawah ini, setLocationRelativeTo (null) harus dipanggil setelah panggilan apa pun dari pack () atau setSize ().
Arnaud P
2
@Eusebius Odd, saya mengikuti tutorial yang membuat saya mengaturnya sebelumnya pack()dan itu menempatkan sudut kiri atas bingkai di tengah layar saya. Setelah memindahkan garis ke bawah, garis pack()itu berada di tengah dengan benar.
pengguna1433479
2
Well pack () menetapkan ukuran yang benar berdasarkan konten dan tata letak, dan Anda tidak dapat memusatkan sesuatu kecuali Anda tahu ukurannya, jadi sungguh aneh bahwa tutorial meminta Anda mengemasnya setelah memusatkannya.
Andrew Swan
65

Ini harus bekerja di semua versi 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
sumber
Saya tahu bahwa ini cukup tua tetapi ini berfungsi dengan baik, asalkan ukuran bingkai disetel sebelum memanggil fungsi ini
S.Krishna
1
Ya, pastikan ukurannya diterapkan sebelumnya (menggunakan paket () misalnya)
Myoch
27

setLocationRelativeTo(null)harus dipanggil setelah Anda menggunakan setSize(x,y), atau menggunakan pack().

Dzmitry Sevkovich
sumber
Kamu benar. Ini harus memiliki panggilan setSize () sebelumnya.
Sai Dubbaka
26

Perhatikan bahwa teknik setLocationRelativeTo (null) dan Tookit.getDefaultToolkit (). GetScreenSize () hanya berfungsi untuk monitor utama. Jika Anda berada di lingkungan multi-monitor, Anda mungkin perlu mendapatkan informasi tentang monitor spesifik tempat jendela aktif sebelum melakukan penghitungan semacam ini.

Terkadang penting, terkadang tidak ...

Lihat GraphicsEnvironment javadocs untuk info lebih lanjut tentang bagaimana mendapatkan ini.

Kevin Day
sumber
17

Di Linux kodenya

setLocationRelativeTo(null)

Letakkan jendela saya ke lokasi acak setiap kali saya meluncurkannya, dalam lingkungan multi-tampilan. Dan kodenya

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

"potong" jendela menjadi dua dengan menempatkannya tepat di tengah, yaitu di antara dua layar saya. Saya menggunakan metode berikut untuk memusatkannya:

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

Membuat jendela muncul tepat di tengah tampilan pertama. Ini mungkin bukan solusi termudah.

Bekerja dengan baik di Linux, Windows dan Mac.

Peter Szabo
sumber
Mempertimbangkan lingkungan multi layar adalah satu-satunya jawaban yang benar, jika tidak, layar di mana jendela muncul bisa jadi agak acak atau jendela berada di tengah antara kedua layar.
Stephan
6

Saya akhirnya mendapatkan sekumpulan kode ini untuk bekerja di NetBeans menggunakan Swing GUI Forms untuk memusatkan jFrame utama:

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

}

ATAU

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

}

ATAU

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

Berikut ini tidak berfungsi untuk JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Itu menempatkan sudut kiri atas di tengah - tidak sama dengan menengahkan jendela. Yang lainnya juga tidak berfungsi, melibatkan frame.getSize () dan dimensional.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);

Metode getSize () diwarisi dari kelas Komponen, dan oleh karena itu frame.getSize juga mengembalikan ukuran jendela. Jadi, dengan mengurangkan setengah dimensi vertikal dan horizontal dari dimensi vertikal dan horizontal, untuk menemukan koordinat x, y tempat meletakkan sudut kiri atas, memberi Anda lokasi titik tengah, yang pada akhirnya juga memusatkan jendela. Namun, baris pertama dari kode di atas berguna, "Dimensi ...". Lakukan saja ini untuk memusatkannya:

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 mengatur ukuran layar. Ada di FrameDemo.java tersedia di tutorial java di situs Oracle / Sun. Saya mengaturnya menjadi setengah tinggi / lebar ukuran layar. Lalu, saya pusatkan dengan menempatkan kiri atas pada 1/4 dimensi ukuran layar dari kiri, dan 1/4 dimensi ukuran layar dari atas. Anda bisa menggunakan konsep serupa.

Jonathan Caraballo
sumber
1
Begitu pula yang lainnya. Kode-kode ini meletakkan sudut kiri atas layar di tengah.
Jonathan Caraballo
7
-1 tidak dapat mereproduksi - atau lebih tepatnya: terjadi hanya jika setLocationRelative dipanggil sebelum mengukur frame (dengan paket atau setSize manual). Untuk bingkai berukuran nol, pojok kiri atas adalah lokasi yang sama dengan .. pusatnya :-)
kleopatra
3

di bawah ini adalah kode untuk menampilkan bingkai di tengah atas jendela yang ada.

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) melempar Exception {

new SwingContainerDemo().showJFrameDemo();

}

Di bawah ini adalah keluaran dari cuplikan kode di atas:masukkan deskripsi gambar di sini

Aman Goel
sumber
1
frame.setLocation(x, 0);sepertinya salah - bukankah seharusnya begitu frame.setLocation(x, y);?
anggap
x menunjukkan panjang sumbu x dan y menunjukkan panjang sumbu y. Jadi jika Anda membuat y = 0 maka hanya itu yang harus di atas.
Aman Goel
Jadi int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);ada dalam kode hanya untuk menunjukkan bahwa Anda juga dapat memusatkan pada sumbu vertikal? Oke, saya pikir Anda baru saja lupa menggunakannya, maaf atas masalah.
anggap
Tidak masalah. Menganggap! Senang sekali bisa bicara denganmu.
Aman Goel
2

Ada sesuatu yang sangat sederhana yang mungkin Anda abaikan setelah mencoba memusatkan jendela menggunakan salah satu setLocationRelativeTo(null)atau setLocation(x,y)dan akhirnya sedikit keluar dari tengah.

Pastikan Anda menggunakan salah satu dari metode ini setelah menelepon pack()karena Anda akan menggunakan dimensi jendela itu sendiri untuk menghitung di mana harus meletakkannya di layar. Sampai pack()dipanggil, dimensinya tidak seperti yang Anda pikirkan sehingga membuang perhitungan ke tengah jendela. Semoga ini membantu.

Clay Ellis
sumber
2

Contoh: Di dalam myWindow () pada baris 3 adalah kode yang Anda butuhkan untuk mengatur jendela di tengah layar.

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

frame.setLocationRelativeTo (null);

Contoh lengkap:

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

Kode berikut memusatkan Windowdi tengah monitor saat ini (yaitu di mana penunjuk mouse berada).

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

Anda juga bisa mencoba ini.

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);
cebol gautam
sumber
1
Bagaimana dengan beberapa monitor?
Supuhstar
0

Sebenarnya bingkai .getHeight()dan getwidth()tidak mengembalikan nilai, periksa dengan System.out.println(frame.getHeight());langsung memasukkan nilai untuk lebar dan tinggi, maka itu akan bekerja dengan baik di tengah. misal: seperti di bawah ini

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

keduanya 450 adalah lebar bingkai dan tinggi saya

Viswanath Lekshmanan
sumber
1
-1 ukuran frame adalah nol sebelum ... mengukurnya :-) Lebih disukai berdasarkan paket, atau setidaknya dengan mengatur ukurannya secara manual ke selain nol sebelum memanggil setLocationRelative akan memungkinkan penghitungan internal yang benar
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.dll
sumber
0

Urutan panggilan penting:

pertama -

pack();

kedua -

setLocationRelativeTo(null);
Adir D
sumber