Reputation: 75
This is honestly so frustrating, especially since I think it should be an easy solution. I'm creating a grid of JButtons and I'm trying to get rid of spaces in-between the buttons. I've tried going from a GridLayout to a GridBagLayout and I also added constraints. I've tried messing with fill, insets, gridwidth, and gridheight. When I was using GridLayout, I printed out the hgap and vgap of the components, and they were zero. I've been looking at tutorials of GridBagLayout and GridLayout and I'm not sure what I'm missing.
JPanel middle = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
for (int i = 0; i < buttons.length; i++) {
c.gridy = i;
for (int j = 0; j < buttons[i].length; j++) {
c.gridx = j;
buttons[i][j] = new JButton("");
buttons[i][j].setPreferredSize(new Dimension(60, 90));
middle.add(buttons[i][j], c);
//buttons[i][j].addActionListener(new ButtonListener());
}
}
This is what the GUI looks like:
Upvotes: 1
Views: 207
Reputation: 37835
Like some others in the comments are saying, this is an issue with the button UI itself.
There are some other UIs that are a bit more square if you want to fit them tightly together, for example:
buttons[i][j].setUI(new javax.swing.plaf.basic.BasicButtonUI());
Border b = new javax.swing.plaf.basic.BasicBorders.ButtonBorder(
Color.gray, Color.darkGray, Color.gray, Color.lightGray);
buttons[i][j].setBorder(b);
buttons[i][j].setBackground(Color.white);
However, the documentation for this kind of thing is pretty sparse, so I'm not sure how proper this actually is.
Another way to set the UI is through the UI manager, which sets the UI across the board:
UIManager.put("ButtonUI", "javax.swing.plaf.basic.BasicButtonUI");
Besides setting the UI, you could write a custom appearance by hand, by setting the border and writing listeners to account for all of the interactions. Here's an example:
class CompactButton extends JButton {
Border pressed = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
Border released = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
Border highlight = BorderFactory.createLineBorder(new Color(0xADD8E6), 2);
Border focused = BorderFactory.createCompoundBorder(released, highlight);
void setPressed(boolean isPressed) {
if (isPressed) {
setBorder(pressed);
setBackground(Color.lightGray);
} else {
setBorder(released);
setBackground(Color.white);
}
}
CompactButton() {
setBorder(released);
setOpaque(true);
setBackground(Color.white);
addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setPressed(getModel().isPressed());
}
});
addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
setBorder(focused);
}
@Override
public void focusLost(FocusEvent e) {
setBorder(released);
}
});
}
}
This does look rather nice:
To be honest, I'm not really sure how robust either of these options are, although I've personally never had an issue with them. The documentation for plaf.basic
is a little foreboding, but I've seen some other answers around SO saying that setting the UI is fine. The question is whether it will work universally on a multitude of platforms, which I don't know.
Upvotes: 1