0

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

gabit
  • 23
  • 5
  • 2
    A frame's visible content size is the frame size minus the frame's decorations insets. So you 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 panel ... 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 – MadProgrammer Aug 09 '22 at 22:31
  • Possible duplicate [How to get the EXACT middle of a screen, even when re-sized](https://stackoverflow.com/questions/13457237/how-to-get-the-exact-middle-of-a-screen-even-when-re-sized/13460914#13460914); [How can I set in the midst?](https://stackoverflow.com/questions/13734069/how-can-i-set-in-the-midst/13734319#13734319); [Java graphic image](https://stackoverflow.com/questions/13077858/java-graphic-image/13078040#13078040); [Graphics rendering in title bar](https://stackoverflow.com/questions/13313084/graphics-rendering-in-title-bar/13316131#13316131) – MadProgrammer Aug 09 '22 at 22:34
  • 1
    __never-ever__ do any manual sizing or locating that's the exclusive task of a suitable layoutManager – kleopatra Aug 09 '22 at 23:29

1 Answers1

2

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);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366