Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Vertically center GridBagLayout like BoxLayout

I am trying to center components using a GridBagLayout in the same manner that a Box centers components when you use Box.createVerticalGlue(). I initially did use a vertical Box:

Box box = Box.createVerticalBox();
box.add(Box.createVerticalGlue());
box.add(add);
box.add(remove);
box.add(edit);
box.add(Box.createVerticalGlue());

JPanel internalPanel = new JPanel(new BorderLayout());
internalPanel.add(keywordsScrollPane, BorderLayout.CENTER);
internalPanel.add(box, BorderLayout.EAST);

But as you can see, it looks sloppy because my buttons are different sizes:

Sloppy Buttons

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I decided to switch to GridBagLayout so I can utilize GridBagConstraints.fill. This approach fixes my button width issue, but I cannot figure out how to vertically center the buttons. I changed the grid size and placed the buttons in the middle three rows, but the buttons were still appearing at the top of the panel. I tried making use of GridBagConstraints.anchor and GridBagConstraints.weighty as well. The latter almost worked, but there are very large margins between the buttons:

Large Margins

I am looking for the buttons to be grouped together as they were in my Box approach. How can I achieve this with a GridBadLayout?

I am using a class I created called ConstraintsBuilder which works exactly as you would expect. It’s for creating GridBagContraints with nice one-liners. Here is all the (relevant) code for your viewing pleasure:

public class KeywordsDialog extends JDialog implements ActionListener, ListSelectionListener {

    private JList<String> keywords;
    private JScrollPane keywordsScrollPane;
    private JButton add;
    private JButton remove;
    private JButton edit;

    private Set<String> keywordsList;

    public KeywordsDialog(Window parent, Collection<String> keywordsList) {
        super(parent);

        this.keywordsList = keywordsList == null ? new HashSet<String>() : new HashSet<String>(keywordsList);
        if (keywordsList != null && !keywordsList.isEmpty()) {
            this.keywords = new JList<String>(toListModel(keywordsList));
        } else {
            this.keywords = new JList<String>(new DefaultListModel<String>());
        }
        this.keywordsScrollPane = new JScrollPane(keywords);

        this.add = new JButton("Add");
        this.remove = new JButton("Remove");
        this.edit = new JButton("Edit");

        this.edit.setEnabled(false);
        this.add.setEnabled(false);

        ConstraintsBuilder builder = LayoutUtils.gridBagConstraintsBuilder();
        JPanel internalPanel = new JPanel(new GridBagLayout());
        internalPanel.add(this.keywordsScrollPane, builder.gridX(0).gridY(0).gridHeight(3).margins(0, 0, 0, 5)
                .fill(GridBagConstraints.BOTH).weightX(1D).weightY(1D).build());
        internalPanel.add(this.add,
                builder.reset().gridX(1).gridY(0).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());
        internalPanel.add(this.remove,
                builder.reset().gridX(1).gridY(1).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());
        internalPanel.add(this.edit,
                builder.reset().gridX(1).gridY(2).fill(GridBagConstraints.HORIZONTAL).weightX(1D).weightY(1D).build());

        this.keywords.setBorder(BorderFactory.createTitledBorder("Keywords"));
        internalPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        this.setLayout(new BorderLayout());
        this.add(internalPanel, BorderLayout.CENTER);

        Dimension screen = GuiHelper.getScreenSize(parent);
        this.setSize((int) (screen.getWidth() / 4), (int) (screen.getHeight() / 3));
        this.setLocationRelativeTo(parent);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    }
    // ...
}

>Solution :

I would make the GUI simpler. Put the three buttons into a JPanel that uses a GridLayout, one declared to use 1 column and variable number of rows, one with a desired spacing between buttons, here, 5 pixels: JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 5, 5)); and then put that JPanel into the center of a another JPanel, and GridBagLayout without constraints works well for this:

JPanel sidePanel = new JPanel(new GridBagLayout());
sidePanel.add(buttonPanel);

and put that JPanel into the right side of a border layout using JPanel. For example:

enter image description here

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

public class FooSwing01 extends JPanel {

    public FooSwing01() {
        JTextArea textArea = new JTextArea(20, 50);
        JScrollPane scrollPane = new JScrollPane(textArea);
        
        JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 5, 5));
        int maxButtons = 3;
        for (int i = 0; i < maxButtons; i++) {
            buttonPanel.add(new JButton("Button " + (i + 1)));
        }
        
        JPanel sidePanel = new JPanel(new GridBagLayout());
        sidePanel.add(buttonPanel);
        
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout(5, 5));
        add(scrollPane);
        add(sidePanel, BorderLayout.LINE_END);
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("GUI");
            frame.add(new FooSwing01());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading