2

I noticed a strange behavior between containers in the swing.

To exemplify the test, I created a JFrame and a JPanel, and set the panel as contentPane. I defined the preferred and maximum JPanel size to 400,300. All this can be seen in the example below:

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

The result is:

inserir a descrição da imagem aqui

To my surprise, the output at the terminal is:

panel size: [400,300]
frame size: [416,338]

I did not understand why the frame added this extra space, even having nothing in the component that forces the frame to resize.

I tried to set zeroed edges on the panel by adding the row panel.setBorder (BorderFactory.createEmptyBorder(0, 0, 0, 0)); before pack(); but the result is still the same.

The problem with this is that java is giving me a false info, since the panel is scaling in the size of the frame, and from the above result, we have seen that the two are not the same size.

Are the two measures being reported correctly? Why does this occur?

  • 1
    Perhaps this may be helpful: http://stackoverflow.com/a/11939203/6776262 – quackenator May 10 '17 at 18:20
  • Thanks @quackenator . But I would also like to understand why this extra space to only contain an empty panel with fixed dimensions. – Blastoise Opressor May 10 '17 at 18:25
  • 3
    The JFrame includes the outside border and title bar. You could try `frame.getContentPane().getSize();` to get the contentpane's size. – quackenator May 10 '17 at 18:34
  • @quackenator frame.getContentPane().getSize(); return the same size on `panel.getSize()`, but in the image, the panel width is the same of width frame. – Blastoise Opressor May 10 '17 at 18:46
  • 1
    Shouldn't it though? You set the content pane to `panel`, and the layout manager chose a size that encapsulated this size for `frame` since there is nothing else in that frame. So the content pane's dimensions currently match those of `panel` and the full dimensions of `frame` include the title bar and window border – quackenator May 10 '17 at 18:54
  • (1-) `but in the image, the panel width is the same of width frame.` - what are you talking about??? The frame is obviously bigger because of the border and the title bar. These are included in the size of the frame, not just the content pane! What don't you understand about this concept? – camickr May 10 '17 at 20:06
  • When "packed", a Window will pack itself around the content pane, this is done to ensure that the content pane is given the amount of space it wants, otherwise it would be smaller then requested. You also have to realise that different operating systems have different window border requirements, so the frame size is actually variable, but the content size is not. I'm not sure why this is an issue, I'd have to kill someone if it was the other way round – MadProgrammer May 10 '17 at 20:34
  • *"but in the image, the panel width is the same of width frame."* - Not it's not, the panel is your desired size, the window is larger to compensate for the requirements of the window border - have a look at [this example](http://stackoverflow.com/questions/16473627/java-jframe-setsizex-y-not-working/16473639#16473639) for more details – MadProgrammer May 10 '17 at 20:37
  • *"I did not understand why the frame added this extra space, even having nothing in the component that forces the frame to resize"* - but - *" I defined the preferred and maximum JPanel size to 400,300"* - What were expectations when you did this? – MadProgrammer May 10 '17 at 20:38
  • Expanding on @camickr's comment, your example has _two_ borders: a red one _inside_ the panel and a the blue one belonging to the frame peer supplied by Windows. – trashgod May 10 '17 at 20:53
  • @camickr I had not noticed the vertical bar until I saw the print of the answer. My question was because of these 16px more width. – Blastoise Opressor May 10 '17 at 21:34

1 Answers1

2

You may find it helpful to compare the result from a similar program on a different platform. In particular,

  • The red Border is inside the panel; your usage conforms to the API recommendation, "we recommend that you put the component in a JPanel and set the border on the JPanel."

  • The frame width matches the panel width on Mac OS X because the heavyweight peer used for the top-level container has no vertical border on Mac OS X; the Windows peer has its own border.

  • The frame height includes the drag bar and frame border: 38 pixels on Widows, 22 on Mac OS X.

  • Don't use setPreferredSize() when you really mean to override getPreferredSize().

  • As an aside, the frame's add() method forwards to the content pane.

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();
        });
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045