Once I hover over any of the round buttons a square background appears behind it and never disappears again. The button is still clickable while the square background isn't. I haven't implemented any MouseEvents so I have no idea why the background appears
left: after it's been clicked, center: after mouseover, right: original state
Code Sample
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class GUI implements ActionListener {
private JLabel textLabel;
private JButton buttonL, buttonConfirm, buttonR;
public GUI() {
JPanel mainDisplay = new JPanel();
mainDisplay.setBackground(new Color(172, 181, 176));
mainDisplay.setPreferredSize(new Dimension(150, 160));
mainDisplay.setLayout(new BorderLayout());
textLabel = new JLabel("1");
textLabel.setHorizontalAlignment(SwingConstants.CENTER);
mainDisplay.add(textLabel, BorderLayout.CENTER);
JPanel container = new JPanel();
container.setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.gridwidth = GridBagConstraints.REMAINDER;
gc.insets = new Insets(75, 0, 0, 0);
container.add(mainDisplay, gc);
Dimension buttonDimension = new Dimension(18, 18);
Color buttonColor = new Color(242, 240, 241);
buttonL = new RoundButton();
buttonL.setBackground(buttonColor);
buttonL.setPreferredSize(buttonDimension);
buttonL.addActionListener(this);
gc.gridwidth = GridBagConstraints.RELATIVE;
gc.insets = new Insets(10, 20, 0, 0);
container.add(buttonL, gc);
buttonConfirm = new RoundButton();
buttonConfirm.setBackground(buttonColor);
buttonConfirm.setPreferredSize(buttonDimension);
buttonConfirm.addActionListener(this);
gc.insets = new Insets(40, -35, 0, 0);
container.add(buttonConfirm, gc);
buttonR = new RoundButton();
buttonR.setBackground(buttonColor);
buttonR.setPreferredSize(buttonDimension);
buttonR.addActionListener(this);
gc.insets = new Insets(10, -50, 0, 0);
container.add(buttonR, gc);
JFrame frame = new JFrame();
frame.add(container);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == buttonL) {
textLabel.setText("L");;
} else if(e.getSource() == buttonConfirm) {
textLabel.setText("");
} else if(e.getSource() == buttonR) {
textLabel.setText("R");
}
}
public static void main(String[] args) {
new GUI();
}
}
Round JButton
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
public class RoundButton extends JButton {
Shape shape;
@Override
protected void paintComponent(Graphics g) {
g.setColor(getBackground());
g.fillOval(0, 0, getSize().width - 1, getSize().height - 1);
}
@Override
protected void paintBorder(Graphics g) {
g.setColor(Color.darkGray);
g.drawOval(0, 0, getSize().width - 1, getSize().height - 1);
}
@Override
public boolean contains(int x, int y) {
if (shape == null || !shape.getBounds().equals(getBounds())) {
shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
}
When doing custom painting the basic code should be:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// add custom painting here
}
This will make sure the background is cleared so there are no painting artifacts.
However, in your case you want the background of the parent panel to be painted before the button is painted so you need to use:
button.setOpaque(false);
Also, when you click on a button the rectangle will still appear indicating the button is in a pressed state. To remove this painting you need to use:
button.setContentAreaFilled( false );
Check out: Change JButton focus area for another implementation of a round button.