tags:

views:

1929

answers:

4

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.

+3  A: 

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);
}
Michael Myers
+2  A: 

First, I should mention, read my article on layouts: http://developer.java.sun.com/developer/onlineTraining/GUI/AWTLayoutMgr/. It's old but very helpful (unfortunately that article pre-dates BoxLayout)

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

Scott Stanchfield
I agree that GridBagLayout is generally more complex, but for centering a single panel, it's only two lines.
Michael Myers
The problem is that you cannot "see" that when reading the code... (I've edited my answer to state "see" rather than "easier"...)
Scott Stanchfield
I "see"... But on the other hand "createVerticalGlue()" means nothing to me either, without reading the docs.
Michael Myers
fair... but gives a little more hint than an empty GridBagConstraints ;)
Scott Stanchfield
I agree that you'll have more luck with a BoxLayout. They are much easier to use than GridBag. And no matter what you choose, reading the docs a little (at least the Swing Layout sample doc, which is pretty short) is always a good idea.
David Irwin
A: 

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.

BobMcGee
A: 

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

}
adrian.tarau
unfortunately, this doesn't work for me. I get a stack overflow (haha) in the method `preferredLayoutSize`.
Atmocreations