2017-01-15 27 views
0

Я создал прямоугольник, который является одновременно подвижным и повторно масштабируемым. Мне нужно выполнить поворот для формы, которую я успешно выполнил. Однако, когда я поворачиваю фигуру, точки привязки не следуют. Может ли кто-нибудь, пожалуйста, дать мне несколько советов о том, что я делаю неправильно, или как я могу исправить эту проблему?Вращение формы - якоря не следуют - JavaFX

Перед вращения: enter image description here

После поворота: enter image description here

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

Прямоугольник Класс^

public void rotateObject(ActionEvent event) throws IOException { 

    rect.setRotate(90); 
    rect.getTransforms().add(new Rotate(45, rect.getBoundsInParent().getMinX() + 
      (rect.getBoundsInLocal().getWidth()/4), 
      rect.getBoundsInParent().getMinY() + rect.getBoundsInLocal().getHeight()/4)); 

} 

^Метод, используемый для вращения.

ответ

1

Помещенный «ручки» и прямоугольник в Group и повернуть группу вместо прямоугольника:

import javafx.application.Application; 
import javafx.geometry.Insets; 
import javafx.geometry.Point2D; 
import javafx.geometry.Pos; 
import javafx.scene.Cursor; 
import javafx.scene.Group; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.scene.shape.Rectangle; 
import javafx.scene.transform.Rotate; 
import javafx.stage.Stage; 

public class DraggingRectangleExample extends Application { 

    private Node rect ; 

    @Override 
    public void start(Stage primaryStage) { 
     rect = createDraggableRectangle(50, 50, 50, 150); 
     Pane pane = new Pane(rect); 
     pane.setMinSize(600, 600); 
     Button button = new Button("Rotate"); 
     button.setOnAction(e -> rotateObject()); 

     BorderPane root = new BorderPane(pane); 
     BorderPane.setMargin(button, new Insets(10)); 
     BorderPane.setAlignment(button, Pos.CENTER); 
     root.setBottom(button); 

     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
    } 

    public void rotateObject() { 

     rect.setRotate(90); 
     rect.getTransforms().add(new Rotate(45, rect.getBoundsInParent().getMinX() + 
       (rect.getBoundsInLocal().getWidth()/4), 
       rect.getBoundsInParent().getMinY() + rect.getBoundsInLocal().getHeight()/4)); 

    } 

    public Group 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 cornerof 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); 
//   } 
//  }); 

     Group group = new Group(rect, resizeHandleNW, resizeHandleSE, moveHandle); 


     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 <= group.getParent().getBoundsInLocal().getWidth() - handleRadius) { 
        rect.setWidth(rect.getWidth() + deltaX); 
       } 
       double newMaxY = rect.getY() + rect.getHeight() + deltaY ; 
       if (newMaxY >= rect.getY() 
         && newMaxY <= group.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 <=group.getParent().getBoundsInLocal().getWidth() - handleRadius) { 
        rect.setX(newX); 
       } 
       double newY = rect.getY() + deltaY ; 
       double newMaxY = newY + rect.getHeight(); 
       if (newY >= handleRadius 
         && newMaxY <=group.getParent().getBoundsInLocal().getHeight() - handleRadius) { 
        rect.setY(newY); 
       } 
       mouseLocation.value = new Point2D(event.getSceneX(), event.getSceneY()); 
      } 

     }); 


     return group ; 
    } 

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

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

Fantastic! Спасибо огромное! : D – TheBeliever12

+0

Однако, как только я сделал это, хотя я могу повернуть, форма больше не перетаскивается. Любая идея почему? – TheBeliever12

+0

Хм. Позвольте мне попытаться это понять. –