圆角边框 JPanel(JPanel 图形改进)
具有圆角边框、阴影和抗锯齿的可重用 JPanel 扩展
引言
Swing 框架的可扩展性允许我们创建非常高级的图形组件,以便更好地查看我们的JFrame,比直接管理外观和感觉更简单。
基本上,一个JComponent
是一个可以添加到 Swing 容器中的空边界框。
它可以通过一个简单的普通类扩展,并重写paintComponent
方法,我们可以在边界框中绘制所需的一切。通过这种方式,我们可以重新创建所有基本的 Swing 组件,如按钮、标签、面板……以及相关的事件。
Using the Code
在本例中,我们将回顾一个JPanel
扩展(而不是JComponent
扩展),因为我们想要创建一个Container
组件(像JPanel
!),但有一些图形改进。
public class RoundedPanel extends JPanel {
/** Stroke size. it is recommended to set it to 1 for better view */
protected int strokeSize = 1;
/** Color of shadow */
protected Color shadowColor = Color.black;
/** Sets if it drops shadow */
protected boolean shady = true;
/** Sets if it has an High Quality view */
protected boolean highQuality = true;
/** Double values for Horizontal and Vertical radius of corner arcs */
protected Dimension arcs = new Dimension(20, 20);
/** Distance between shadow border and opaque panel border */
protected int shadowGap = 5;
/** The offset of shadow. */
protected int shadowOffset = 4;
/** The transparency value of shadow. ( 0 - 255) */
protected int shadowAlpha = 150;
//FOLLOWING CODES GOES HERE
}
我们创建了一个扩展 JPanel 的简单类。它具有一些用于改进的属性(有关属性说明,请参见内联注释)。
注意!!如果要直接在可视化 GUI 编辑器(例如集成 Netbeans 编辑器)中使用此类,则必须编写一个void
构造函数,因为编辑器无法直接知道我们组件的构造函数参数。
public RoundedPanel() {
super();
setOpaque(false);
}
我们调用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;
//Sets antialiasing if HQ.
if (highQuality) {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
//Draws shadow borders if any.
if (shady) {
graphics.setColor(shadowColorA);
graphics.fillRoundRect(
shadowOffset,// X position
shadowOffset,// Y position
width - strokeSize - shadowOffset, // width
height - strokeSize - shadowOffset, // height
arcs.width, arcs.height);// arc Dimension
} else {
shadowGap = 1;
}
//Draws the rounded opaque panel with borders.
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);
//Sets strokes to default, is better.
graphics.setStroke(new BasicStroke());
}
该方法有五个宏观部分。标题部分调用超级重写方法并声明主要变量:(width
、height
)是组件的当前大小;shadowGap
是同名属性的重写,稍后我们将看到原因;shadowColor
是添加了透明度的颜色属性;graphics
是由方法参数传递的Graphics
对象,表示我们可以在其上绘画的画布(Graphics2D
转换更强大,请参见抗锯齿)。
下一部分检查highQuality
是否为true
,因此为之后绘制的所有形状启用画布上的抗锯齿。
类似地,shady确定组件是否绘制阴影。阴影是一个简单的roundRect
,通常是黑色,其左上和右下角由shadowOffset
值参数化。
在可能的阴影之上,组件绘制具有细边的不透明面板。这里右上和右下位置由shadowGap
参数化。
图形上,图层的顺序 1) -> 2) -> 3) 必须是这样的,因为存在重叠。

页脚部分用于重置我们已扭曲的参数。实际上,如果我们不重置笔触,则添加到此面板的下一个组件将具有扭曲的边框。
结论
通过这简单的几行代码,我们创建了一个外观类似这样的可靠的可再分发 Swing 组件。
我们可以在这里看到三个RoundedPanel
:紫色、绿色和蓝色,每个都有不同的圆角尺寸,决定角的曲率。像蓝色面板一样,最佳尺寸是 [10,10],因为过度的曲线(如紫色)可能会切掉上方的内部组件(尝试设置 [80,80]..)。