Home > Net >  Java Swing Jframe has less size than configured
Java Swing Jframe has less size than configured

Time:08-11

I want to place some elements inside a JFrame by setLocation(x, y) but my frame is not the size I expect.

The size of my JFrame is 600 x 400 but when I run the app it looks like a JFrame of about 550 x 350.

I would like to understand why this happens, even if there are better ways to implement it.

Thanks in advance for any assistance.

My code:

  public static void main(String[] args) {

      JFrame mainFrame = new JFrame("Example");
      mainFrame.setVisible(true);
      mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      mainFrame.setSize(600, 400);
      mainFrame.setLayout(null);
      mainFrame.setResizable(false);

      JPanel p1 = new JPanel();
      p1.setSize(100, 100);
      p1.setLocation(0,0);
      p1.setBackground(Color.BLUE);
      mainFrame.add(p1);

      JPanel p2 = new JPanel();
      p2.setSize(100, 100);
      p2.setLocation(500,300);
      p2.setBackground(Color.BLUE);
      mainFrame.add(p2);
  }

Output:

enter image description here

CodePudding user response:

A frame's visible content size is the frame size minus the frame's decorations insets.

So your viewable area will be 600x400 - frameDecorationInsets, and this will be variable (even across the same platform).

Instead, you should be looking at the size of the parent container, for example

enter image description here

Note, I'm running on MacOS, which has a different frame decoration then Windows, but this concept will still work on both ... and you get resizability

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {
        private JPanel p1 = new JPanel();
        private JPanel p2 = new JPanel();

        public TestPane() {
            setLayout(null);

            p1.setBackground(Color.BLUE);
            add(p1);

            p2.setBackground(Color.BLUE);
            add(p2);
        }

        @Override
        public void doLayout() {
            super.doLayout();
            p1.setSize(100, 100);
            p1.setLocation(0, 0);

            p2.setSize(100, 100);
            p2.setLocation(getWidth() - p2.getWidth(), getHeight() - p2.getHeight());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 400);
        }
    }
}

But...

Arguably, you shouldn't be using null layouts, you should be relying on things like JComponent#getPreferredSize and JFrame#pack to provide suitable hints about how best you want the window to be sized by default, for example...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            JPanel p1 = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
            };
            p1.setBackground(Color.BLUE);
            JPanel p2 = new JPanel() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(100, 100);
                }
            };
            p2.setBackground(Color.BLUE);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.anchor = GridBagConstraints.NORTHWEST;            
            add(p1, gbc);

            gbc.gridx = 1;
            gbc.gridy = 1;
            gbc.anchor = GridBagConstraints.SOUTHEAST;
            add(p2, gbc);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(600, 400);
        }
    }
}
  • Related