Jak wyśrodkować okno w Javie?


113

Jaki jest najłatwiejszy sposób wyśrodkowania a java.awt.Window, na przykład a JFramelub a JDialog?


2
Tytuł powinien brzmieć „w języku Swing”, a nie „w języku Java”, w ten sposób byłoby bardziej zrozumiałe.
Joe Skora

6
@Joe setLocation(), setLocationRelativeTo()i setLocationByPlatform()czy wszystko AWT, nie Swing. ;)
Andrew Thompson,

Odpowiedzi:


244

Z tego linku

Jeśli używasz języka Java 1.4 lub nowszego, możesz użyć prostej metody setLocationRelativeTo (null) w oknie dialogowym, ramce lub oknie, aby je wyśrodkować.


9
Jak @kleopatra powiedział w innej odpowiedzi, setLocationRelativeTo (null) musi być wywołane po pack (), aby działało.
Euzebiusz

6
Jak wyjaśniono poniżej, setLocationRelativeTo (null) musi zostać wywołane po każdym wywołaniu funkcji pack () lub setSize ().
Arnaud P

2
@Eusebius Odd, skorzystałem z samouczka, który kazał mi ustawić go wcześniej pack()i umieścił lewy górny róg ramki na środku mojego ekranu. Po przesunięciu linii poniżej pack()została prawidłowo wyśrodkowana.
user1433479,

2
Cóż, pack () ustawia właściwy rozmiar w oparciu o zawartość i układ, i nie możesz czegoś wyśrodkować, dopóki nie znasz jego rozmiaru, więc jest rzeczywiście dziwne, że samouczek kazał ci go spakować po wyśrodkowaniu.
Andrew Swan,

65

Powinno to działać we wszystkich wersjach 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);
}

Wiem, że to jest dość stare, ale działa dobrze, pod warunkiem, że rozmiar klatki zostanie ustawiony przed wywołaniem tej funkcji
S.Krishna

1
Tak, upewnij się, że rozmiar został zastosowany wcześniej (na przykład przy użyciu funkcji pack ())
Myoch,


26

Zauważ, że obie techniki setLocationRelativeTo (null) i Tookit.getDefaultToolkit (). GetScreenSize () działają tylko na głównym monitorze. Jeśli pracujesz w środowisku z wieloma monitorami, może być konieczne uzyskanie informacji o konkretnym monitorze, na którym znajduje się okno, przed wykonaniem tego rodzaju obliczeń.

Czasami ważne, czasami nie ...

Zobacz javadocs GraphicsEnvironment, aby uzyskać więcej informacji o tym, jak to uzyskać.


17

W systemie Linux kod

setLocationRelativeTo(null)

Umieszczaj moje okno w losowej lokalizacji za każdym razem, gdy je uruchamiam, w środowisku z wieloma wyświetlaczami. I kod

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

„przeciąć” okno na pół, umieszczając je dokładnie na środku, czyli między moimi dwoma wyświetlaczami. Użyłem następującej metody, aby go wyśrodkować:

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

Powoduje, że okno pojawia się na środku pierwszego ekranu. To chyba nie jest najłatwiejsze rozwiązanie.

Działa poprawnie w systemach Linux, Windows i Mac.


Uwzględnienie środowisk wieloekranowych jest jedyną poprawną odpowiedzią, w przeciwnym razie ekran, na którym pojawia się okno, może być nieco losowy lub okno jest wyśrodkowane między obydwoma ekranami.
Stephan

6

W końcu dostałem ten zestaw kodów do pracy w NetBeans przy użyciu Swing GUI Forms w celu wyśrodkowania głównego 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); 
    } 

}

LUB

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

}

LUB

    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

Poniższe elementy nie działają w przypadku JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Umieszcza lewy górny róg na środku - nie to samo, co wyśrodkowanie okna. Drugi też nie działa, obejmujący frame.getSize () i Dimensions.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);

