2017-05-10 4 views
2

Ich bemerkte ein seltsames Verhalten zwischen den Containern in der Schaukel.Warum überschreitet die Größe des JFrame die Größe seines ContentPane, obwohl er eine definierte Größe hat?

Um den Test zu veranschaulichen, habe ich ein JFrame und ein JPanel erstellt und das Panel als contentPane festgelegt. Ich habe die bevorzugte und maximale JPanel-Größe auf 400.300 festgelegt. All dies kann im Beispiel unten zu sehen:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ExcessiveSpacePanelTest { 
    JFrame frame; 
    JPanel panel; 

    public void initGUI(){ 

     frame = new JFrame(); 

     panel = new JPanel(); 
     panel.setBorder(BorderFactory.createLineBorder(Color.RED, 1)); 
     panel.setPreferredSize(new Dimension(400, 300)); 
     panel.setMaximumSize(new Dimension(400, 300)); 


     frame.setContentPane(panel); 
     frame.pack(); 

     System.out.println("panel size: [" + panel.getSize().width + "," + panel.getSize().height +"]"); 
     System.out.println("frame size: [" + frame.getSize().width + "," + frame.getSize().height+"]"); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(false); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() ->{ 
      new ExcessiveSpacePanelTest().initGUI(); 
     }); 
    } 
} 

Das Ergebnis ist:

inserir a descrição da imagem aqui

Zu meiner Überraschung, der Ausgang am Terminal ist:

Panel-Größe: [400,300]
Rahmengröße: [416,338]

Ich habe nicht verstanden, warum der Rahmen diesen zusätzlichen Platz hinzugefügt hat, sogar nichts in der Komponente, die den Rahmen zur Größenänderung zwingt.

Ich habe versucht, zeroed Kanten auf dem Panel durch Hinzufügen der Zeile panel.setBorder (BorderFactory.createEmptyBorder(0, 0, 0, 0)); vor pack();, aber das Ergebnis ist immer noch das gleiche.

Das Problem mit diesem ist, dass Java mir eine falsche Info gibt, da das Panel in der Größe des Rahmens skaliert, und vom obigen Ergebnis haben wir gesehen, dass die zwei nicht die gleiche Größe haben.

Werden die beiden Maßnahmen korrekt gemeldet? Warum passiert das?

+1

Vielleicht kann dies hilfreich sein: http://stackoverflow.com/a/11939203/6776262 – quackenator

+0

Dank @quackenator.Aber ich möchte auch verstehen, warum dieser zusätzliche Platz nur ein leeres Panel mit festen Abmessungen enthält. – Articuno

+3

Der JFrame enthält den äußeren Rahmen und die Titelleiste. Sie könnten 'frame.getContentPane(). GetSize();' versuchen, um die Größe des Inhaltspanels zu erhalten. – quackenator

Antwort

2

Es kann hilfreich sein, das Ergebnis eines ähnlichen Programms auf einer anderen Plattform zu vergleichen. Insbesondere

  • Die rote Border ist innen die Platte; Ihre Verwendung entspricht der API recommendation, "wir empfehlen, dass Sie die Komponente in eine JPanel setzen und den Rahmen auf der JPanel setzen."

  • Die Rahmenbreite entspricht der Feldbreite unter Mac OS X, da der schwergewichtige Peer, der für top-level container verwendet wird, unter Mac OS X keine vertikale Begrenzung hat; Der Windows-Peer hat eine eigene Grenze.

  • Die Rahmenhöhe enthält die Zugstange und Rahmen Grenze: 38 Pixel auf Widows, 22 auf Mac OS X.

  • nicht setPreferredSize() Verwenden Sie, wenn Sie wirklich getPreferredSize() außer Kraft bedeuten zu.

  • Nebenbei, die Methode add() des Frames wird an den Inhaltsbereich weitergeleitet.

panel size: [400,300] 
frame size: [400,322] 

image

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 

import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ExcessiveSpacePanelTest { 
    JFrame frame; 
    JPanel panel; 

    public void initGUI(){ 
     frame = new JFrame(); 
     panel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(400, 300); 
      } 
     }; 
     panel.setBorder(BorderFactory.createLineBorder(Color.RED, 1)); 
     frame.add(panel); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(false); 
     frame.setVisible(true); 

     System.out.println("panel size: [" + panel.getSize().width + "," + panel.getSize().height +"]"); 
     System.out.println("frame size: [" + frame.getSize().width + "," + frame.getSize().height+"]"); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() ->{ 
      new ExcessiveSpacePanelTest().initGUI(); 
     }); 
    } 
} 
+1

Danke, das verdeutlicht den Zweifel. – Articuno

Verwandte Themen