分类: Java
2017-05-11 19:49:56
有时候,需要创建一个特殊形状的panel。这个panel 的形状需要自己绘制,也可以使用现有的layout manager,但是可供现有的layout manager管理的面积会发生变化,这个需要通过getInsets通知layout manager.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.RenderingHints;
import javax.swing.JPanel;
/**
* This class represents a Rounded Border JPanel.
*/
public class ArrowPanel extends JPanel {
private static final long serialVersionUID = 1L;
//笔画的粗细
/** 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;
//阴影和边界的距离。
/** Distance between border of shadow and border of opaque panel */
protected int shadowGap = 4;
//阴影的偏移量。
/** The offset of shadow. */
protected int shadowOffset = 3;
/** The transparency value of shadow. ( 0 - 255) */
protected int shadowAlpha = 150;
//这里设定箭头的五个顶点。
//x,y坐标
// Points of the Polygon.
protected int xArrowPoints[]={0,0,0,0,0};
protected int yArrowPoints[]={0,0,0,0,0};
public ArrowPanel() {
super();
setOpaque(false);
}
// 更改Layout Manager的insets的大小,这个很重要,可以通知layout manager 该箭头形状的
//panel的到底那些部分可以用于绘图和布局子组件。
// New size of insets for the layout manager.
@Override
public Insets getInsets() {
Insets insets = (Insets) super.getInsets().clone();
// Return new insets.
insets.top += strokeSize;
insets.left += strokeSize;
insets.bottom += strokeSize + shadowGap;
insets.right += strokeSize + shadowGap + getHeight() /2;
return insets;
}
// 绘制这个特殊的panel
// Paint the panel.
@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);
//计算阴影的形状。
calcArrowPoints(shadowOffset,shadowOffset,
width - strokeSize - shadowOffset,
height - strokeSize - shadowOffset);
graphics.fillPolygon(xArrowPoints, yArrowPoints, 5);
} else {
shadowGap = 1;
}
//绘制透明图层。
//Draws the arrow opaque panel with borders.
// fill the arrow.
graphics.setColor(getBackground());
calcArrowPoints(0,0,
width - shadowGap,
height - shadowGap);
graphics.fillPolygon(xArrowPoints, yArrowPoints, 5);
// 绘制这个panel本身。
//Draw the arrow panel border.
graphics.setColor(getForeground());
graphics.setStroke(new BasicStroke(strokeSize));
calcArrowPoints(0,0,
width - shadowGap,
height - shadowGap);
graphics.drawPolygon(xArrowPoints, yArrowPoints, 5);
//Sets strokes to default, is better.
graphics.setStroke(new BasicStroke());
}
/**
* Check if component has High Quality enabled.
*
* @return TRUE if it is HQ ; FALSE Otherwise
*/
public boolean isHighQuality() {
return highQuality;
}
/**
* Sets whether this component has High Quality or not
*
* @param highQuality if TRUE, set this component to HQ
*/
public void setHighQuality(boolean highQuality) {
this.highQuality = highQuality;
}
/**
* Returns the Color of shadow.
*
* @return a Color object.
*/
public Color getShadowColor() {
return shadowColor;
}
/**
* Sets the Color of shadow
*
* @param shadowColor Color of shadow
*/
public void setShadowColor(Color shadowColor) {
this.shadowColor = shadowColor;
}
/**
* Check if component drops shadow.
*
* @return TRUE if it drops shadow ; FALSE Otherwise
*/
public boolean isShady() {
return shady;
}
/**
* Sets whether this component drops shadow
*
* @param shady if TRUE, it draws shadow
*/
public void setShady(boolean shady) {
this.shady = shady;
}
/**
* Returns the size of strokes.
*
* @return the value of size.
*/
public float getStrokeSize() {
return strokeSize;
}
/**
* Sets the stroke size value.
*
* @param strokeSize stroke size value
*/
public void setStrokeSize(int strokeSize) {
this.strokeSize = strokeSize;
}
/**
* Get the value of shadowOffset
*
* @return the value of shadowOffset
*/
public int getShadowOffset() {
return shadowOffset;
}
/**
* Set the value of shadowOffset
*
* @param shadowOffset new value of shadowOffset
*/
public void setShadowOffset(int shadowOffset) {
if (shadowOffset >= 1) {
this.shadowOffset = shadowOffset;
} else {
this.shadowOffset = 1;
}
}
/**
* Get the value of shadowGap
*
* @return the value of shadowGap
*/
public int getShadowGap() {
return shadowGap;
}
/**
* Set the value of shadowGap
*
* @param shadowGap new value of shadowGap
*/
public void setShadowGap(int shadowGap) {
if (shadowGap >= 1) {
this.shadowGap = shadowGap;
} else {
this.shadowGap = 1;
}
}
/**
* Get the value of shadowAlpha
*
* @return the value of shadowAlpha
*/
public int getShadowAlpha() {
return shadowAlpha;
}
/**
* Set the value of shadowAlpha
*
* @param shadowAlpha new value of shadowAlpha
*/
public void setShadowAlpha(int shadowAlpha) {
if (shadowAlpha >= 0 && shadowAlpha <= 255) {
this.shadowAlpha = shadowAlpha;
} else {
this.shadowAlpha = 255;
}
}
//计算箭头形状的五个顶点。
/**
* Calculate the value of Arrow points.
*
* @param iStartX: start X of Arrow points.
* iStartY: start Y of Arrow points.
* iWidth: width of Arrow.
* iHeight: height of Arrow.
*
*/
public void calcArrowPoints(int iStartX, int iStartY, int iWidth, int iHeight) {
// Point 0;
xArrowPoints[0] = iStartX;
yArrowPoints[0] = iStartY;
// Point 1;
xArrowPoints[1] = iStartX+iWidth-iHeight/2;
yArrowPoints[1] = iStartY;
// Point 2;
xArrowPoints[2] = iStartX+iWidth;
yArrowPoints[2] = iStartY+iHeight/2;
// Point 3;
xArrowPoints[3] = iStartX+iWidth-iHeight/2;
yArrowPoints[3] = iStartY+iHeight;
// Point 4;
xArrowPoints[4] = iStartX;
yArrowPoints[4] = iStartY+iHeight;
}
}