How can I properly center a JPanel ( FIXED SIZE ) inside a JFrame?

IT. picture IT. · Aug 28, 2011 · Viewed 59.6k times · Source

Hi all! I'm trying to solve an -apparently- simple problem, but I cannot fix it. I'm working on a sample application with Java/Swing libraries; I have a JFrame and a JPanel. I just want to achieve the following objectives:

  1. JPanel MUST be centered inside the JFrame.

  2. JPanel MUST have ALWAYS the size that is specified with
    setPreferredSize() method. It MUST NOT be resized under this size.

I tried by using a GridBagLayout: it's the ONLY way I can do it.

See the sample below:

/* file StackSample01.java */

import java.awt.*;
import javax.swing.*;

public class StackSample01 {
    public static void main(String [] args) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(100, 100));
        panel.setBackground(Color.RED);  

        frame.setLayout(new GridBagLayout());
        frame.add(panel, new GridBagConstraints());
        frame.setSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

Here a screenshot:

I would not use a GridBagLayout to do a thing too simple. I tried a simplest solution, by using a Box, but this does not work:

Sample code:

/* file StackSample02.java */

import java.awt.*;
import javax.swing.*;

public class StackSample02 {
    public static void main(String [] args) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(100, 100));
        panel.setBackground(Color.RED); // for debug 

        panel.setAlignmentX(JComponent.CENTER_ALIGNMENT); // have no effect

        Box box = new Box(BoxLayout.Y_AXIS);

        box.add(Box.createVerticalGlue());
        box.add(panel);     
        box.add(Box.createVerticalGlue()); // causes a deformation

        frame.add(box);
        frame.setSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

Here a screenshot,

Any ideas? Thanks to all :-)

Answer

mKorbel picture mKorbel · Aug 29, 2011

BoxLayout can pretty to hold your setXxxSize(), then just add panel.setMaximumSize(new Dimension(100, 100));

and your output would be

Removed by setMinimumSize(notice if Container has greater size as ... )

enter image description here enter image description here enter image description here

import java.awt.*;
import javax.swing.*;

public class CustomComponent12 extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent12() {
        Box box = new Box(BoxLayout.Y_AXIS);
        box.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        box.add(Box.createVerticalGlue());
        box.add(new CustomComponents12());
        box.add(Box.createVerticalGlue());
        add(box);
        pack();
        setTitle("Custom Component Test / BoxLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setMaximumSize(getMinimumSize());
        setMinimumSize(getMinimumSize());
        setPreferredSize(getPreferredSize());
        setLocation(150, 150);
        setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                CustomComponent12 main = new CustomComponent12();
            }
        };
        javax.swing.SwingUtilities.invokeLater(r);
    }
}

class CustomComponents12 extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(100, 100);
    }

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(100, 100);
    }

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

    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
    }
}