Dans mon programme, j'ai deux rectangles qui sont à la fois déplaçables et redimensionnables. J'ai ajouté une fonction qui me permet de sélectionner entre les deux, puis d'en supprimer une en fonction de la sélection et un clic sur un bouton.JavaFX - La forme supprime les points d'ancrage mais pas
après suppression:
code:
//Fields
private DraggingRectangle drag = new DraggingRectangle();
private List<Node> selectedShapes = new ArrayList<>();
@FXML
private AnchorPane container, container2;
//CreatingTheRectangle
if (treeview.getSelectionModel().getSelectedItem() == blackrect) {
Rectangle rect = drag.createDraggableRectangle(200, 60, 200, 60);
GraphicsContext gc = canvas.getGraphicsContext2D();
rect.setFill(Color.BLACK);
container2.getChildren().addAll(rect);
rect.setOnMouseClicked(e -> onShapeSelected(e));
}
//SelectingMethod
public void onShapeSelected(MouseEvent e) {
Shape shape = (Shape) e.getSource();
shape.setStyle("-fx-effect: dropshadow(three-pass-box, red, 10, 10, 0, 0);");
if (!selectedShapes.contains(shape)) {
selectedShapes.add(shape);
System.out.println("Shape Selected:" + shape);
} else {
shape.setStyle("-fx-effect: null");
selectedShapes.remove(shape);
}
//DeletingMethod
public void deleteButton(ActionEvent e) {
deletebutton.setOnAction(a -> container2.getChildren().removeAll(selectedShapes));
}
DraggableRectangle Classe:
public class DraggingRectangle {
public Rectangle createDraggableRectangle(double x, double y, double width, double height) {
final double handleRadius = 20 ;
final double handleRadius2 = 30 ;
Rectangle rect = new Rectangle(x, y, width, height);
// top left resize handle:
Circle resizeHandleNW = new Circle(handleRadius, Color.RED);
// 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.RED);
// 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(handleRadius2,Color.RED);
moveHandle.setOpacity(0.0);
// bind to bottom center of Rectangle:
moveHandle.centerXProperty().bind(rect.xProperty().add(rect.widthProperty().divide(2)));
moveHandle.centerYProperty().bind(rect.yProperty().add(rect.heightProperty().divide(2)));
// 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 ; }
}
Je me rends compte qu'il a quelque chose à voir avec la liste J'ajoute les rectangles aussi, mais ne peut pas comprendre comment j'ajouter les points d'ancrage avec elle. Thank You
EXCEPTION:
Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = AnchorPane[id=container2]
at javafx.scene.Parent$2.onProposedChange(Parent.java:454)
at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:329)
at com.sun.javafx.collections.VetoableListDecorator.remove(VetoableListDecorator.java:221)
at Model.DraggingRectangle.lambda$createDraggableRectangle$0(DraggingRectangle.java:43)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.Node.setParent(Node.java:720)
at javafx.scene.Parent$2.onProposedChange(Parent.java:497)
at com.sun.javafx.collections.VetoableListDecorator.removeFromList(VetoableListDecorator.java:149)
at com.sun.javafx.collections.VetoableListDecorator.removeAll(VetoableListDecorator.java:264)
at Controller.NewLayoutController.lambda$deleteButton$9(NewLayoutController.java:261)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8411)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:352)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:275)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$355(GlassViewEventHandler.java:388)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:387)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
Polygon
public ObservableList<Anchor> createAnchorsPoly(Polygon polygon, final ObservableList<Double> points) {}
polygon.parentProperty().addListener((obs, oldParent, newParent) -> {
Platform.runLater(() -> {
for (ObservableList<Double> a : Arrays.asList(points)) {
Pane currentParent = (Pane)oldParent;
if (currentParent != null) {
currentParent.getChildren().remove(a);
}
if (newParent != null) {
((Pane)newParent).getChildren().add(a); <<Error!
}
}
});
Je pense que votre méthode ne supprime que les rectangles dans 'selectedShapes', ce qui n'est pas le cas avec' Circles'! –
J'ai essayé d'ajouter votre programme à Netbeans. Pas assez de code. – Sedrick