Як центрувати вікно на Java?


113

Який найпростіший спосіб централізувати a java.awt.Window, наприклад, a JFrameчи a JDialog?


2
Назва повинна бути "in 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()вона була належним чином по центру.
користувач1433479

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

Я знаю, що це досить старе, але це працює добре, за умови встановлення розміру кадру перед тим, як викликати цю функцію
С.Крішна

1
Так, переконайтеся, що розмір застосовано раніше (наприклад, використовуючи pack ())
Myoch

27

setLocationRelativeTo(null)слід викликати після того, як ви або користуєтесь setSize(x,y), або користуєтесь pack().


Ти маєш рацію. Потрібно мати виклик setSize () раніше.
Сай Дуббака

26

Зауважте, що методи setLocationRelativeTo (null) і Tookit.getDefaultToolkit (). GetScreenSize () працюють лише для основного монітора. Якщо ви перебуваєте в середовищі з декількома моніторами, можливо, вам знадобиться отримати інформацію про конкретний монітор, у якому знаходиться вікно, перш ніж робити такий обчислення.

Іноді важливо, іноді ні ...

Докладнішу інформацію про те, як це отримати, див. У javadocs GraphicsEn Environment .


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

3

Наступне не працює для JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Він ставить верхній лівий кут у центрі - не такий, як центрування вікна. Інший також не працює, включаючи frame.getSize () і Dimenge.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);натомість це буде ?
deem

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 (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
А як щодо декількох моніторів?
Супухстар

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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.