完成矩形的八个点操作操作和移动矩形操作
This commit is contained in:
parent
04ab07d87a
commit
f0cc080a5e
|
@ -1,9 +1,9 @@
|
|||
package org.rococy.roomit.control;
|
||||
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.scene.Cursor;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.rococy.roomit.enums.RectangleCtrl;
|
||||
|
||||
/**
|
||||
* 能改变尺寸的矩形
|
||||
|
@ -13,177 +13,147 @@ import javafx.scene.shape.Rectangle;
|
|||
*/
|
||||
public class ResizableRectangle extends Rectangle {
|
||||
|
||||
private double lastX, lastY;
|
||||
/**
|
||||
* 矩形原点
|
||||
*/
|
||||
private double originX, originY;
|
||||
|
||||
double dragStartX, dragStartY, dragOriginWidth, dragOriginHeight,
|
||||
newX = 0, newY = 0, newLayoutX = -1, newLayoutY = -1, width = 0, height = 0;
|
||||
/**
|
||||
* 记录调整完矩形后的大小
|
||||
*/
|
||||
private double width, height;
|
||||
|
||||
private String resizeType;
|
||||
/**
|
||||
* 当处于移动状态时,记录的xy值
|
||||
*/
|
||||
private double moveX, moveY;
|
||||
|
||||
/**
|
||||
* 矩形操作类型
|
||||
*/
|
||||
private RectangleCtrl rectangleCtrl;
|
||||
|
||||
public ResizableRectangle(double x, double y) {
|
||||
/**
|
||||
* 配置项
|
||||
*/
|
||||
private static final String COLOR = "#f00";
|
||||
private static final double BORDER_WIDTH = 3;
|
||||
|
||||
/**
|
||||
* @param originX 在整个屏幕内的x值
|
||||
* @param originY 在整个屏幕内的y值
|
||||
*/
|
||||
public ResizableRectangle(double originX, double originY) {
|
||||
// 记录原点
|
||||
this.originX = originX;
|
||||
this.originY = originY;
|
||||
|
||||
// 填充透明色,边框颜色,边框宽度
|
||||
this.setFill(Paint.valueOf("#00000000"));
|
||||
this.setStroke(Paint.valueOf("#f00"));
|
||||
this.setStrokeWidth(3);
|
||||
this.setStroke(Paint.valueOf(COLOR));
|
||||
this.setStrokeWidth(BORDER_WIDTH);
|
||||
|
||||
this.setCache(false);
|
||||
|
||||
|
||||
this.widthProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
width = newValue.doubleValue();
|
||||
});
|
||||
this.heightProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
height = newValue.doubleValue();
|
||||
});
|
||||
this.xProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
newX = newValue.doubleValue();
|
||||
});
|
||||
this.yProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
newY = newValue.doubleValue();
|
||||
});
|
||||
this.layoutXProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
newLayoutX = newValue.doubleValue();
|
||||
});
|
||||
this.layoutYProperty().addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
|
||||
newLayoutY = newValue.doubleValue();
|
||||
});
|
||||
|
||||
this.initScaleEvents();
|
||||
// 初始化调整大小事件
|
||||
this.initEvents();
|
||||
}
|
||||
|
||||
public void initScaleEvents() {
|
||||
|
||||
/**
|
||||
* 初始化矩形调整大小事件
|
||||
*/
|
||||
public void initEvents() {
|
||||
bindMousePressedEvent();
|
||||
bindMouseMovedEvent();
|
||||
bindMouseDraggedEvent();
|
||||
bindMouseReleasedEvent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标按下
|
||||
*/
|
||||
private void bindMousePressedEvent() {
|
||||
this.setOnMousePressed(e -> {
|
||||
dragOriginWidth = width;
|
||||
dragOriginHeight = height;
|
||||
width = this.getWidth();
|
||||
height = this.getHeight();
|
||||
|
||||
this.lastX = e.getScreenX();
|
||||
this.lastY = e.getScreenY();
|
||||
|
||||
System.out.println("startX: " + e.getScreenX() + ", startY: " + e.getScreenY());
|
||||
});
|
||||
|
||||
this.setOnMouseReleased(e -> {
|
||||
this.lastX = e.getScreenX();
|
||||
this.lastY = e.getScreenY();
|
||||
});
|
||||
|
||||
|
||||
this.setOnMouseDragged(e -> {
|
||||
// 防止快速操作
|
||||
if (resizeType == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
double endX = e.getScreenX() - lastX, endY = e.getScreenY() - lastY;
|
||||
|
||||
|
||||
switch (resizeType) {
|
||||
case "topLeft" -> {
|
||||
this.setLayoutX(e.getScreenX());
|
||||
this.setLayoutY(e.getScreenY());
|
||||
|
||||
this.setWidth(dragOriginWidth - endX);
|
||||
this.setHeight(dragOriginHeight - endY);
|
||||
|
||||
}
|
||||
|
||||
case "topMiddle" -> {
|
||||
if (endY > dragOriginHeight) {
|
||||
this.setY(dragOriginHeight);
|
||||
this.setHeight(endY - dragOriginHeight);
|
||||
} else {
|
||||
// 定义原点
|
||||
this.setY(endY);
|
||||
this.setHeight(dragOriginHeight - endY);
|
||||
}
|
||||
}
|
||||
|
||||
case "topRight" -> {
|
||||
// 定义原点
|
||||
this.setX(endX);
|
||||
this.setY(endY);
|
||||
|
||||
|
||||
this.setWidth(endX);
|
||||
this.setHeight(dragOriginHeight - endY);
|
||||
}
|
||||
|
||||
case "bottomRight" -> {
|
||||
}
|
||||
if (rectangleCtrl == RectangleCtrl.MOVE) {
|
||||
moveX = e.getScreenX() - this.getLayoutX();
|
||||
moveY = e.getScreenY() - this.getLayoutY();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标移动
|
||||
*/
|
||||
private void bindMouseMovedEvent() {
|
||||
this.setOnMouseMoved(e -> {
|
||||
double width = this.getWidth(),
|
||||
height = this.getHeight(),
|
||||
x = e.getX() - newX,
|
||||
y = e.getY() - newY;
|
||||
x = e.getScreenX() - this.getLayoutX(),
|
||||
y = e.getScreenY() - this.getLayoutY();
|
||||
|
||||
|
||||
// topLeft
|
||||
if (x <= 3 && y <= 3) {
|
||||
this.setCursor(Cursor.SE_RESIZE);
|
||||
resizeType = "topLeft";
|
||||
rectangleCtrl = RectangleCtrl.TOP_LEFT;
|
||||
return;
|
||||
}
|
||||
|
||||
// topMiddle
|
||||
if (x <= width - 3 && y <= 3) {
|
||||
this.setCursor(Cursor.N_RESIZE);
|
||||
resizeType = "topMiddle";
|
||||
rectangleCtrl = RectangleCtrl.TOP_MIDDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
// topRight
|
||||
if (x <= width && y <= 3) {
|
||||
this.setCursor(Cursor.NE_RESIZE);
|
||||
resizeType = "topRight";
|
||||
rectangleCtrl = RectangleCtrl.TOP_RIGHT;
|
||||
return;
|
||||
}
|
||||
|
||||
// centerLeft
|
||||
if (x <= 3 && y <= height - 3) {
|
||||
this.setCursor(Cursor.W_RESIZE);
|
||||
resizeType = "centerLeft";
|
||||
rectangleCtrl = RectangleCtrl.CENTER_LEFT;
|
||||
return;
|
||||
}
|
||||
|
||||
// bottomLeft
|
||||
if (x <= 3 && y <= height) {
|
||||
this.setCursor(Cursor.NE_RESIZE);
|
||||
resizeType = "bottomLeft";
|
||||
rectangleCtrl = RectangleCtrl.BOTTOM_LEFT;
|
||||
return;
|
||||
}
|
||||
|
||||
// bottomMiddle
|
||||
if (x <= width - 3 && y >= height - 3) {
|
||||
this.setCursor(Cursor.N_RESIZE);
|
||||
resizeType = "bottomMiddle";
|
||||
rectangleCtrl = RectangleCtrl.BOTTOM_MIDDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
// bottomRight
|
||||
if (x <= width && y >= height - 3) {
|
||||
this.setCursor(Cursor.SE_RESIZE);
|
||||
resizeType = "bottomRight";
|
||||
rectangleCtrl = RectangleCtrl.BOTTOM_RIGHT;
|
||||
return;
|
||||
}
|
||||
|
||||
// centerRight
|
||||
if (x >= width - 3 && y <= height) {
|
||||
this.setCursor(Cursor.W_RESIZE);
|
||||
resizeType = "centerRight";
|
||||
rectangleCtrl = RectangleCtrl.CENTER_RIGHT;
|
||||
return;
|
||||
}
|
||||
|
||||
// 移动指针
|
||||
if (x >= 3 + 1 && x <= width - 3 && y >= 3 + 1 && y <= height - 3) {
|
||||
this.setCursor(Cursor.MOVE);
|
||||
resizeType = "move";
|
||||
rectangleCtrl = RectangleCtrl.MOVE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,8 +161,79 @@ public class ResizableRectangle extends Rectangle {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResizable() {
|
||||
return true;
|
||||
/**
|
||||
* 鼠标拖拽
|
||||
*/
|
||||
private void bindMouseDraggedEvent() {
|
||||
this.setOnMouseDragged(e -> {
|
||||
// 防止快速操作
|
||||
if (rectangleCtrl == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
double screenX = e.getScreenX(),
|
||||
screenY = e.getScreenY(),
|
||||
x = screenX - originX,
|
||||
y = screenY - originY;
|
||||
|
||||
|
||||
switch (rectangleCtrl) {
|
||||
case TOP_LEFT -> {
|
||||
this.setLayoutX(screenX);
|
||||
this.setLayoutY(screenY);
|
||||
|
||||
this.setWidth(width - x);
|
||||
this.setHeight(height - y);
|
||||
}
|
||||
|
||||
case TOP_MIDDLE -> {
|
||||
this.setLayoutY(screenY);
|
||||
this.setHeight(height - y);
|
||||
}
|
||||
|
||||
case TOP_RIGHT -> {
|
||||
this.setLayoutY(screenY);
|
||||
|
||||
this.setWidth(x);
|
||||
this.setHeight(height - y);
|
||||
}
|
||||
|
||||
case CENTER_LEFT -> {
|
||||
this.setLayoutX(screenX);
|
||||
this.setWidth(width - x);
|
||||
}
|
||||
|
||||
case CENTER_RIGHT -> this.setWidth(x);
|
||||
|
||||
case BOTTOM_LEFT -> {
|
||||
this.setLayoutX(screenX);
|
||||
this.setWidth(width - x);
|
||||
this.setHeight(y);
|
||||
}
|
||||
|
||||
case BOTTOM_MIDDLE -> this.setHeight(y);
|
||||
|
||||
case BOTTOM_RIGHT -> {
|
||||
this.setWidth(x);
|
||||
this.setHeight(y);
|
||||
}
|
||||
|
||||
case MOVE -> {
|
||||
this.setLayoutX(screenX - moveX);
|
||||
this.setLayoutY(screenY - moveY);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标抬起
|
||||
*/
|
||||
private void bindMouseReleasedEvent() {
|
||||
this.setOnMouseReleased(e -> {
|
||||
this.originX = this.getLayoutX();
|
||||
this.originY = this.getLayoutY();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
package org.rococy.roomit.enums;
|
||||
|
||||
/**
|
||||
* Shape的八个调整大小的点位
|
||||
*
|
||||
* @author Rococy
|
||||
* @date 2022/9/16
|
||||
*/
|
||||
public enum RectangleCtrl {
|
||||
|
||||
/**
|
||||
* 上左缩放
|
||||
*/
|
||||
TOP_LEFT,
|
||||
|
||||
/**
|
||||
* 上中缩放
|
||||
*/
|
||||
TOP_MIDDLE,
|
||||
|
||||
/**
|
||||
* 上右缩放
|
||||
*/
|
||||
TOP_RIGHT,
|
||||
|
||||
/**
|
||||
* 中左缩放
|
||||
*/
|
||||
CENTER_LEFT,
|
||||
|
||||
/**
|
||||
* 中右缩放
|
||||
*/
|
||||
CENTER_RIGHT,
|
||||
|
||||
/**
|
||||
* 下左缩放
|
||||
*/
|
||||
BOTTOM_LEFT,
|
||||
|
||||
/**
|
||||
* 下中缩放
|
||||
*/
|
||||
BOTTOM_MIDDLE,
|
||||
|
||||
/**
|
||||
* 下右缩放
|
||||
*/
|
||||
BOTTOM_RIGHT,
|
||||
|
||||
/**
|
||||
* 移动
|
||||
*/
|
||||
MOVE
|
||||
|
||||
}
|
Loading…
Reference in New Issue