在Java的Swing框架中,经常需要创建具有特定外观和行为的自定义组件。本文将介绍如何通过扩展JPanel来创建一个具有圆角和可选阴影效果的自定义组件,名为RoundedPanel。这个组件可以被添加到Swing容器中,并且可以通过重写paintComponent方法来实现自定义的绘制逻辑。
RoundedPanel是一个扩展自JPanel的类,它提供了一些属性来改善图形表现,例如圆角的大小、阴影的颜色和透明度等。通过重写paintComponent方法,可以在这个组件上绘制任何需要的图形,从而重新创建所有基本的Swing组件,如按钮、标签、面板等,并且可以添加相对的事件处理。
以下是一个简单的RoundedPanel类实现,它包含了一些用于改进外观的属性(属性描述见内联注释):
public class RoundedPanel extends JPanel {
// 笔触大小,建议设置为1以获得更好的视觉效果
protected int strokeSize = 1;
// 阴影颜色
protected Color shadowColor = Color.black;
// 是否显示阴影
protected boolean shady = true;
// 是否启用高质量视图
protected boolean highQuality = true;
// 圆角的横向和纵向半径
protected Dimension arcs = new Dimension(20, 20);
// 阴影边界与不透明面板边界之间的距离
protected int shadowGap = 5;
// 阴影的偏移量
protected int shadowOffset = 4;
// 阴影的透明度值(0 - 255)
protected int shadowAlpha = 150;
// 构造函数
public RoundedPanel() {
super();
setOpaque(false);
}
// 重写paintComponent方法
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
int shadowGap = this.shadowGap;
Color shadowColorA = new Color(shadowColor.getRed(),
shadowColor.getGreen(), shadowColor.getBlue(), shadowAlpha);
Graphics2D graphics = (Graphics2D) g;
// 如果启用高质量视图,则设置抗锯齿
if (highQuality) {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
// 如果启用阴影,则绘制阴影边界
if (shady) {
graphics.setColor(shadowColorA);
graphics.fillRoundRect(
shadowOffset, shadowOffset, width - strokeSize - shadowOffset,
height - strokeSize - shadowOffset, arcs.width, arcs.height);
} else {
shadowGap = 1;
}
// 绘制圆角不透明面板及其边框
graphics.setColor(getBackground());
graphics.fillRoundRect(0, 0, width - shadowGap, height - shadowGap,
arcs.width, arcs.height);
graphics.setColor(getForeground());
graphics.setStroke(new BasicStroke(strokeSize));
graphics.drawRoundRect(0, 0, width - shadowGap, height - shadowGap,
arcs.width, arcs.height);
// 重置笔触到默认值
graphics.setStroke(new BasicStroke());
}
}
在上述代码中,创建了一个简单的类,它继承自JPanel。它有一些属性用于改进外观(见属性描述)。注意,如果想在可视化GUI编辑器中直接使用这个类,比如集成的Netbeans编辑器,必须写一个无参构造函数,因为编辑器不能直接知道组件的构造函数参数。
RoundedPanel组件可以像其他Swing组件一样被添加到容器中。以下是如何在Swing应用程序中使用RoundedPanel组件的示例:
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame {
public MainFrame() {
setTitle("RoundedPanel Example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 300);
setLocationRelativeTo(null);
RoundedPanel panel = new RoundedPanel();
panel.setArcs(new Dimension(20, 20));
panel.setBackground(Color.BLUE);
panel.setForeground(Color.WHITE);
panel.setOpaque(true);
JButton button = new JButton("Click Me!");
button.setBackground(Color.GREEN);
button.setForeground(Color.WHITE);
panel.add(button);
add(panel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MainFrame frame = new MainFrame();
frame.setVisible(true);
});
}
}
在这个示例中,创建了一个名为MainFrame的JFrame,并添加了一个RoundedPanel组件。设置了RoundedPanel的圆角大小、背景颜色和前景颜色,并添加了一个按钮。