最近又开始学习Java的Swing,感觉在某些方面,对于控件的简单重绘方面,比VC++、C#等微软的要简单一些。学习到给控件绘制一个带圆角的边框时,看到有一个帖子询问如何绘制只有一个圆角的矩形。在Java的API里,我没有找到可以实现该要求的方法,有人提出用drawline的方式,但是感觉过于笨拙,而且无法真正实现圆角,我也就没有深入研究。
没想到最近正好遇到一个需要绘制只有一个圆角的矩形边框的问题,仔细分析了一下网上的一些范例,发现绘制只有一个圆角的矩形边框还是很简单的。
package com.test.myLineBorder;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.border.LineBorder;
public class MyLineBorder extends LineBorder{
public MyLineBorder(Color color, int thickness, boolean roundedCorners) {
super(color, thickness, roundedCorners);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Color oldColor = g.getColor();
Graphics2D g2 = (Graphics2D)g;
int i;
g2.setRenderingHints(rh);
g2.setColor(lineColor);
for(i = 0; i < thickness; i++) {
if(roundedCorners)
g2.drawRoundRect(x, y, width, height, 5, 5);
else
g2.drawRect(x, y, width, height);//实际中此循环语句需要修改
}
g2.setColor(oldColor);
}
}
这段代码是网上给的一段范例,其中paintBorder方法覆盖了LineBorder的同名方法。控件在绘制时,会自动调用paintBorder方法。
构造函数中thickness代表边框的线宽。在paintBorder中,循环对每个边框进行绘制,每次单独绘制一个线宽。
如果我能够把2个线宽的边框,分别进行绘制和拼接,不就可是绘制出只有一个圆角的矩形了么?
例如上图,黄色的区域是我们要进行绘制的控件。黑色是我们要绘制的圆角及两个边框,蓝色是另外两个边框,由于显示的区域只有(width+(2*线宽))x( height * ( 2 * 线宽))的范围, 最终呈现在面前的,就只有一个左下角是圆角的矩形边框。
代码修改思路。
在构造函数中,添加一个圆角方位的参数,和一个记录方位的私有变量ROUND_NUM。如果可以,可用一个类RoundCorner来描述该信息。
public MyLineBorder(Color color, int thickness, boolean roundedCorners,int roundNum) {
super(color, thickness, roundedCorners);
this.ROUND_NUM = roundNum
}
public class RoundCorner{
public final static int TOP_LEFT = 0;
public final static int BOTTOM_LEFT = 1;
public final static int TOP_RIGHT = 2;
public final static int BOTTOM_RIGHT = 3;
}
在遍历thickness时,通过设置合理的x,y偏移量,让圆角矩形和矩形错开,形成类似如图的样子。这样基本就大功告成了。
最后可以创建两个shape,计算相交的区域,并通过Graphics2D制定可见区域。这样圆角所露出来的地方就可以隐藏了。
当然,还有其他很多种类似的方法。我这里就算是抛砖引玉吧,同样,我这个也适用用绘制只有2个圆角,3个圆角的边框。唯一的缺点就是线宽越大的话,与紧邻的控件间距也会越大。