Как центрировать окно в Java?

113

Какой самый простой способ центрировать a java.awt.Window, например a JFrameили a JDialog?

Эндрю Свон
источник
3
Заголовок должен быть «в Swing», а не «в Java», так было бы более понятно.
Джо Скора,
6
@Joe setLocation(), setLocationRelativeTo()и setLocationByPlatform()все или AWT, не свинг. ;)
Эндрю Томпсон

Ответы:

244

По этой ссылке

Если вы используете Java 1.4 или новее, вы можете использовать простой метод setLocationRelativeTo (null) в диалоговом окне, фрейме или окне для его центрирования.

Эндрю Свон
источник
9
Как сказал @kleopatra в другом ответе, setLocationRelativeTo (null) должен вызываться после pack () для работы.
Евсевий
6
Как объясняется ниже, setLocationRelativeTo (null) должен вызываться после любого вызова pack () или setSize ().
Арно П.
2
@Eusebius Odd, я следовал руководству, которое заставило меня установить его раньше, pack()и он поместил верхний левый угол рамки в центр моего экрана. После перемещения линии вниз pack()она правильно отцентрировалась.
user1433479 06
2
Хорошо pack () устанавливает правильный размер в зависимости от содержимого и макета, и вы не можете центрировать что-либо, если не знаете его размер, поэтому действительно странно, что в учебнике вы упаковывали его после центрирования.
Эндрю Свон
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);
}
Dónal
источник
Я знаю, что это довольно старый
вариант,
1
Да, убедитесь, что размер применен перед (например, с помощью pack ())
Myoch
27

setLocationRelativeTo(null)должен вызываться после того, как вы используете setSize(x,y)или используете pack().

Дмитрий Севкович
источник
Ты прав. Перед этим должен быть вызов setSize ().
Сай Дуббака
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.

Питер Сабо
источник
Учет многоэкранной среды - единственный правильный ответ, иначе экран, на котором появляется окно, может быть каким-то случайным, или окно находится по центру между обоими экранами.
Стефан
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...
   }
TheLooker
источник
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 () унаследован от класса Component, и поэтому 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
Другой тоже. Эти коды помещают верхний левый угол экрана в центр.
Джонатан Карабалло,
7
-1 не может воспроизвести - или, точнее: происходит, только если setLocationRelative вызывается перед изменением размера кадра (пакетом или ручным setSize). Для кадра нулевого размера его верхний левый угол находится в том же месте, что и его центр :-)
kleopatra
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) выдает исключение {

new SwingContainerDemo().showJFrameDemo();

}

Ниже приведен вывод вышеуказанного фрагмента кода:введите описание изображения здесь

Аман Гоэль
источник
1
frame.setLocation(x, 0);кажется неправильным - разве не должно быть frame.setLocation(x, y);?
считают
x обозначает длину оси x, а y обозначает длину оси y. Итак, если вы сделаете y = 0, тогда только он должен быть наверху.
Аман Гоэль
Так int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);существует в коде только для того, чтобы показать, что вы также можете центрировать по вертикальной оси? Хорошо, я думал, ты просто забыл его использовать, извините за проблемы.
считает
Нет проблем. Считай! Приятно с вами поговорить.
Аман Гоэль
2

Есть кое-что действительно простое, что вы могли упустить из виду, пытаясь отцентрировать окно с помощью либо setLocationRelativeTo(null)или, setLocation(x,y)и оно в итоге оказывается немного не по центру.

Убедитесь, что вы используете один из этих методов после вызова, pack()потому что в конечном итоге вы будете использовать размеры самого окна, чтобы вычислить, где его разместить на экране. До тех пор, pack()пока не будет вызван, размеры не такие, как вы думаете, что отбрасывает вычисления по центру окна. Надеюсь это поможет.

Клэй Эллис
источник
2

Пример: внутри 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 (ноль);

Полный пример:

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);
Manikant Gautam
источник
1
А как насчет нескольких мониторов?
Supuhstar
0

На самом деле frame .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);
    }
}
borchvm
источник
0

Порядок звонков важен:

первый -

pack();

второй -

setLocationRelativeTo(null);
Адир Д
источник