⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractfiguare.java

📁 一个简易的java画图软件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 + -