简体   繁体   English

将自定义 JButton 添加到 JFrame 会更改背景颜色

[英]Adding custom JButton to JFrame changes background color

I have created a simple GUI because I wanted to create a rounded JButton instead of the normal button.我创建了一个简单的 GUI,因为我想创建一个圆形的 JButton 而不是普通按钮。 Therefore I created a class that extends JButton and overrides some methods to achieve the painting.因此,我创建了一个扩展 JButton 并覆盖一些方法来实现绘画的类。

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.但是,一旦我执行代码(使用 Java 13),框架就会被创建为丑陋的黄色,之后包含按钮并且整个 JFrame 背景颜色都会发生变化。 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?这是为什么?

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).所以你所有的绘画都应该在 (0,0) 和 (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, ...具体来说: 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.编辑回答问题编辑:当您只向北添加一些东西而中心没有任何东西时,BorderLayout 有点未定义。 Also, the panel and button's preferred sizes are ignored when placed into the center of border layouts.此外,面板和按钮的首选大小在放置到边框布局的中心时会被忽略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM