15
votes

I have panel that is using group layout to organize some label. I want to keep this panel center of the screen when re sized. If i put the panel inside a another panel using flow layout i can keep the labels centered horizontally but not vertically. Which layout manager will allow me to keep the panel centered in the middle of the screen?

I also tried border layout and placed it in the center but it resizes to the window size.

4

4 Answers

25
votes

Try using a GridBagLayout and adding the panel with an empty GridBagConstrants object.
For example:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setLayout(new GridBagLayout());
    JPanel panel = new JPanel();
    panel.add(new JLabel("This is a label"));
    panel.setBorder(new LineBorder(Color.BLACK)); // make it easy to see
    frame.add(panel, new GridBagConstraints());
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}
10
votes

First, I should mention, read my article on layouts: http://web.archive.org/web/20120420154931/http://java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/. It's old but very helpful (unfortunately that article pre-dates BoxLayout. I have some slides when I gave that talk at JavaOne, which includes BoxLayout at http://javadude.com/articles/javaone)

Try BoxLayout:

Box verticalBox = Box.createVerticalBox();
verticalBox.add(Box.createVerticalGlue());
verticalBox.add(stuffToCenterVertically);
verticalBox.add(Box.createVerticalGlue());

and if you want to center that stuff, use a HorizontalBox as the stuffToCenterVertically:

Box horizontalBox = Box.createHorizontalBox();
horizontalBox.add(Box.createHorizontalGlue());
horizontalBox.add(stuffToCenter);
horizontalBox.add(Box.createHorizontalGlue());

Way easier to "see" in the code than gridbag

0
votes

You can build you own LayoutManager to center a single component(both axis or just one). Here is the one which does it on both axis, you can easily change it to have vertical or horizontal centering.

The current implementation layouts first visible child, you can change that too...

public class CentreLayout implements LayoutManager, java.io.Serializable {

public void addLayoutComponent(String name, Component comp) {
}

public void removeLayoutComponent(Component comp) {
}

public Dimension preferredLayoutSize(Container target) {
    return target.getPreferredSize();
}

public Dimension minimumLayoutSize(Container target) {
    return target.getMinimumSize();
}

public void layoutContainer(Container target) {
    synchronized (target.getTreeLock()) {
        Insets insets = target.getInsets();
        Dimension size = target.getSize();
        int w = size.width - (insets.left + insets.right);
        int h = size.height - (insets.top + insets.bottom);
        int count = target.getComponentCount();

        for (int i = 0; i < count; i++) {
            Component m = target.getComponent(i);
            if (m.isVisible()) {
                Dimension d = m.getPreferredSize();
                m.setBounds((w - d.width) / 2, (h - d.height) / 2, d.width, d.height);
                break;
            }
        }
    }
}

}
0
votes

GroupLayout on the panel itself, with GroupLayout.Alignment.CENTER, for both vertical and horizontal, and setPreferredSize(new Dimension(yourChosenWidth,yourChosenHeight)) to set the panel to not resize.

You might also do setMinimumSize and setMaximum size on the panel, just to be safe.

If you're feeling snazzy, you can just use one single GroupLayout for the whole thing, by carefully choosing parallel/sequential groups and grouping the labels appropriately.