Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping preferred sizes of components in center of BorderLayout

I have a medium-large UI that uses a BorderLayout; the center is a tabbed pane containing various panels with various layouts, etc.

I want the panel in the center of this border layout to resize according to the size of the window, but I don't want the components within the panel to stretch. Labels, combo boxes, text fields, buttons -- I want them to stay at their preferred sizes, and allow the panel that contains them to stretch. I put them in a scroll pane in case the space gets too small for the panel.

Various posters with colorful vocabularies warn against the danger of using any of the setXXXsize() methods on components. That's what I do now, and I'd like to learn how to avoid it.

GridBagLayout is not appropriate for some of my panels. It is, by nature, oriented around rows and columns, and not everything fits into rows and columns. Of course I could create artificial rows and columns to fit everything into, but I'm really hoping Swing has more layout options than that.

Vertical Glue doesn't do it either. I've included it in HFOE's beloved SSCE:

    package example;

    import java.awt.BorderLayout;

    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;

    public class BorderAndBox extends JFrame
    {
        public static void main(String args[])
        {
            BorderAndBox bnb = new BorderAndBox();
            bnb.createUI();
            bnb.setVisible(true);
        }

        public void createUI()
        {
            JPanel borderPanel = new JPanel(new BorderLayout());

            JLabel northLabel = new JLabel("Nawth");
            borderPanel.add(northLabel, BorderLayout.NORTH);

            String[] southComboChoices = { "one", "two", "three" };
            JComboBox southCombo = new JComboBox(southComboChoices);
            borderPanel.add(southCombo, BorderLayout.SOUTH);

            JPanel centerPanel = new JPanel();
            centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
            String[] firstChoices = { "first", "uno", "UN" };
            String[] secondChoices = { "second", "dos", "zwei" };
            String[] thirdChoices = { "third", "tres", "drei" };
            JComboBox firstCombo = new JComboBox(firstChoices);
            JComboBox secondCombo = new JComboBox(secondChoices);
            JComboBox thirdCombo = new JComboBox(thirdChoices);
            centerPanel.add(firstCombo);
            centerPanel.add(secondCombo);
            centerPanel.add(thirdCombo);
            centerPanel.add(Box.createVerticalGlue());  // first attempt; does NOT
            // take up available vertical space, instead it appears to create a space
            // that is shared equally among the (now) four components of this space.
            borderPanel.add(centerPanel, BorderLayout.CENTER);

            getContentPane().add(borderPanel);
            pack();
        }

    }

If you enlarge the window, the comboboxes in the center enlarge; as written, a vertical glue piece below them also enlarges, but doesn't take up all available space. It appears it is given as much space as each of them.

So what is a good way to approach this?

like image 625
arcy Avatar asked Mar 02 '12 16:03

arcy


People also ask

How many ways we can arrange components in BorderLayout?

The BorderLayout is used to arrange the components in five regions: north, south, east, west, and center. Each region (area) may contain one component only.

How many components can be added to a region in the BorderLayout?

There can only be one component in any region, so any component already in the named region is removed. To get multiple components in one region of a BorderLayout, group the components in another container, and add the container as a whole to the layout.

What happens when more than one component is added to a particular region in a BorderLayout?

Note : Using BorderLayout manager, we can only add one component in a particular region. If we add more than one component in any region, only the last added component will be visible in that region.

Which of the following is the constant of BorderLayout?

For border layouts, the constraint must be one of the following constants: NORTH , SOUTH , EAST , WEST , or CENTER . Most applications do not call this method directly. This method is called when a component is added to a container using the Container. add method with the same argument types.


1 Answers

BorderAndBox - centered

import java.awt.BorderLayout;
import java.awt.GridBagLayout;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class BorderAndBox extends JFrame
{
public static void main(String args[])
{
    BorderAndBox bnb = new BorderAndBox();
    bnb.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    bnb.createUI();
    bnb.setVisible(true);
}

public void createUI()
{
    JPanel borderPanel = new JPanel(new BorderLayout());

    JLabel northLabel = new JLabel("Nawth");
    borderPanel.add(northLabel, BorderLayout.NORTH);

    String[] southComboChoices = { "one", "two", "three" };
    JComboBox southCombo = new JComboBox(southComboChoices);
    borderPanel.add(southCombo, BorderLayout.SOUTH);

    JPanel centerPanel = new JPanel();
    centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
    String[] firstChoices = { "first", "uno", "UN" };
    String[] secondChoices = { "second", "dos", "zwei" };
    String[] thirdChoices = { "third", "tres", "drei" };
    JComboBox firstCombo = new JComboBox(firstChoices);
    JComboBox secondCombo = new JComboBox(secondChoices);
    JComboBox thirdCombo = new JComboBox(thirdChoices);
    centerPanel.add(firstCombo);
    centerPanel.add(secondCombo);
    centerPanel.add(thirdCombo);
    centerPanel.add(Box.createVerticalGlue());  // first attempt; does NOT
    // take up available vertical space, instead it appears to create a space
    // that is shared equally among the (now) four components of this space.
    JPanel centerPanelConstrain = new JPanel(new GridBagLayout());
    centerPanelConstrain.add(centerPanel);
    borderPanel.add(centerPanelConstrain, BorderLayout.CENTER);

    getContentPane().add(borderPanel);
    pack();
}

}

See also this answer. There is more than one way to solve this.

like image 152
Andrew Thompson Avatar answered Sep 29 '22 04:09

Andrew Thompson