Java'da bir pencere nasıl ortalanır?


113

java.awt.WindowA JFrameveya a gibi a'yı ortalamanın en kolay yolu nedir JDialog?


3
Başlık "Java'da" değil "Swing'de" olmalıdır, bu şekilde daha açık olur.
Joe Skora

6
@Joe setLocation(), setLocationRelativeTo()ve setLocationByPlatform()ya tüm AWT Swing değil. ;)
Andrew Thompson

Yanıtlar:


244

Gönderen bu bağlantı

Java 1.4 veya daha yenisini kullanıyorsanız, ortalamak için iletişim kutusu, çerçeve veya pencerede setLocationRelativeTo (null) basit yöntemini kullanabilirsiniz.


9
@Kleopatra'nın başka bir cevapta söylediği gibi, setLocationRelativeTo (null), çalışabilmesi için pack () 'den sonra çağrılmalıdır.
Eusebius

6
Aşağıda açıklandığı gibi, setLocationRelativeTo (null), herhangi bir pack () veya setSize () çağrısından sonra çağrılmalıdır.
Arnaud P

2
@Eusebius Odd, daha önce ayarlamamı sağlayan bir öğretici takip ettim pack()ve çerçevenin sol üst köşesini ekranımın ortasına koydu. Çizgiyi aşağıya taşıdıktan pack()sonra düzgün şekilde ortalandı.
user1433479

2
Well pack (), içeriğe ve düzene göre doğru boyutu ayarlar ve boyutunu bilmediğiniz sürece bir şeyi ortalayamazsınız, bu nedenle eğiticinin onu ortaladıktan sonra paketlemeniz gerçekten tuhaftır.
Andrew Swan

65

Bu, Java'nın tüm sürümlerinde çalışmalıdır

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

Bunun oldukça eski olduğunu biliyorum, ancak çerçeve boyutunun bu işlevi çağırmadan önce ayarlanmış olması koşuluyla bu iyi çalışıyor
S.Krishna

1
Evet, boyutun daha önce uygulandığından emin olun (örneğin pack () kullanarak)
Myoch

27

setLocationRelativeTo(null)kullanımdan setSize(x,y)veya kullandıktan sonra aranmalıdır pack().


Haklısın. Daha önce setSize () çağrısına sahip olması gerekir.
Sai Dubbaka

26

Hem setLocationRelativeTo (null) hem de Tookit.getDefaultToolkit (). GetScreenSize () tekniklerinin yalnızca birincil monitör için çalıştığını unutmayın. Çoklu monitör ortamındaysanız, bu tür bir hesaplama yapmadan önce pencerenin açık olduğu belirli monitör hakkında bilgi almanız gerekebilir.

Bazen önemli, bazen değil ...

Bunu nasıl edineceğiniz hakkında daha fazla bilgi için GraphicsEnvironment javadocs'a bakın .


17

Linux'ta kod

setLocationRelativeTo(null)

Penceremi her başlatışımda çoklu ekran ortamında rastgele bir konuma yerleştirin. Ve kod

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

iki ekranımın arasındaki tam merkeze yerleştirerek pencereyi ikiye "kesin". Ortalamak için aşağıdaki yöntemi kullandım:

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

Pencerenin ilk ekranın tam ortasında görünmesini sağlar. Bu muhtemelen en kolay çözüm değildir.

Linux, Windows ve Mac'te düzgün çalışır.


Çoklu ekran ortamlarını hesaba katmak tek doğru cevaptır, aksi takdirde pencerenin göründüğü ekran bir şekilde rastgele olabilir veya pencere her iki ekran arasında ortalanmış olabilir.
Stephan

6

Sonunda ana jFrame'i ortalamak için Swing GUI Formlarını kullanarak NetBeans'te çalışmak üzere bu kod grubunu aldım:

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

}

VEYA

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

}

VEYA

    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

Aşağıdakiler JDK 1.7.0.07 için çalışmaz:

frame.setLocationRelativeTo(null);

