2017-01-22 40 views
0

在我的程序中,我有两个可拖动和可调整大小的矩形。我添加了一个功能,允许我在两者之间进行选择,然后根据选择和按钮单击删除其中的一个。JavaFX - 形状删除但锚点不是

删除之前: enter image description here

删除后:

enter image description here

代码:

//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类:

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 ; } 


} 

我认识到,它有事情做与我加入矩形太名单,但想不通我怎么会与它一起添加锚点。谢谢

例外:

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) 

多边形

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! 
        } 
       } 
      }); 
+0

我认为你的方法只删除'selectedShapes'里面的矩形,这与'Circles'不一样! –

+0

我试图将您的程序添加到Netbeans。没有足够的代码。 – Sedrick

回答

1

更换

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); 
    } 
}); 

rect.parentProperty().addListener((obs, oldParent, newParent) -> { 
    Platform.runLater(() -> { 
     for (Circle c : Arrays.asList(resizeHandleNW, resizeHandleSE, moveHandle)) { 
      Pane currentParent = (Pane)oldParent; 
      if (currentParent != null) { 
       currentParent.getChildren().remove(c); 
      } 
      if (newParent != null) { 
       ((Pane)newParent).getChildren().add(c); 
      } 
     } 
    }); 
}); 
+0

嘿,谢谢你的回复。我按照你的说法改变了代码,但我仍然遇到同样的问题。矩形删除,但锚点不删除。 :( – TheBeliever12

+0

是否有例外? –

+0

例外加入到我的原始消息 – TheBeliever12