Reputation: 1604
I'm making a calculator with Swing for practice, and I can't figure out why I have this gap between the edge of JButton rows and the edge of the parent JPanel (buttonPanel
). I looked through my code and changed stuff, but I still can't figure out why the gap is there. If I remove MatteBorder, leaving the border as default, the gap goes away, but then I will have double borders between the buttons. If I reduce the column size of my JTextField
to like 7, then the gap will go away. How can I fix the gap without having to resort to double borders or making my application smaller?
(I set the background of the panel to red to help identify which component was causing the gap.)
public class CalculatorView extends JFrame {
// NOTE: Not recommended to extend JFrame, recommended to use composition over inheritance
private JTextField display = new JTextField("0", 17);
// Number buttons
private JButton zeroButton = new JButton("0");
private JButton oneButton = new JButton("1");
private JButton twoButton = new JButton("2");
private JButton threeButton = new JButton("3");
private JButton fourButton = new JButton("4");
private JButton fiveButton = new JButton("5");
private JButton sixButton = new JButton("6");
private JButton sevenButton = new JButton("7");
private JButton eightButton = new JButton("8");
private JButton nineButton = new JButton("9");
private JButton periodButton = new JButton(".");
// Operation buttons
private JButton additionButton = new JButton("+");
private JButton subtractionButton = new JButton("-");
private JButton divisionButton = new JButton("÷");
private JButton multiplicationButton = new JButton("x");
private JButton signChangeButton = new JButton("+/-");
private JButton percentButton = new JButton("%");
private JButton clearButton = new JButton("AC");
private JButton equalButton = new JButton("=");
CalculatorView() {
// Set the look and feel to the cross-platform look and feel,
// otherwise mac os will have quirks like gaps between jbuttons
try {
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {
System.err.println("Unsupported look and feel.");
e.printStackTrace();
}
// Let the OS set location, prevent user from resizing window, and exit app on close
this.setLocationByPlatform(true);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setUndecorated(true); // must be undecorated for setbackground to work
// Create the main panel, which by default covers the entire frame
// NOTE: Good practice. Never put components directly onto a JFrame.
JPanel gui = new JPanel();
// Set the main panel's layout manager to BorderLayout
gui.setLayout(new BorderLayout());
// Create the button panel
JPanel buttonPanel = new JPanel();
// Set button panel's layout manager to GridBagLayout
buttonPanel.setLayout(new GridBagLayout());
// Create a GridBagConstraints object to control the layout of components
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(0, 0, 0, 0);
c.fill = GridBagConstraints.HORIZONTAL;
// Position buttons on the grid
c.gridx = 0;
c.gridy = 0;
c.ipady = 30; // adjust vertical height of buttons
c.weightx = 1; // needed or buttons will cluster at center w/ gap on sides
buttonPanel.add(clearButton, c);
clearButton.setBackground(Color.gray);
clearButton.setOpaque(true);
clearButton.setBorder(new MatteBorder(0, 1, 0, 1, Color.BLACK));
c.gridx = 1;
buttonPanel.add(signChangeButton, c);
signChangeButton.setBackground(Color.gray);
signChangeButton.setOpaque(true);
signChangeButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK));
c.gridx = 2;
buttonPanel.add(percentButton, c);
percentButton.setBackground(Color.gray);
percentButton.setOpaque(true);
percentButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK));
c.gridx = 3;
buttonPanel.add(divisionButton, c);
divisionButton.setBackground(Color.ORANGE);
divisionButton.setOpaque(true);
divisionButton.setBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK));
c.gridx = 0;
c.gridy = 1;
buttonPanel.add(sevenButton, c);
sevenButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK));
c.gridx = 1;
buttonPanel.add(eightButton, c);
eightButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 2;
buttonPanel.add(nineButton, c);
nineButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 3;
buttonPanel.add(multiplicationButton, c);
multiplicationButton.setBackground(Color.ORANGE);
multiplicationButton.setOpaque(true);
multiplicationButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 0;
c.gridy = 2;
buttonPanel.add(fourButton, c);
fourButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK));
c.gridx = 1;
buttonPanel.add(fiveButton, c);
fiveButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 2;
buttonPanel.add(sixButton, c);
sixButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 3;
buttonPanel.add(subtractionButton, c);
subtractionButton.setBackground(Color.ORANGE);
subtractionButton.setOpaque(true);
subtractionButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 0;
c.gridy = 3;
buttonPanel.add(oneButton, c);
oneButton.setBorder(new MatteBorder(1, 1, 0, 1, Color.BLACK));
c.gridx = 1;
buttonPanel.add(twoButton, c);
twoButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 2;
buttonPanel.add(threeButton, c);
threeButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 3;
buttonPanel.add(additionButton, c);
additionButton.setBackground(Color.ORANGE);
additionButton.setOpaque(true);
additionButton.setBorder(new MatteBorder(1, 0, 0, 1, Color.BLACK));
c.gridx = 0;
c.gridy = 4;
c.gridwidth = 2; // spans 2 cells
buttonPanel.add(zeroButton, c);
zeroButton.setBorder(new MatteBorder(1, 1, 1, 1, Color.BLACK));
c.gridx = 2;
c.gridwidth = 1;
buttonPanel.add(periodButton, c);
periodButton.setBorder(new MatteBorder(1, 0, 1, 1, Color.BLACK));
c.gridx = 3;
buttonPanel.add(equalButton, c);
equalButton.setBackground(Color.ORANGE);
equalButton.setOpaque(true);
equalButton.setBorder(new MatteBorder(1, 0, 1, 1, Color.BLACK));
// Customize display field
display.setHorizontalAlignment(JTextField.RIGHT);
display.setFont(new Font("Arial", Font.PLAIN, 40));
display.setBorder(new EmptyBorder(30, 0, 0, 0));
display.setForeground(Color.WHITE);
// Make display translucent but leave button panel opaque
this.setBackground(new Color(0, 0, 0, 100));
gui.setBackground(new Color(0,0,0,100));
display.setBackground(new Color(0, 0, 0, 100));
// I need to fix the gap between the edge of the buttonPanel and the buttons...
buttonPanel.setBackground(Color.red);
// Add display and button panel to main panel, then main panel to frame
gui.add(display, BorderLayout.NORTH);
gui.add(buttonPanel, BorderLayout.CENTER);
this.add(gui);
this.pack();
}
}
Upvotes: 3
Views: 1181
Reputation: 306
I don't know why there is this gap, but if you set the following empty border, the background is gone:
JPanel buttonPanel = new JPanel();
// Set button panel's layout manager to GridBagLayout
buttonPanel.setLayout(new GridBagLayout());
buttonPanel.setBorder(new EmptyBorder(0, -1, 0, -1));
Upvotes: 2
Reputation: 339
Check every statement that assigns padding in the Y AXIS for the GridBagConstraints i.e.
c.ipady = 30;
Try to remove them or reduce them
Upvotes: 0