Sol üst köşeyi ortaya koyar - pencereyi ortalamakla aynı şey değildir. Diğeri de frame.getSize () ve dimension.getSize () dahil olmak üzere çalışmaz:

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 () yöntemi, Component sınıfından miras alınır ve bu nedenle frame.getSize, pencerenin boyutunu da döndürür. Böylece, dikey ve yatay boyutların yarısını dikey ve yatay boyutlardan çıkarmak, sol üst köşenin yerleştirileceği x, y koordinatlarını bulmak, size pencereyi ortalayarak sonuçlanan merkez noktasının konumunu verir. Ancak, yukarıdaki kodun ilk satırı "Boyut ..." kullanışlıdır. Bunu ortalamak için yapmanız yeterli:

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, ekran boyutunu ayarlar. Oracle / Sun sitesindeki java eğitimlerinde FrameDemo.java'da mevcuttur. Ekran boyutunun yüksekliğinin / genişliğinin yarısına ayarladım. Ardından, sol üst kısmı soldan ekran boyutunun 1 / 4'üne ve üstten ekran boyutunun 1 / 4'üne yerleştirerek ortaladım. Benzer bir konsept kullanabilirsiniz.


1
Diğeri de bilmiyor. Bu kodlar ekranın sol üst köşesini ortaya koyar.
Jonathan Caraballo

7
-1 yeniden üretilemez - veya daha doğrusu: sadece çerçeve boyutlandırılmadan önce setLocationRelative çağrılırsa gerçekleşir (paket veya manuel setSize ile). Sıfır boyutlu bir çerçeve için sol üst köşesi ile aynı konumdur .. ortası :-)
kleopatra

3

Aşağıda, mevcut pencerenin üst ortasındaki bir çerçeveyi görüntülemek için kod bulunmaktadır.

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 [] değiştirgeler) Exception {

new SwingContainerDemo().showJFrameDemo();

}

Yukarıdaki kod parçacığının çıktısı aşağıdadır:görüntü açıklamasını buraya girin


1
frame.setLocation(x, 0);yanlış gibi görünüyor - onun frame.setLocation(x, y);yerine olması gerekmez mi?
gördükleri

x, x ekseninin uzunluğunu ve y, y ekseninin uzunluğunu belirtir. Yani y = 0 yaparsanız, o zaman sadece üstte olmalıdır.
Aman Goel

Yani int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);kodda sadece dikey eksende ortalayabileceğinizi göstermek için var mı? Tamam, sadece kullanmayı unuttuğunu sanıyordum, sorun için üzgünüm.
gördükleri

Sorun değil. Deem! Seninle konuşmak harika.
Aman Goel

2

Ya setLocationRelativeTo(null)veya kullanarak pencereyi ortalamaya çalıştıktan sonra gözden kaçırabileceğiniz gerçekten basit bir şey var setLocation(x,y)ve bu biraz merkezin dışında kalıyor.

Emin Bu yöntemlerden birini kullanma emin olun sonra arayarak pack()nerede ekranda yerleştirmek için hesaplamak için pencerenin kendisinin boyutları kullanarak bitireceğiz çünkü. Çağrılıncaya kadar pack(), boyutlar düşündüğünüz gibi değildir, bu nedenle pencereyi ortalamak için hesaplamaları atar. Bu yardımcı olur umarım.


2

Örnek: myWindow () 'un 3. satırında, pencereyi ekranın ortasına ayarlamanız için gereken kod bulunur.

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 (boş);

Tam örnek:

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

Aşağıdaki kod Window, geçerli monitörün merkezinde (yani fare işaretçisinin bulunduğu yer) ortalanır.

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

Bunu da deneyebilirsin.

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
Birden çok monitör ne olacak?
Supuhstar

0

Aslında çerçeve .getHeight()ve getwidth()değer döndürmez, System.out.println(frame.getHeight());doğrudan genişlik ve yükseklik değerlerini girerek kontrol edin , sonra merkezde iyi çalışacaktır. örneğin: aşağıdaki gibi

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

her ikisi de benim çerçeve genişliğim n yüksekliğidir


1
-1 bir çerçevenin boyutu önce sıfırdır ... boyutlandırma :-) Tercihen paketle veya setLocationRelative'i çağırmadan önce boyutunu manuel olarak sıfırdan başka bir şeye ayarlayarak , dahili doğru hesaplamaya izin verir
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

Çağrıların sırası önemlidir:

ilk -

pack();

ikinci -

setLocationRelativeTo(null);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.