📄 rectangularfiguare.java
字号:
package draw.figuare;
import java.awt.*;
import java.awt.geom.*;
import draw.Cursors;
/**
* 所有类矩形图形的基类
*
* @author Thihy
*
*/
public abstract class RectangularFiguare extends AbstractFiguare {
protected boolean isSquare;// 长等于宽
public RectangularFiguare() {
this(0.0, 0.0, null, null, null);
}
public RectangularFiguare(double x, double y, Color lineColor,
Color fillColor, String text) {
super(x, y, lineColor, fillColor, text);
this.isSquare = false;
}
@Override
public void drawTo(int x, int y) {
super.drawTo(x, y);
if (isSquare) {
double width = Math.abs(x - x1) + 1;
double height = Math.abs(y - y1) + 1;
width = height = Math.min(width, height);
x2 = x < x1 ? x1 - width + 1 : x1 + width - 1;
y2 = y < y1 ? y1 - height + 1 : y1 + height - 1;
}
updateFiguare();
}
public void setSquare(boolean isSquare) {
this.isSquare = isSquare;
}
public boolean isSquare() {
return this.isSquare;
}
@Override
public Rectangle2D getBounds() {
Rectangle2D.Double rect = (Rectangle2D.Double) super.getBounds();
if (isSquare) {
rect.width = rect.height = Math.min(rect.width, rect.height);
}
Rectangle2D.Double returnRect = (Rectangle2D.Double) rect.clone();// 这个是必须的
return returnRect;
}
@Override
public boolean contains(double x, double y) {
Point2D p = getPointBeforeTransform(x, y);
RectangularShape tempFiguare = (RectangularShape) ((RectangularShape) figuare)
.clone();
tempFiguare.setFrame(getExtraBounds());
boolean returnValue = tempFiguare.contains(p);
return returnValue;
}
@Override
public void preSelect(Graphics2D g) {
if (isSelect())
return;
AffineTransform saveAt = g.getTransform();
Color saveColor = g.getColor();
g.rotate(rtTheta, rx, ry);
g.shear(Math.tan(shXTheta), Math.tan(shYTheta));
g.translate(-Math.max(y1, y2) * Math.tan(shXTheta), 0);
RectangularShape tempFiguare = (RectangularShape) ((RectangularShape) figuare)
.clone();
// 画出选择框
Rectangle2D extraRect = getExtraBounds();
tempFiguare.setFrame(extraRect);
Stroke saveStroke = g.getStroke();
g.setColor(PRESELECT_RECT_COLOR);
g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_MITER, 10.0f, new float[] { 1f, 0.0f }, 0.0f));
g.draw(tempFiguare);
g.setStroke(saveStroke);
g.setColor(saveColor);
g.setTransform(saveAt);
}
@Override
public void select(Graphics2D g) {
if (!isSelect())
return;
AffineTransform saveAt = g.getTransform();
Color saveColor = g.getColor();
g.rotate(rtTheta, rx, ry);
g.shear(Math.tan(shXTheta), Math.tan(shYTheta));
g.translate(-Math.max(y1, y2) * Math.tan(shXTheta), 0);
// 画出选择框
Rectangle2D rect = getBounds();
Stroke saveStroke = g.getStroke();
g.setColor(SELECT_RECT_COLOR);
g
.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
BasicStroke.JOIN_MITER, 10.0f,
new float[] { 5.0f, 5.0f }, 0.0f));
int x = (int) rect.getX(), y = (int) rect.getY(), width = (int) rect
.getWidth(), height = (int) rect.getHeight();
g.drawRect(x, y, width, height);
g.setStroke(saveStroke);
g.setColor(saveColor);
g.setTransform(saveAt);
dRects.clear();
Rectangle2D.Double dRect;
for (int i = 0; i <= 14; ++i) {
dRect = new Rectangle2D.Double();
dRects.add(dRect);
}
// 边框变化
g.setColor(LINECHANGE_RECT_COLOR);
double px1 = x, py1 = y, px2 = x + width - 1, py2 = y + height - 1;
Point2D lwPoint = getPointAfterTransform(px2 + 8, py1 + 12);
double lwX = lwPoint.getX(), lwY = lwPoint.getY();
// 线宽
int[] xPoints = { (int) (lwX + lineWidth / 2),
(int) (lwX - 4 + lineWidth / 2), (int) (lwX + lineWidth / 2),
(int) (lwX + 4 + lineWidth / 2) };
int[] yPoints = { (int) (lwY + 4), (int) (lwY), (int) (lwY - 4),
(int) (lwY) };
Polygon aRect = new Polygon(xPoints, yPoints, 4);
dRects.setElementAt(aRect, LINE_WIDTH_CHANGE);
g.fill(aRect);
Point2D lsPoint = getPointAfterTransform(px2 - 2 * lineStyle, py1 - 8);
double lsX = lsPoint.getX(), lsY = lsPoint.getY();
// 线间间距
xPoints = new int[] { (int) (lsX - 4), (int) (lsX), (int) (lsX + 4),
(int) (lsX) };
yPoints = new int[] { (int) (lsY), (int) (lsY - 4), (int) (lsY),
(int) (lsY + 4) };
aRect = new Polygon(xPoints, yPoints, 4);
dRects.setElementAt(aRect, LINE_STYLE_CHANGE);
g.fill(aRect);
// 四个切变边界
((Rectangle2D.Double) dRects.elementAt(N_SHEAR_BORDER)).setFrame(x,
y - 5, width, 10);
((Rectangle2D.Double) dRects.elementAt(E_SHEAR_BORDER)).setFrame(x
+ width - 1 - 5, y, 10, height);
((Rectangle2D.Double) dRects.elementAt(S_SHEAR_BORDER)).setFrame(x, y
+ height - 1 - 5, width, 10);
((Rectangle2D.Double) dRects.elementAt(W_SHEAR_BORDER)).setFrame(x - 5,
y, 10, width);
g.setColor(DRAG_RECT_COLOR);
Point2D point1 = getPointAfterTransform(px1, py1);// 左上
Point2D point2 = getPointAfterTransform(px1, py2);// 左下
Point2D point3 = getPointAfterTransform(px2, py2);// 右下
Point2D point4 = getPointAfterTransform(px2, py1);// 右上
int dx1 = (int) point1.getX(), dy1 = (int) point1.getY();// 左上
int dx2 = (int) point2.getX(), dy2 = (int) point2.getY();// 左下
int dx3 = (int) point3.getX(), dy3 = (int) point3.getY();// 右下
int dx4 = (int) point4.getX(), dy4 = (int) point4.getY();// 右上
int dx5 = (dx1 + dx4) / 2, dy5 = (dy1 + dy4) / 2; // 上
int dx6 = (dx2 + dx3) / 2, dy6 = (dy2 + dy3) / 2; // 下
int dx7 = (dx1 + dx2) / 2, dy7 = (dy1 + dy2) / 2; // 左
int dx8 = (dx3 + dx4) / 2, dy8 = (dy3 + dy4) / 2; // 右
int size = DRAG_RECT_SIZE;
// 四角
((Rectangle2D.Double) dRects.elementAt(NORTH_WEST)).setFrame(
dx1 - size, dy1 - size, 2 * size, 2 * size);// 西北
((Rectangle2D.Double) dRects.elementAt(NORTH_EAST)).setFrame(
dx4 - size, dy4 - size, 2 * size, 2 * size);// 东北
((Rectangle2D.Double) dRects.elementAt(SOUTH_WEST)).setFrame(
dx2 - size, dy2 - size, 2 * size, 2 * size);// 西南
((Rectangle2D.Double) dRects.elementAt(SOUTH_EAST)).setFrame(
dx3 - size, dy3 - size, 2 * size, 2 * size);// 东南
// 四边
((Rectangle2D.Double) dRects.elementAt(NORTH)).setFrame(dx5 - size, dy5
- size, 2 * size, 2 * size);// 北
((Rectangle2D.Double) dRects.elementAt(SOUTH)).setFrame(dx6 - size, dy6
- size, 2 * size, 2 * size);// 西
((Rectangle2D.Double) dRects.elementAt(WEST)).setFrame(dx7 - size, dy7
- size, 2 * size, 2 * size);// 东
((Rectangle2D.Double) dRects.elementAt(EAST)).setFrame(dx8 - size, dy8
- size, 2 * size, 2 * size);// 南
for (int i = 2; i < 10; ++i) {
g.fill(dRects.elementAt(i));
}
// 旋转
g.setColor(ROTATE_RECT_COLOR);
Point2D rotatePoint = getPointAfterTransform(x + width / 2, y - 15);
Ellipse2D.Double rRect = new Ellipse2D.Double();
rRect.setFrame(rotatePoint.getX() - size, rotatePoint.getY() - size, 6,
6);
dRects.setElementAt(rRect, ROTATE);
g.fill(rRect);
g.setColor(saveColor);
g.setTransform(saveAt);
}
@Override
public Cursor getCursor(int Style) {
// 根据旋转调整光标
if (2 <= Style && Style <= 9) {
Style = (Style - 2 + (int) ((rtTheta) * 8 / Math.PI + 1) / 2) % 8 + 2;
}
switch (Style) {
case NORTH:
return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
case SOUTH:
return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
case EAST:
return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
case LINE_STYLE_CHANGE:
case LINE_WIDTH_CHANGE:
case WEST:
return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
case NORTH_EAST:
return Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
case NORTH_WEST:
return Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
case SOUTH_EAST:
return Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
case SOUTH_WEST:
return Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
case ROTATE:
return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
default:
break;
}
// 根据切变调整光标
int cursorStyle = ((int) (rtTheta * 8 / Math.PI + 1) % 8) / 2;
switch (cursorStyle) {
case 0:
return Cursors.getCursor(Cursors.N_SHEAR_CURSOR);
case 1:
return Cursors.getCursor(Cursors.NE_SHEAR_CURSOR);
case 2:
return Cursors.getCursor(Cursors.E_SHEAR_CURSOR);
case 3:
return Cursors.getCursor(Cursors.SE_SHEAR_CURSOR);
default:
return Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
}
}
/**
* 重写moveTo
*/
@Override
public void moveTo(double px, double py) {
isRotating = false;
if (isDragging) {
Point2D p = getPointBeforeTransform(px, py);
double x = p.getX();
double y = p.getY();
double dx = getPointBeforeRotate(px, py).getX()
- getPointBeforeRotate(mx, my).getX();
double height = Math.abs(y1 - y2) + 1;
double deltaX;
switch (dragStyle) {
case NORTH:
deltaX = (this.y1 - this.y2) * Math.tan(shXTheta);
if (this.y2 < this.y1) {
this.x1 = this.tx1 + deltaX;
this.x2 = this.tx2 + deltaX;
}
this.y1 = y;
break;
case SOUTH:
deltaX = (y - this.ty2) * Math.tan(shXTheta);
if (this.y2 > this.y1) {
this.x1 = this.tx1 + deltaX;
this.x2 = this.tx2 + deltaX;
}
this.y2 = y;
break;
case EAST:
this.x2 = x;
break;
case WEST:
this.x1 = x;
break;
case NORTH_EAST:
deltaX = (this.y1 - this.y2) * Math.tan(shXTheta);
if (this.y2 < this.y1) {
this.x1 = this.tx1 + deltaX;
}
this.x2 = x;
this.y1 = y;
break;
case NORTH_WEST:
deltaX = (this.y1 - this.y2) * Math.tan(shXTheta);
if (this.y2 < this.y1) {
this.x2 = this.tx2 + deltaX;
}
this.x1 = x;
this.y1 = y;
break;
case SOUTH_EAST:
deltaX = (y - this.ty2) * Math.tan(shXTheta);
if (this.y2 > this.y1) {
this.x1 = this.tx1 + deltaX;
}
this.x2 = x;
this.y2 = y;
break;
case SOUTH_WEST:
deltaX = (y - this.ty2) * Math.tan(shXTheta);
if (this.y2 > this.y1) {
this.x2 = this.tx2 + deltaX;
}
this.x1 = x;
this.y2 = y;
break;
case ROTATE:
isRotating = true;
double trX = (x1 + x2) / 2,
trY = (y1 + y2) / 2;
Point2D pr = getPointAfterShear(trX, trY);
rx = pr.getX();
ry = pr.getY();
rtTheta = Math.PI / 2
+ Math.atan2(py - pr.getY(), px - pr.getX()) + shXTheta;
break;
case LINE_STYLE_CHANGE:
if (x <= x2) {
lineStyle = (x2 - x) / 2;
if (lineStyle > LINE_MAX_STYLE) {
lineStyle = LINE_MAX_STYLE;
}
}
break;
case LINE_WIDTH_CHANGE:
if (x >= x2 + 4) {
lineWidth = (x - x2 - 4) * 2;
if (lineWidth > LINE_MAX_WIDTH) {
lineWidth = LINE_MAX_WIDTH;
}
}
break;
case N_SHEAR_BORDER:
shXTheta = Math.atan(Math.tan(tshXTheta) - dx / height);
break;
default:
break;
}
} else {
super.moveTo(px, py);
}
isChanged = true;
updateFiguare();
}
@Override
public abstract void deselect();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -