2023-02-16 338
使用以下代码(在这里有几篇文章),我绘制了一个矩形,我想可以解析和可移动.
两个锚(左上和右上)做我想做的事,最后一个(下部)移动矩形,但是两个第一个锚不遵循矩形.
当我让它们移动时,他们的听众调整了矩形大小.
package application;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.shape.StrokeType;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
private Rectangle rectangle;
private Group group;
private Scene scene;
private Stage primaryStage;
private ObservableList<Double> Coins;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
group = new Group();
rectangle = new Rectangle(200,200,400,300);
Coins = FXCollections.observableArrayList();
//UpperLeft
Coins.add(rectangle.getX());
Coins.add(rectangle.getY());
//LowerRight
Coins.add(rectangle.getX() + rectangle.getWidth());
Coins.add(rectangle.getY()+ rectangle.getHeight());
//Moving
Coins.add(rectangle.getX() + (rectangle.getWidth()/2));
Coins.add(rectangle.getY()+ (rectangle.getHeight()));
group.getChildren().addAll(createControlAnchorsFor(Coins));
group.getChildren().add(rectangle);
scene = new Scene(group,800,800);
primaryStage.setScene(scene);
primaryStage.show();
}
//@return a list of anchors which can be dragged around to modify points in the format [x1, y1, x2, y2...]
private ObservableList<Anchor> createControlAnchorsFor(final ObservableList<Double> points) {
ObservableList<Anchor> anchors = FXCollections.observableArrayList();
//Coin GaucheHaut
DoubleProperty xProperty = new SimpleDoubleProperty(points.get(0));
DoubleProperty yProperty = new SimpleDoubleProperty(points.get(1));
xProperty.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldX, Number x) {
System.out.println(oldX + " et " + x);
rectangle.setX((double) x);
rectangle.setWidth((double) rectangle.getWidth() -((double) x- (double) oldX));
anchors.get(2).setCenterX((double) x + rectangle.getWidth()/2 );
}
});
yProperty.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldY, Number y) {
rectangle.setY((double) y);
rectangle.setHeight((double) rectangle.getHeight() -((double) y- (double) oldY));
}
});
anchors.add(new Anchor(Color.GOLD, xProperty, yProperty));
//Coin DroiteBas
DoubleProperty xProperty2 = new SimpleDoubleProperty(points.get(2));
DoubleProperty yProperty2 = new SimpleDoubleProperty(points.get(3));
xProperty2.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldX, Number x) {
rectangle.setWidth((double) rectangle.getWidth() -((double) oldX- (double) x));
anchors.get(2).setCenterX((double) x - rectangle.getWidth()/2 );
}
});
yProperty2.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldY, Number y) {
rectangle.setHeight((double) rectangle.getHeight() -((double) oldY- (double) y));
anchors.get(2).setCenterY((double) y);
}
});
anchors.add(new Anchor(Color.GOLD, xProperty2, yProperty2));
//Moving
DoubleProperty xPropertyM = new SimpleDoubleProperty(points.get(4));
DoubleProperty yPropertyM = new SimpleDoubleProperty(points.get(5));
xPropertyM.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldX, Number x) {
rectangle.setX((double) x - rectangle.getWidth()/2 );
//anchors.get(0).setCenterX((double) x- rectangle.getWidth()/2);
//anchors.get(0).setVisible(false);
}
});
yPropertyM.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> ov, Number oldY, Number y) {
rectangle.setY((double) y - rectangle.getHeight() );
Coins.set(1, (double) y);
}
});
anchors.add(new Anchor(Color.GOLD, xPropertyM, yPropertyM));
return anchors;
}
//a draggable anchor displayed around a point.
class Anchor extends Circle {
private final DoubleProperty x, y;
Anchor(Color color, DoubleProperty x, DoubleProperty y) {
super(x.get(), y.get(), 20);
setFill(color.deriveColor(1, 1, 1, 0.5));
setStroke(color);
setStrokeWidth(2);
setStrokeType(StrokeType.OUTSIDE);
this.x = x;
this.y = y;
x.bind(centerXProperty());
y.bind(centerYProperty());
enableDrag();
}
//make a node movable by dragging it around with the mouse.
private void enableDrag() {
final Delta dragDelta = new Delta();
setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = getCenterX() - mouseEvent.getX();
dragDelta.y = getCenterY() - mouseEvent.getY();
getScene().setCursor(Cursor.MOVE);
}
});
setOnMouseReleased(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
getScene().setCursor(Cursor.HAND);
}
});
setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
double newX = mouseEvent.getX() + dragDelta.x;
if (newX > 0 && newX < getScene().getWidth()) {
setCenterX(newX);
}
double newY = mouseEvent.getY() + dragDelta.y;
if (newY > 0 && newY < getScene().getHeight()) {
setCenterY(newY);
}
//Recompute screen;
group.getChildren().add(rectangle);
scene = new Scene(group,800,800);;
primaryStage.setScene(scene);
}
});
setOnMouseEntered(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.HAND);
}
}
});
setOnMouseExited(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
getScene().setCursor(Cursor.DEFAULT);
}
}
});
}
//records relative x and y co-ordinates.
private class Delta { double x, y; }
}
}
有什么想法,我应该在哪里添加一些东西?
由于”手柄”始终相对于矩形相同的位置,因此我将它们的位置绑定到矩形的位置.您可以通过
来实现这一目标
circle.centerXProperty().bind(...);
circle.centerYProperty().bind(...);
参数有些ObservableValue<Number>.
然后,在拖动处理程序中,只需根据需要移动Rectangle(计算稍微复杂,但还不错).由于圆的位置是绑定的,因此它们将遵循矩形.
这是一种使用此策略的可能实现:
import java.util.Arrays;
import javafx.application.Application;
import javafx.geometry.Point2D;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class DraggingRectangle extends Application {
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
Pane root = new Pane();
Rectangle rect = createDraggableRectangle(200, 200, 400, 300);
rect.setFill(Color.NAVY);
root.getChildren().add(rect);
Scene scene = new Scene(root, 800, 800);
primaryStage.setScene(scene);
primaryStage.show();
}
private Rectangle createDraggableRectangle(double x, double y, double width, double height) {
final double handleRadius = 10 ;
Rectangle rect = new Rectangle(x, y, width, height);
// top left resize handle:
Circle resizeHandleNW = new Circle(handleRadius, Color.GOLD);
// bind to top left corner of Rectangle:
resizeHandleNW.centerXProperty().bind(rect.xProperty());
resizeHandleNW.centerYProperty().bind(rect.yProperty());
// bottom right resize handle:
Circle resizeHandleSE = new Circle(handleRadius, Color.GOLD);
// bind to bottom right corner of Rectangle:
resizeHandleSE.centerXProperty().bind(rect.xProperty().add(rect.widthProperty()));
resizeHandleSE.centerYProperty().bind(rect.yProperty().add(rect.heightProperty()));
// move handle:
Circle moveHandle = new Circle(handleRadius, Color.GOLD);
// bind to bottom center of Rectangle:
moveHandle.centerXProperty().bind(rect.xProperty().add(rect.widthProperty().divide(2)));
moveHandle.centerYProperty().bind(rect.yProperty().add(rect.heightProperty()));
// force circles to live in same parent as rectangle:
rect.parentProperty().addListener((obs, oldParent, newParent) -> {
for (Circle c : Arrays.asList(resizeHandleNW, resizeHandleSE, moveHandle)) {
Pane currentParent = (Pane)c.getParent();
if (currentParent != null) {
currentParent.getChildren().remove(c);
}
((Pane)newParent).getChildren().add(c);
}
});
Wrapper<Point2D> mouseLocation = new Wrapper<>();
setUpDragging(resizeHandleNW, mouseLocation) ;
setUpDragging(resizeHandleSE, mouseLocation) ;
setUpDragging(moveHandle, mouseLocation) ;
resizeHandleNW.setOnMouseDragged(event -> {
if (mouseLocation.value != null) {
double deltaX = event.getSceneX() - mouseLocation.value.getX();
double deltaY = event.getSceneY() - mouseLocation.value.getY();
double newX = rect.getX() + deltaX ;
if (newX >= handleRadius
&& newX <= rect.getX() + rect.getWidth() - handleRadius) {
rect.setX(newX);
rect.setWidth(rect.getWidth() - deltaX);
}
double newY = rect.getY() + deltaY ;
if (newY >= handleRadius
&& newY <= rect.getY() + rect.getHeight() - handleRadius) {
rect.setY(newY);
rect.setHeight(rect.getHeight() - deltaY);
}
mouseLocation.value = new Point2D(event.getSceneX(), event.getSceneY());
}
});
resizeHandleSE.setOnMouseDragged(event -> {
if (mouseLocation.value != null) {
double deltaX = event.getSceneX() - mouseLocation.value.getX();
double deltaY = event.getSceneY() - mouseLocation.value.getY();
double newMaxX = rect.getX() + rect.getWidth() + deltaX ;
if (newMaxX >= rect.getX()
&& newMaxX <= rect.getParent().getBoundsInLocal().getWidth() - handleRadius) {
rect.setWidth(rect.getWidth() + deltaX);
}
double newMaxY = rect.getY() + rect.getHeight() + deltaY ;
if (newMaxY >= rect.getY()
&& newMaxY <= rect.getParent().getBoundsInLocal().getHeight() - handleRadius) {
rect.setHeight(rect.getHeight() + deltaY);
}
mouseLocation.value = new Point2D(event.getSceneX(), event.getSceneY());
}
});
moveHandle.setOnMouseDragged(event -> {
if (mouseLocation.value != null) {
double deltaX = event.getSceneX() - mouseLocation.value.getX();
double deltaY = event.getSceneY() - mouseLocation.value.getY();
double newX = rect.getX() + deltaX ;
double newMaxX = newX + rect.getWidth();
if (newX >= handleRadius
&& newMaxX <= rect.getParent().getBoundsInLocal().getWidth() - handleRadius) {
rect.setX(newX);
}
double newY = rect.getY() + deltaY ;
double newMaxY = newY + rect.getHeight();
if (newY >= handleRadius
&& newMaxY <= rect.getParent().getBoundsInLocal().getHeight() - handleRadius) {
rect.setY(newY);
}
mouseLocation.value = new Point2D(event.getSceneX(), event.getSceneY());
}
});
return rect ;
}
private void setUpDragging(Circle circle, Wrapper<Point2D> mouseLocation) {
circle.setOnDragDetected(event -> {
circle.getParent().setCursor(Cursor.CLOSED_HAND);
mouseLocation.value = new Point2D(event.getSceneX(), event.getSceneY());
});
circle.setOnMouseReleased(event -> {
circle.getParent().setCursor(Cursor.DEFAULT);
mouseLocation.value = null ;
});
}
static class Wrapper<T> { T value ; }
}
tldr:将其包装在新parent!= null检查中.
由于声誉较低,我无法发表评论,但我想指出的是需要添加到詹姆斯_D的代码中以避免问题.当我试图在带有多个可重大矩形的窗格上使用clear()方法时,我遇到了问题.我能够通过…
更改他的代码来解决此问题.
这个
// force circles to live in same parent as rectangle:
rect.parentProperty().addListener((obs, oldParent, newParent) -> {
for (Circle c : Arrays.asList(resizeHandleNW, resizeHandleSE, moveHandle)) {
Pane currentParent = (Pane)c.getParent();
if (currentParent != null) {
currentParent.getChildren().remove(c);
}
((Pane)newParent).getChildren().add(c);
}
});
.
// force circles to live in same parent as rectangle:
rect.parentProperty().addListener((obs, oldParent, newParent) -> {
if (newParent != null) {
for (Circle c : Arrays.asList(resizeHandleNW, resizeHandleSE, moveHandle)) {
Pane currentParent = (Pane)c.getParent();
if (currentParent != null) {
currentParent.getChildren().remove(c);
}
((Pane)newParent).getChildren().add(c);
}
}
});
以上所述是小编给大家介绍的可调整大小且可移动的矩形,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!
原文链接:https://77isp.com/post/33905.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态