Metoda getSize () jest dziedziczona z klasy Component, w związku z czym frame.getSize zwraca również rozmiar okna. W ten sposób odejmując połowę wymiarów pionowych i poziomych od wymiarów pionowych i poziomych, aby znaleźć współrzędne x, y miejsca, w którym należy umieścić lewy górny narożnik, podaje położenie punktu środkowego, który kończy się również wyśrodkowaniem okna. Jednak pierwsza linia powyższego kodu jest przydatna, „Wymiar ...”. Po prostu zrób to, aby go wyśrodkować:

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 ustawia rozmiar ekranu. Znajduje się w FrameDemo.java dostępnym w samouczkach java w witrynie Oracle / Sun. Ustawiłem go na połowę wysokości / szerokości rozmiaru ekranu. Następnie wyśrodkowałem go, umieszczając lewy górny róg na 1/4 wymiaru ekranu od lewej i 1/4 wymiaru ekranu od góry. Możesz użyć podobnej koncepcji.


1
Drugi też nie. Te kody umieszczają lewy górny róg ekranu na środku.
Jonathan Caraballo

7
-1 nie może odtworzyć - a dokładniej: dzieje się tylko wtedy, gdy setLocationRelative jest wywoływana przed określeniem rozmiaru ramki (przez pakiet lub ręcznie setSize). Dla ramki o zerowym rozmiarze jej lewy górny róg znajduje się w tym samym miejscu, co ... jej środek :-)
kleopatra

3

poniżej znajduje się kod do wyświetlania ramki w górnej środkowej części istniejącego okna.

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) rzuca wyjątek {

new SwingContainerDemo().showJFrameDemo();

}

Poniżej znajduje się wynik powyższego fragmentu kodu:wprowadź opis obrazu tutaj


1
frame.setLocation(x, 0);wydaje się źle - czy nie powinno być frame.setLocation(x, y);zamiast tego?
patrz

x oznacza długość osi x, a y oznacza długość osi y. Więc jeśli zrobisz y = 0, to tylko powinno znajdować się na górze.
Aman Goel,

Czyli int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);istnieje w kodzie tylko po to, aby pokazać, że można również wyśrodkować na osi pionowej? Ok, myślałem, że zapomniałeś go użyć, przepraszam za kłopoty.
patrz

Nie ma problemu. Uważać! Wspaniale z tobą rozmawiać.
Aman Goel

2

Jest coś naprawdę prostego, co możesz przeoczyć po próbie wyśrodkowania okna za pomocą jednego setLocationRelativeTo(null)lub drugiego, setLocation(x,y)a kończy się to trochę poza środkiem.

Upewnij się, że po wywołaniu używasz jednej z tych metod, pack()ponieważ w końcu użyjesz wymiarów samego okna, aby obliczyć, gdzie umieścić je na ekranie. Dopóki nie pack()zostanie wywołane, wymiary nie są tym, co myślisz, odrzucając obliczenia w celu wyśrodkowania okna. Mam nadzieję że to pomoże.


2

Przykład: Wewnątrz myWindow () w linii 3 znajduje się kod potrzebny do ustawienia okna na środku ekranu.

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

Pełny przykład:

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

Poniższy kod wyśrodkowuje Windoww środku bieżącego monitora (tj. Tam, gdzie znajduje się wskaźnik myszy).

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

Ty też możesz spróbować.

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
A co z wieloma monitorami?
Supuhstar

0

Właściwie ramka .getHeight()i getwidth()nie zwraca wartości, sprawdź to, System.out.println(frame.getHeight());bezpośrednio wstawiając wartości szerokości i wysokości, wtedy będzie działać dobrze na środku. np. jak poniżej

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

oba 450 to szerokość mojej ramy n wysokość


1
-1 rozmiar ramki jest zerowy przed ... dopasowaniem jej rozmiaru :-) Najlepiej według paczki lub przynajmniej ręcznie ustawiając jej rozmiar na cokolwiek innego niż zero przed wywołaniem setLocationRelative, co pozwoli na jej wewnętrzne poprawne obliczenie
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

Kolejność połączeń jest ważna:

pierwszy -

pack();

drugi -

setLocationRelativeTo(null);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.