Reputation: 1132
I have created a simple GUI because I wanted to create a rounded JButton instead of the normal button. Therefore I created a class that extends JButton and overrides some methods to achieve the painting.
But as soon as I execute the code (using Java 13) the frame get created with an ugly yellow color, after that the button is included and the whole JFrame backgroundcolor changes. Why is that and how can I prevent it? I only want the button to be created, but nothing else to be color-changed or similar.
public class RoundedButton extends JButton {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setSize(800, 800);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setSize(new Dimension(200, 200));
JButton button = new RoundedButton("Text", 40, 2F, Color.BLACK);
button.setBackground(new Color(116, 10, 10));
button.setForeground(Color.WHITE);
button.setSize(new Dimension(200, 120));
button.setPreferredSize(new Dimension(200, 120));
button.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
button.setBackground(button.getBackground().brighter().brighter());
}
@Override
public void mouseExited(MouseEvent e) {
button.setBackground(button.getBackground().darker().darker());
}
});
panel.add(button, BorderLayout.CENTER);
frame.add(panel, BorderLayout.NORTH);
frame.setBackground(Color.YELLOW);
//frame.pack();
frame.setVisible(true);
}
private int arcRadius;
private float borderSize;
private Color borderColor;
public RoundedButton(String label, int arcRadius, float borderSize, Color borderColor) {
super(label);
this.setContentAreaFilled(false);
this.arcRadius = arcRadius;
this.borderSize = borderSize;
this.borderColor = borderColor;
}
@Override
public void paint(Graphics g) {
if(g instanceof Graphics2D) {
((Graphics2D) g).setStroke(new BasicStroke(borderSize));
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
//Draw background / fill button
g.setColor(this.getBackground());
g.fillRoundRect(getX(), getY(), this.getWidth(), (int)(this.getHeight()-borderSize), arcRadius, arcRadius);
//Draw border
g.setColor(borderColor);
g.drawRoundRect(getX(), getY(), this.getWidth(), (int)(this.getHeight()-borderSize), arcRadius, arcRadius);
//Draw font
if (this.getFont() != null && this.getText() != null) {
FontMetrics fm = getFontMetrics(getFont());
g.setColor(this.getForeground());
g.drawString(this.getText(), ((this.getWidth() / 2) - (fm.stringWidth(this.getText()) / 2)),
((this.getHeight() / 2) + fm.getMaxDescent()));
}
}
@Override
public boolean contains(int x, int y) {
return new RoundRectangle2D.Double(getX(), getY(), this.getWidth(), (int)(this.getHeight()-borderSize), arcRadius, arcRadius).contains(x, y);
}
@Override
public void updateUI() {
super.updateUI();
this.setContentAreaFilled(false);
this.setFocusPainted(false);
}
}
If I add this to the frame, the background of the color changes. Why is that?
Upvotes: 1
Views: 120
Reputation: 5870
The graphics object given to the paint method of a component should already be translated to the component's position. So all your painting should be done within (0,0) and (width, height).
I would have expected the clip to be set to the component's bounds as well, preventing you from painting outside of it. But maybe your button is covering a very large area of your frame, or the clip is null for some reason.
Specifically: g.drawRoundRect(0, 0, ...
Edit responding to question edit: BorderLayout is kind of undefined when you add something just to the NORTH, with nothing in the CENTER. Also, the panel and button's preferred sizes are ignored when placed into the center of border layouts.
Upvotes: 1