Center panel when window resized
Asked Answered
I

2

1

I would like to keep a panel I have created using an absolute layout in the center of my window even when the window is resized (if possible). I've come across a couple of suggestions here and [here][2] but no dice! Below is my sample code, any ideas or suggestions? I have no problems centered a single component like a JLable but I want to center a panel with many components!

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.JLabel;


public class TestPanel extends JFrame {

    private JLabel lblSetupTitle;
    private Border compoundBorder, outlineColorBorder, outlineBorder;
    private JTextArea txtrManageData;
    private JPanel childPanel;

    public TestPanel() 
    {
        setBackground(Color.white);
        outlineColorBorder = BorderFactory.createLineBorder(Color.gray);
        outlineBorder = BorderFactory.createEmptyBorder(20, 20, 20, 20);
        compoundBorder = BorderFactory.createCompoundBorder(outlineColorBorder, outlineBorder);

        lblSetupTitle = new JLabel("Setup");
        lblSetupTitle.setBounds(443, 288, 44, 23);
        txtrManageData = new JTextArea("Text Area Text");
        txtrManageData.setBounds(393, 322, 142, 61);

        childPanel = new JPanel();
        childPanel.setLocation(89, 38);
        childPanel.setSize(921, 452);
        childPanel.setBorder(compoundBorder);

        setupGUIElements();
        setupPanel();
    }

    private void setupGUIElements()
    {
        txtrManageData.setBackground(null);
        txtrManageData.setLineWrap(true);
        txtrManageData.setWrapStyleWord(true);
    }

    private void setupPanel()
    {
        getContentPane().setLayout(new GridBagLayout()); // set layout of parent panel to GridBagLayout
        childPanel.setLayout(null); // set layout of child panel to AbsoluteLayout
        childPanel.add(lblSetupTitle);
        childPanel.add(txtrManageData);

        getContentPane().add(childPanel, new GridBagConstraints());

        this.setSize(1020, 500);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                TestPanel ex = new TestPanel();
                ex.setVisible(true);
            }
        });
    }
}

EDIT: Any tips, links, guidance on creating something like this

example gui i would like to create

Indeciduous answered 6/11, 2014 at 9:17 Comment(6)
Don't use null LayoutManager.Baresark
Using an absolute layout us your burst mistake, BorderLayout or GrudBagLayout will do this for free. This is exactly (one of the many) reasons we have layout managers, to take care of these tedious, larbrious, repetitive tasks...Bland
Oh ..and it would help the layout if txtrManageData = new JTextArea("Text Area Text"); were instead something like txtrManageData = new JTextArea("Text Area Text", 3, 20);Exhilarant
Java GUIs have to work on different OS', screen size, screen resolution etc. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or combinations of them along with layout padding and borders for white space.Exhilarant
Also you use GridBagLayout in a wrong way. Check out its Javadoc, the class javadoc has a usage example.Kwangtung
Thanks for the feedback.. I kind of knew absolute layout wasn't the right play here but very much a newb at this.. any recommendations on creating something like the image above?Indeciduous
E
2

I'd nest layouts.

enter image description here

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;

public class ThreeButtonTextFieldCombo {

    private JPanel ui = null;

    ThreeButtonTextFieldCombo() {
        initUI();
    }

    public final void initUI() {
        if (ui!=null) return;
        ui = new JPanel(new GridBagLayout());
        ui.setBorder(new TitledBorder("Parent Panel"));

        JPanel controls = new JPanel(new GridLayout(1,0,10,10));
        ui.add(controls);
        controls.setBackground(Color.RED);
        controls.setBorder(new TitledBorder("Child Panel"));

        for (int ii=1; ii<4; ii++) {
            addLabelAndField(controls, "String " + ii);
        }
    } 

    public JComponent getUI() {
        return ui;
    }

    private void addLabelAndField(JPanel panel, String text) {
        JPanel controls = new JPanel(new BorderLayout(3, 3));
        controls.setBorder(new EmptyBorder(20,20,20,20));
        JLabel l = new JLabel(text);
        controls.add(l, BorderLayout.PAGE_START);

        JTextArea ta = new JTextArea(text, 2, 8);
        controls.add(new JScrollPane(ta));

        panel.add(controls);
    }

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

            @Override
            public void run() {
                JFrame f = new JFrame("Three Button/Text Field Combo");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);
                ThreeButtonTextFieldCombo tbtfc = 
                        new ThreeButtonTextFieldCombo();
                f.setContentPane(tbtfc.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Exhilarant answered 6/11, 2014 at 9:52 Comment(1)
OK ..button/label, label/button got a bit mixed up, but swap the labels for buttons and it will work just the same.Exhilarant
M
0

The first problem with your code is that you are adding your child panel using an empty instantiation of GridBagConstraints. I have never seen it used like that before.

getContentPane().add(childPanel, new GridBagConstraints());

Do not set any layout to content pane and just add it like this :

getContentPane().add(childPanel);

Now if you run it you will get the two components in the middle, where you defined them using the setBounds(..) method.

Like almost everyone commenting on your question, you should not use null layout, and use some other layout instead. I would use a GridBagLayout to organise the three buttons and three textfields in your diagram. You could then setBounds(..) on your child panel.

If you really must use absolute layout then you will have to do a bit of maths.

If your first label is like this :

labell1.setBounds(443, 288, 44, 23);

then your second label should be something like this :

labell2.setBounds(443 + someXDisplacement, 288, 44, 23);

..and third :

labell3.setBounds(443 + (someXDisplacement x 2), 288, 44, 23);

You get the picture.

Marijo answered 6/11, 2014 at 9:39 Comment(3)
"If you really must use absolute layout.." I'll really need absolute layouts when hell freezes over.Exhilarant
nice to get downvoted for answering exactly what the OP wanted. Expressly recommending them not to use AbsoluteLayout, but then giving them a suggestion if they do need to use it. Sometimes SO is a joke.Marijo
"nice to get downvoted.." Don't look at me for the down-vote. But.. "..for answering exactly what the OP wanted." ..I feel that is a mistake in this case.Exhilarant

© 2022 - 2024 — McMap. All rights reserved.