Home > Blockchain >  Vertically center GridBagLayout like BoxLayout
Vertically center GridBagLayout like BoxLayout

Time:10-21

I am trying to center components using a Sloppy Buttons

I decided to switch to GridBagLayout so I can utilize 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);
    }
    // ...
}

CodePudding user response:

Oracle has a helpful tutorial, Example GUI

Here's the complete runnable code.

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class ExampleGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ExampleGUI());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Example GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createTextArea(), BorderLayout.CENTER);
        frame.add(createButtonPanel(), BorderLayout.EAST);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JScrollPane createTextArea() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        JTextArea textArea = new JTextArea(10, 30);
        textArea.setText("keyword");
        panel.add(textArea, BorderLayout.CENTER);

        return new JScrollPane(panel);
    }

    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new GridBagLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.insets = new Insets(0, 5, 5, 5);

        gbc.gridy = 0;
        JButton button = new JButton("Add");
        panel.add(button, gbc);

        gbc.gridy  ;
        button = new JButton("Remove");
        panel.add(button, gbc);

        gbc.gridy  ;
        button = new JButton("Edit");
        panel.add(button, gbc);

        return panel;
    }
}

CodePudding user response:

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);
        });
    }
}
  • Related