📄 abstractfiguare.java
字号:
package draw.figuare;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Vector;
/**
* 所有图形的基类<br/> 提供了图形的大多数操作,如绘制,移动,克隆,序列化等。
*
* @author Thihy
*
*/
public abstract class AbstractFiguare implements Serializable, Cloneable {
protected static final long serialVersionUID = 215121613548646121L;
// 一些常量
public static final int DRAG_RECT_SIZE = 3;// 八个方向的小方块的大小
public static final Color DRAG_RECT_COLOR = Color.blue;// 八个方向的小方块的颜色
public static final Color ROTATE_RECT_COLOR = Color.green;// 旋转方块的颜色
public static final Color LINECHANGE_RECT_COLOR = Color.cyan;// 控制线宽和虚线间距的方块的颜色
public static final Color ARCCHANGE_RECT_COLOR = Color.orange;// 控制圆角矩形的圆角大小的方块的颜色
public static final Color PRESELECT_RECT_COLOR = Color.yellow;// 预选时的颜色
public static final Color SELECT_RECT_COLOR = Color.darkGray;// 选择时的颜色
protected Shape figuare;
public static int figuareNum = 0;
public String serialId;// 唯一id
protected boolean selected;// 当前是否选择
protected Color strokeColor, fillColor;
/**
* 左上角坐标和右下角坐标
*/
public double x1, y1, x2, y2;
transient protected double tx1, ty1, tx2, ty2;// 暂存之前的值
protected double mx, my;// 移动时的拖动点
protected boolean perm;// 是否绘制完成
protected String name;
protected boolean isChanged;
protected double rx, ry;// 中心旋转点
protected boolean isRotating;// 正在旋转
protected double rtTheta;// =Math.PI/2;
protected double shXTheta, shYTheta;// 切变的角度
transient protected double tshXTheta, tshYTheta;
protected double transX, transY;// 切变后的偏移量
transient protected double ttransX, ttransY;
protected double scaleX, scaleY;
protected double lineStyle, lineWidth;
protected final Insets offset = new Insets(0, 2, 0, 5);// 字与边框之间的空隙。
/**
* 线宽和虚线间距的最大值
*/
public static final double LINE_MAX_WIDTH = 100.0, LINE_MAX_STYLE = 100.0;
protected final static Color DEFAULT_COLOR = Color.black;
/**
* 默认初始化
*/
public AbstractFiguare() {
this(0.0, 0.0, null, null, null);
}
/**
* 初始化
*
* @param x
* 起始点的横坐标
* @param y
* 起始点的纵坐标
* @param strokeColor
* 显示颜色,null则无色
* @param fillColor
* 填充颜色,null则无色
* @param name
* 名称
*/
public AbstractFiguare(double x, double y, Color strokeColor,
Color fillColor, String name) {
this.serialId = ((Integer) (++figuareNum)).toString();
this.strokeColor = strokeColor;
this.fillColor = fillColor;
this.x1 = this.x2 = x;
this.y1 = this.y2 = y;
this.rtTheta = 0;
this.shXTheta = this.shYTheta = 0;
this.transX = this.transY = 0;
this.scaleX = this.scaleY = 1.0;
this.mx = x;
this.my = y;
this.name = name;
this.selected = false;
this.isDragging = false;
this.dragStyle = -1;
this.lineStyle = 0.0;
this.lineWidth = 2.0;
this.isChanged = false;
}
/**
* 设置id,这个id在网络通信是必须唯一指定
*
* @param newId
*/
public void setSerialId(String newId) {
serialId = newId;
}
/**
* 克隆
*/
@Override
public Object clone() {
Object a = null;
try {
a = super.clone();
} catch (CloneNotSupportedException e) {
}
((AbstractFiguare) a).selected = false;
((AbstractFiguare) a).figuare = (Shape) getFiguareClone();
return a;
}
protected abstract Object getFiguareClone();
/**
* 本图形是否改变
*
* @return 如果改变则返回真
*/
public boolean isChanged() {
return isChanged;
}
/**
* 置当前图形为改变状态
*/
public void hasChanged() {
isChanged = true;
}
/**
* 已经通过网络传输,则将已经改变标记置位假
*/
public void hasUpdatedNet() {
isChanged = false;
}
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException {
try {
in.defaultReadObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取类型:圆角矩形,直线等
*
* @return 类型
*/
public abstract int getID();
/**
* 在指定的Graphics2D上画出这个图形
*
* @param g
* 指定的Graphics2D
*/
public void draw(Graphics2D g) {
Color saveColor = g.getColor();
AffineTransform saveAt = g.getTransform();
if (getID() != STRAIGHT_LINE) {
g.rotate(rtTheta, rx, ry);
g.shear(Math.tan(shXTheta), Math.tan(shYTheta));
g.translate(-Math.max(y1, y2) * Math.tan(shXTheta), 0);
}
updateFiguare();
if (isFilled() && getID() != STRAIGHT_LINE) {
g.setColor(fillColor);
g.fill(figuare);
}
if (strokeColor != null) {
g.setColor(strokeColor);
Stroke saveStroke = g.getStroke();
int cap = BasicStroke.CAP_ROUND;
if (getID() == RECTANGEL)
cap = BasicStroke.CAP_SQUARE;
Stroke stroke = new BasicStroke((float) lineWidth, cap,
BasicStroke.JOIN_MITER, 10.0f, new float[] {
(float) (Math.max(2.0, lineStyle)),
(float) lineStyle }, 0.0f);
g.setStroke(stroke);
g.draw(figuare);
g.setStroke(saveStroke);
}
g.setColor(saveColor);
g.setTransform(saveAt);
}
/**
* 从起始点画到指定点
*/
public void drawTo(int x, int y) {
this.x2 = x;
this.y2 = y;
updateFiguare();
}
/**
* 移动到指定点
*/
public void moveTo(double x, double y) {
Point2D p = getPointBeforeRotate(x, y);
Point2D mp = getPointBeforeRotate(mx, my);
double dx = p.getX() - mp.getX(), dy = p.getY() - mp.getY();
x1 = tx1 + dx;
y1 = ty1 + dy;
x2 = tx2 + dx;
y2 = ty2 + dy;
isChanged = true;
updateFiguare();
}
/**
* 如果指定点在图形之中,则返回真
*/
public boolean contains(double x, double y) {
Point2D p = getPointBeforeTransform(x, y);
boolean returnValue = getExtraBounds().contains(p);
return returnValue;
}
/**
* 更新图形
*/
public abstract void updateFiguare();
/**
* 获取图形的名称
*
* @return 图形的名称
*/
public String getName() {
return name;
}
public void makePermanent() {
perm = true;
isChanged = true;
if (x1 > x2) {
double t = x1;
x1 = x2;
x2 = t;
}
if (y1 > y2) {
double t = y1;
y1 = y2;
y2 = t;
}
updateFiguare();
}
/**
* 判断已经绘成
*
* @return 如果已经绘成返回真
*/
public boolean isPermanent() {
return perm;
}
/**
* 置选择状态
*
* @param selectIt
* 新的选择状态
*/
public void setSelect(boolean selectIt) {
selected = selectIt;
}
/**
* 判断选择
*
* @return 如果选择返回真
*/
public boolean isSelect() {
return selected;
}
protected boolean isFilled() {
return fillColor != null;
}
protected void setBounds(Rectangle2D rect) {
setBounds(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
protected void setBounds(Rectangle2D.Double rect) {
setBounds(rect.x, rect.y, rect.width, rect.height);
}
protected void setBounds(double x, double y, double width, double height) {
this.x1 = width > 0 ? x : x + width + 1;
this.y1 = height > 0 ? y : y + height + 1;
this.x2 = width > 0 ? x + width + 1 : x;
this.y2 = height > 0 ? y + height + 1 : y;
updateFiguare();
isChanged = true;
}
protected Rectangle2D getExtraBounds() {
Rectangle2D.Double rect = (Rectangle2D.Double) getBounds();
return new Rectangle2D.Double(rect.getX() - lineWidth / 2, rect.getY()
- lineWidth / 2, rect.getWidth() + lineWidth, rect.getHeight()
+ lineWidth);
}
/**
* 重写equals 更具serialID进行判断
*/
@Override
public boolean equals(Object obj) {
return (obj == null) ? false : serialId
.equals(((AbstractFiguare) obj).serialId);
}
/**
* 获取图形边界范围
*
* @return 图形边界范围
*/
public Rectangle2D getBounds() {
Rectangle2D.Double rect = new Rectangle2D.Double();
rect.x = x1 < x2 ? x1 : x2;
rect.y = y1 < y2 ? y1 : y2;
rect.width = Math.abs(x1 - x2) + 1;
rect.height = Math.abs(y1 - y2) + 1;
return rect;
}
/**
* 获取线条颜色
*
* @return 线条颜色
*/
public Color getStrokeColor() {
return strokeColor;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -