Q: How to center text in one grid of a button that span in two grids? I am trying to recreate Mac Calculator GUI. I use Swing and GridBagLayout for this project.
I manage to put 0 in a button that span in 2 column grid but I want to center it in the first column grid instead of 2 column grid.
Basically I want to the button to look exactly like:
.
In the calculator, the first column grid (consists of button "AC", "1", "4", "7" and "0") has the texts center evenly.
Here I try to use setHorizontalAlignment(SwingConstants.LEFT) but the result is not what I want.
 
JButton bt
n_0 = new JButton("0");
btn_0.setHorizontalAlignment(SwingConstants.LEFT);
GridBagConstraints gbc_btn_0 = new GridBagConstraints();
gbc_btn_0.fill = GridBagConstraints.HORIZONTAL;
gbc_btn_0.gridwidth = 2;
gbc_btn_0.insets = new Insets(0, 0, 5, 5);
gbc_btn_0.gridx = 0;
gbc_btn_0.gridy = 5;
frame.getContentPane().add(btn_0, gbc_btn_0);

Is it possible to achieve or are there alternative way to do this?

A: Do you absolutely need buttons ? I'm not used to the Mac, but if those calculator keys don't require an actual "button" behaviour (3D effect, moving the text when pressed, etc), maybe a plain JPanel would do.
In that case, if your "0" key is a JPanel, applying a GridLayout(1,2) to it and putting a JLabel("0") in the first cell and nothing in the second one would probably achieve the result you want.
Now of course you'll need handle click and key events at the JPanel level (look for example at this answer for more) but I think it would be a "clean" (from a component hierarchy point of view) way of doing it.
Update: Here is what I mean (part between ### comments):
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Calculator {
    public static final Color CALC_BACKGROUND = new Color(44, 45, 47);
    public static final Color KEY_BG_LAST_OPERATION = new Color(255,159,12);
    public static final Color KEY_BG_NUMBER = new Color(96,97,99);
    public static final Color KEY_BG_SPECIAL = new Color(64,65,67);
    public static final Font BUTTON_FONT = new Font("SansSerif", Font.PLAIN, 30);    

    private static JComponent make0Button(String text) {
        JPanel panel = new JPanel();
        panel.setBorder(new LineBorder(CALC_BACKGROUND));
        panel.setBackground(KEY_BG_NUMBER);
        final JLabel label = new JLabel(text);
        label.setFont(BUTTON_FONT);
        label.setForeground(Color.WHITE);
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setVerticalAlignment(JLabel.CENTER);

        //#######################################
        // The "0" key is a panel with two cells
        panel.setLayout(new GridLayout(1, 2));
        // The "0" text on the left
        panel.add(label);
        // A blank (dummy) label on the right
        panel.add(new JLabel(" "));
        //#######################################

        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println(text);
            }
        });
        return panel;
    }

    private static JComponent makeStdButton(String text, Color color) {
        JPanel panel = new JPanel();
        panel.setBorder(new LineBorder(CALC_BACKGROUND));
        panel.setBackground(color);
        panel.setLayout(new GridLayout(1, 1));
        JLabel label = new JLabel(text);
        label.setFont(BUTTON_FONT);
        label.setForeground(Color.WHITE);
        label.setHorizontalAlignment(JLabel.CENTER);
        label.setVerticalAlignment(JLabel.CENTER);
        panel.add(label);
        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println(text);
            }
        });
        return panel;
    }

    public static void addComponentsToPane(Container container) {
        container.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        // Result (top)
        c.anchor = GridBagConstraints.EAST;
        c.fill = GridBagConstraints.BOTH;
        c.gridwidth = 4;
        c.gridx = 0; c.gridy = 0;
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.setBackground(CALC_BACKGROUND);
        final JLabel resultLabel = new JLabel("0");
        resultLabel.setFont(new Font("SansSerif", Font.PLAIN, 100));
        resultLabel.setForeground(Color.WHITE);
        panel.add(resultLabel, BorderLayout.EAST);
        container.add(panel, c);

        // Special "0" key
        c = new GridBagConstraints();
        c.anchor = GridBagConstraints.CENTER;
        c.fill = GridBagConstraints.BOTH;
        c.gridwidth = 2;
        c.gridx = 0; c.gridy = 5;
        container.add(make0Button("0"), c);

        // All other keys
        c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.gridwidth = 1;
        c.weightx = 1;
        c.weighty = 1;
        c.gridx = 0; c.gridy = 1;
        container.add(makeStdButton("AC", KEY_BG_SPECIAL), c);
        c.gridx = 1; c.gridy = 1;
        container.add(makeStdButton("+/-", KEY_BG_SPECIAL), c);
        c.gridx = 2; c.gridy = 1;
        container.add(makeStdButton("%", KEY_BG_SPECIAL), c);
        c.gridx = 3; c.gridy = 1;
        container.add(makeStdButton("/", KEY_BG_LAST_OPERATION), c);

        c.gridx = 0; c.gridy = 2;
        container.add(makeStdButton("7", KEY_BG_NUMBER), c);
        c.gridx = 1; c.gridy = 2;
        container.add(makeStdButton("8", KEY_BG_NUMBER), c);
        c.gridx = 2; c.gridy = 2;
        container.add(makeStdButton("9", KEY_BG_NUMBER), c);
        c.gridx = 3; c.gridy = 2;
        container.add(makeStdButton("x", KEY_BG_LAST_OPERATION), c);

        c.gridx = 0; c.gridy = 3;
        container.add(makeStdButton("4", KEY_BG_NUMBER), c);
        c.gridx = 1; c.gridy = 3;
        container.add(makeStdButton("5", KEY_BG_NUMBER), c);
        c.gridx = 2; c.gridy = 3;
        container.add(makeStdButton("6", KEY_BG_NUMBER), c);
        c.gridx = 3; c.gridy = 3;
        container.add(makeStdButton("-", KEY_BG_LAST_OPERATION), c);

        c.gridx = 0; c.gridy = 4;
        container.add(makeStdButton("1", KEY_BG_NUMBER), c);
        c.gridx = 1; c.gridy = 4;
        container.add(makeStdButton("2", KEY_BG_NUMBER), c);
        c.gridx = 2; c.gridy = 4;
        container.add(makeStdButton("3", KEY_BG_NUMBER), c);
        c.gridx = 3; c.gridy = 4;
        container.add(makeStdButton("+", KEY_BG_LAST_OPERATION), c);

        c.gridx = 2; c.gridy = 5;
        container.add(makeStdButton(".", KEY_BG_NUMBER), c);
        c.gridx = 3; c.gridy = 5;
        container.add(makeStdButton("=", KEY_BG_LAST_OPERATION), c);
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addComponentsToPane(frame.getContentPane());
        frame.setSize(400,600);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGUI());
    }
}

Looks to me it's quite close to the expected layout... (with clicks, see console)


A: I recommend you to use:

mig_layout library.

allows you to make easy/adaptable designs and you can solve your problem.
