Come centrare una finestra in Java?


113

Qual è il modo più semplice per centrare a java.awt.Window, come a JFrameo a JDialog?


2
Il titolo dovrebbe essere "in Swing" non "in Java", sarebbe più chiaro in questo modo.
Joe Skora

6
@ Joe setLocation(), setLocationRelativeTo()e / setLocationByPlatform()o tutto AWT, non Swing. ;)
Andrew Thompson

Risposte:


244

Da questo collegamento

Se si utilizza Java 1.4 o più recente, è possibile utilizzare il semplice metodo setLocationRelativeTo (null) nella finestra di dialogo, nel frame o nella finestra per centrarlo.


9
Come ha detto @kleopatra in un'altra risposta, setLocationRelativeTo (null) deve essere chiamato dopo pack () per funzionare.
Eusebio

6
Come spiegato di seguito, setLocationRelativeTo (null) deve essere chiamato dopo ogni chiamata di pack () o setSize ().
Arnaud P

2
@Eusebius Odd, ho seguito un tutorial che mi ha fatto impostare prima pack()e ha messo l'angolo in alto a sinistra della cornice al centro del mio schermo. Dopo aver spostato la linea al di sotto, pack()è stata centrata correttamente.
user1433479

2
Bene pack () imposta la dimensione corretta in base al contenuto e al layout, e non puoi centrare qualcosa a meno che tu non ne conosca le dimensioni, quindi è davvero strano che il tutorial ti abbia impacchettato dopo averlo centrato.
Andrew Swan

65

Questo dovrebbe funzionare in tutte le versioni di 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);
}

So che è piuttosto vecchio ma funziona bene, a condizione che la dimensione del frame sia impostata prima di chiamare questa funzione
S.Krishna

1
Sì, assicurati che la taglia sia applicata prima (usando pack () per esempio)
Myoch

27

setLocationRelativeTo(null)dovrebbe essere chiamato dopo aver usato setSize(x,y)o usato pack().


Hai ragione. Prima deve essere chiamata setSize ().
Sai Dubbaka

26

Notare che entrambe le tecniche setLocationRelativeTo (null) e Tookit.getDefaultToolkit (). GetScreenSize () funzionano solo per il monitor principale. Se ci si trova in un ambiente con più monitor, potrebbe essere necessario ottenere informazioni sul monitor specifico su cui si trova la finestra prima di eseguire questo tipo di calcolo.

A volte importante, a volte no ...

Vedi javadocs GraphicsEnvironment per maggiori informazioni su come ottenere questo.


17

Su Linux il codice

setLocationRelativeTo(null)

Metti la mia finestra in una posizione casuale ogni volta che l'ho avviata, in un ambiente con più display. E il codice

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

"tagliare" la finestra a metà posizionandola al centro esatto, che è tra i miei due display. Ho usato il seguente metodo per centrarlo:

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

Fa apparire la finestra proprio al centro del primo display. Questa probabilmente non è la soluzione più semplice.

Funziona correttamente su Linux, Windows e Mac.


Prendere in considerazione gli ambienti multischermo è l'unica risposta corretta, altrimenti lo schermo in cui appare la finestra potrebbe essere casuale o la finestra è centrata tra i due schermi.
Stephan

6

Finalmente ho ottenuto questo gruppo di codici per funzionare in NetBeans usando Swing GUI Forms per centrare jFrame principale:

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

}

O

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

}

O

    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

Quanto segue non funziona per JDK 1.7.0.07:

frame.setLocationRelativeTo(null);

Mette l'angolo in alto a sinistra al centro, non è lo stesso che centrare la finestra. Anche l'altro non funziona, coinvolgendo frame.getSize () e 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);

Il metodo getSize () è ereditato dalla classe Component, quindi frame.getSize restituisce anche la dimensione della finestra. Quindi sottraendo metà delle dimensioni verticale e orizzontale dalle dimensioni verticale e orizzontale, per trovare le coordinate x, y di dove posizionare l'angolo in alto a sinistra, si ottiene la posizione del punto centrale, che finisce per centrare anche la finestra. Tuttavia, la prima riga del codice precedente è utile, "Dimension ...". Basta farlo per centrarlo:

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 imposta le dimensioni dello schermo. È in FrameDemo.java disponibile nei tutorial Java sul sito Oracle / Sun. L'ho impostato a metà altezza / larghezza delle dimensioni dello schermo. Quindi, l'ho centrato posizionando la parte superiore sinistra a 1/4 della dimensione della dimensione dello schermo da sinistra e 1/4 della dimensione della dimensione dello schermo dall'alto. Puoi usare un concetto simile.


1
Nemmeno l'altro. Questi codici posizionano l'angolo superiore sinistro dello schermo al centro.
Jonathan Caraballo

7
-1 non può riprodurre - o più precisamente: accade solo se setLocationRelative viene chiamato prima di ridimensionare il frame (tramite pack o setSize manuale). Per una cornice di dimensioni zero, l'angolo in alto a sinistra è la stessa posizione del .. il suo centro :-)
kleopatra

3

di seguito è riportato il codice per la visualizzazione di una cornice in alto al centro della finestra esistente.

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) genera un'eccezione {

new SwingContainerDemo().showJFrameDemo();

}

Di seguito è riportato l'uscita dello snippet di codice sopra:inserisci qui la descrizione dell'immagine


1
frame.setLocation(x, 0);sembra essere sbagliato - non dovrebbe essere frame.setLocation(x, y);invece?
ritengono il

x denota la lunghezza dell'asse x ey denota la lunghezza dell'asse y. Quindi se rendi y = 0 allora solo dovrebbe essere in alto.
Aman Goel,

Quindi int y = (int) ((dimension.getHeight() - frame.getHeight()) / 2);esiste nel codice solo per mostrare che puoi centrare anche sull'asse verticale? Ok, pensavo ti fossi appena dimenticato di usarlo, scusa per i guai.
ritiene il

Nessun problema. Deem! È fantastico parlare con te.
Aman Goel

2

C'è qualcosa di veramente semplice che potresti trascurare dopo aver provato a centrare la finestra usando setLocationRelativeTo(null)o setLocation(x,y)e finisce per essere un po 'fuori centro.

Assicurati di utilizzare uno di questi metodi dopo aver chiamato pack()perché finirai per utilizzare le dimensioni della finestra stessa per calcolare dove posizionarla sullo schermo. Fino a quando non pack()viene chiamato, le dimensioni non sono quelle che penseresti, eliminando così i calcoli per centrare la finestra. Spero che questo ti aiuti.


2

Esempio: Dentro myWindow () sulla riga 3 c'è il codice necessario per posizionare la finestra al centro dello schermo.

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

Esempio completo:

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

Il codice seguente centra il Windowal centro del monitor corrente (cioè dove si trova il puntatore del mouse).

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

Potresti provare anche questo.

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
E i monitor multipli?
Supuhstar

0

In realtà frame .getHeight()e non getwidth()restituisce valori, controllalo inserendo System.out.println(frame.getHeight());direttamente i valori per larghezza e altezza, quindi funzionerà bene al centro. es: come sotto

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

entrambi 450 è il mio telaio larghezza n altezza


1
-1 la dimensione di un frame è zero prima di ... dimensionarlo :-) Preferibilmente per pacchetto, o almeno impostando manualmente la sua dimensione su qualsiasi cosa diversa da zero prima di chiamare setLocationRelative consentirà il suo corretto calcolo interno
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

L'ordine delle chiamate è importante:

primo -

pack();

secondo -

setLocationRelativeTo(null);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.