无法使用 Swing 绘制自定义按钮
Having trouble painting custom buttons with swing
我写了一个简短的程序,因为我想创建一个带有圆角的定制按钮。因此我扩展了 JButton class 并覆盖了 paintComponent 方法(见下面的代码)。
public class JRoundedButton extends JButton {
private int arcRadius;
public JRoundedButton(String label, int arcRadius) {
super(label);
this.setContentAreaFilled(false);
this.arcRadius = arcRadius;
}
@Override
protected void paintComponent(Graphics g) {
if(g instanceof Graphics2D) {
Graphics2D graphics = (Graphics2D) g;
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//Draw button background
graphics.setColor(getBackground());
graphics.fillRoundRect(getX(), getY(), getWidth() - 1, getHeight() - 1, arcRadius, arcRadius);
}
}
@Override
public boolean contains(int x, int y) {
return new RoundRectangle2D.Double(getX(), getY(), getWidth(), getHeight(), arcRadius, arcRadius).contains(x,y);
}
public int getArcRadius() {
return arcRadius;
}
public void setArcRadius(int arcRadius) {
this.arcRadius = arcRadius;
this.repaint();
}
}
当我创建一个简单的框架并将一个按钮添加到面板时,我将其添加到框架中,它完美地显示出来。但是一旦我想创建两个按钮并将它们设置在彼此下方(使用 Borderlayout 我使用 NORTH 和 SOUTH),只有上面的按钮显示正确。下面的按钮正确显示了文本(我从 painComponent(...) 方法中删除了该部分),但没有绘制背景。我不以任何方式使用 setOpaque(...) 方法。
可能是什么问题?
我需要设置自定义按钮的边界吗?
编辑:
下面是创建框架和显示按钮的代码:
public static void main(String[] args) {
JFrame frame = new JFrame("Buttontest");
frame.setSize(new Dimension(500, 500));
frame.setLayout(new BorderLayout());
JPanel contentPanel = new JPanel();
contentPanel.setSize(new Dimension(500, 500));
contentPanel.setLayout(new GridLayout(2, 1, 0, 20));
JRoundedButton button1 = new JRoundedButton("Rounded Button", 40);
button1.setForeground(Color.YELLOW);
button1.setBackground(Color.GREEN);
JRoundedButton button2 = new JRoundedButton("Rounded Button 2", 40);
button2.setBackground(Color.BLACK);
button2.setForeground(Color.WHITE);
contentPanel.add(button1);
contentPanel.add(button2);
frame.add(contentPanel, BorderLayout.CENTER);
frame.setVisible(true);
}
输出是这样的:
为什么下方按钮的背景不可见?应该是黑色的!
在您的 paintComponent()
中,您需要 fillRoundRect(0,0,...)
而不是 getX()
和 getY()
因为g是相对于组件本身的。
我写了一个简短的程序,因为我想创建一个带有圆角的定制按钮。因此我扩展了 JButton class 并覆盖了 paintComponent 方法(见下面的代码)。
public class JRoundedButton extends JButton {
private int arcRadius;
public JRoundedButton(String label, int arcRadius) {
super(label);
this.setContentAreaFilled(false);
this.arcRadius = arcRadius;
}
@Override
protected void paintComponent(Graphics g) {
if(g instanceof Graphics2D) {
Graphics2D graphics = (Graphics2D) g;
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//Draw button background
graphics.setColor(getBackground());
graphics.fillRoundRect(getX(), getY(), getWidth() - 1, getHeight() - 1, arcRadius, arcRadius);
}
}
@Override
public boolean contains(int x, int y) {
return new RoundRectangle2D.Double(getX(), getY(), getWidth(), getHeight(), arcRadius, arcRadius).contains(x,y);
}
public int getArcRadius() {
return arcRadius;
}
public void setArcRadius(int arcRadius) {
this.arcRadius = arcRadius;
this.repaint();
}
}
当我创建一个简单的框架并将一个按钮添加到面板时,我将其添加到框架中,它完美地显示出来。但是一旦我想创建两个按钮并将它们设置在彼此下方(使用 Borderlayout 我使用 NORTH 和 SOUTH),只有上面的按钮显示正确。下面的按钮正确显示了文本(我从 painComponent(...) 方法中删除了该部分),但没有绘制背景。我不以任何方式使用 setOpaque(...) 方法。
可能是什么问题?
我需要设置自定义按钮的边界吗?
编辑: 下面是创建框架和显示按钮的代码:
public static void main(String[] args) {
JFrame frame = new JFrame("Buttontest");
frame.setSize(new Dimension(500, 500));
frame.setLayout(new BorderLayout());
JPanel contentPanel = new JPanel();
contentPanel.setSize(new Dimension(500, 500));
contentPanel.setLayout(new GridLayout(2, 1, 0, 20));
JRoundedButton button1 = new JRoundedButton("Rounded Button", 40);
button1.setForeground(Color.YELLOW);
button1.setBackground(Color.GREEN);
JRoundedButton button2 = new JRoundedButton("Rounded Button 2", 40);
button2.setBackground(Color.BLACK);
button2.setForeground(Color.WHITE);
contentPanel.add(button1);
contentPanel.add(button2);
frame.add(contentPanel, BorderLayout.CENTER);
frame.setVisible(true);
}
输出是这样的:
为什么下方按钮的背景不可见?应该是黑色的!
在您的 paintComponent()
中,您需要 fillRoundRect(0,0,...)
而不是 getX()
和 getY()
因为g是相对于组件本身的。