2017-11-09 4 views
0

사용자가 javafx에서 사각형을 끌거나 크기를 조정할 수 있도록 노력하고 있습니다. javafx의 직사각형은 TopLeft-X, Y, 높이 및 너비로 그립니다.JavaFx - 사각형 크기 조정

내가하려는 것은 사용자가 핸들을 끌 수 있도록 사각형의 각 구석에 4 개의 핸들을 갖는 것입니다. 사각형의 크기가 변경됩니다.

내 응용 프로그램은 리스너의 재귀 호출로 인해 발생하는 것으로 알고있는 stackoverflow 예외를 throw합니다.

내가 뭔가를 잊었습니까? 아니면 불필요한 청취자가 있습니까?

public class Handler extends Circle 
{ 
    private double deltaX; 
    private double deltaY; 

    private static final double DEFAULT_RADIUS = 10; 
    private static final Color DEFAULT_COLOR = Color.GOLD; 

    private DoubleProperty xProperty; 
    private DoubleProperty yProperty; 

    public Handler(DoubleProperty xProperty, DoubleProperty yProperty) 
    { 
     super(DEFAULT_RADIUS, DEFAULT_COLOR); 

     this.xProperty = xProperty; 
     this.yProperty = yProperty; 

     init(); 
    } 

    private void init() 
    { 
     setFill(DEFAULT_COLOR.deriveColor(1, 1, 1, 0.5)); 
     setStroke(DEFAULT_COLOR); 
     setStrokeWidth(2); 
     setStrokeType(StrokeType.OUTSIDE); 

     centerXProperty().bind(xProperty); 
     centerYProperty().bind(yProperty); 

     setOnMousePressed(new EventHandler<MouseEvent>() 
     { 
      @Override 
      public void handle(MouseEvent mouseEvent) 
      { 
       mouseEvent.consume(); 

       deltaX = getCenterX() - mouseEvent.getX(); 
       deltaY = getCenterY() - mouseEvent.getY(); 

       getScene().setCursor(javafx.scene.Cursor.MOVE); 
      } 
     }); 

     setOnMouseReleased(new EventHandler<MouseEvent>() 
     { 
      @Override 
      public void handle(MouseEvent mouseEvent) 
      { 
       getScene().setCursor(javafx.scene.Cursor.HAND); 
      } 
     }); 

     setOnMouseEntered(new EventHandler<MouseEvent>() 
     { 
      @Override 
      public void handle(MouseEvent mouseEvent) 
      { 
       if (!mouseEvent.isPrimaryButtonDown()) 
       { 
        getScene().setCursor(javafx.scene.Cursor.HAND); 
       } 
      } 
     }); 

     setOnMouseExited(new EventHandler<MouseEvent>() 
     { 
      @Override 
      public void handle(MouseEvent mouseEvent) 
      { 
       if (!mouseEvent.isPrimaryButtonDown()) 
       { 
        getScene().setCursor(javafx.scene.Cursor.DEFAULT); 
       } 
      } 
     }); 

     setOnMouseDragged(new EventHandler<MouseEvent>() 
     { 
      @Override 
      public void handle(MouseEvent mouseEvent) 
      { 
       double newX = mouseEvent.getX() + deltaX; 
       double newY = mouseEvent.getY() + deltaY; 

       if (newX > 0 && newX < getScene().getWidth()) 
       {     
        xProperty.set(newX); 
       } 

       if (newY > 0 && newY < getScene().getHeight()) 
       {     
        yProperty.set(newY); 
       } 
      } 
     }); 
    } 

    //JavaFx Accessor and mutator 
} 


public class CustomRectangle extends Rectangle 
{ 
    private DoubleProperty topRightX; 
    private DoubleProperty topRightY; 

    private DoubleProperty btmLeftX; 
    private DoubleProperty btmLeftY; 

    private DoubleProperty btmRightX; 
    private DoubleProperty btmRightY; 

    private DoubleProperty customeWidth; 
    private DoubleProperty customHeight; 

    public CustomRectangle() 
    { 
     super(); 
     init(); 
    } 

    public CustomRectangle(double x, double y, double width, double height) 
    { 
     super(x, y, width, height); 
     init(); 
    } 

    public CustomRectangle(double width, double height, Paint fill) 
    { 
     super(width, height, fill); 
     init(); 
    } 

    public CustomRectangle(double width, double height) 
    { 
     super(width, height); 
     init(); 
    } 

    private void init() 
    {  
     topRightX = new SimpleDoubleProperty(); 
     topRightY = new SimpleDoubleProperty(); 

     btmLeftX = new SimpleDoubleProperty(); 
     btmLeftY = new SimpleDoubleProperty(); 

     btmRightX = new SimpleDoubleProperty(); 
     btmRightY = new SimpleDoubleProperty(); 

     topRightX.addListener((observable, oldValue, newValue) -> 
     { 
      this.setWidth(this.getWidth() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     topRightY.addListener((observable, oldValue, newValue) -> 
     { 
      this.setY(newValue.doubleValue()); 
      this.setHeight(this.getHeight() - (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     btmLeftX.addListener((observable, oldValue, newValue) -> 
     { 
      this.setX(newValue.doubleValue()); 
      this.setWidth(this.getWidth() - (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     btmLeftY.addListener((observable, oldValue, newValue) -> 
     { 
      this.setY(newValue.doubleValue()); 
      this.setHeight(this.getHeight() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     btmRightX.addListener((observable, oldValue, newValue) -> 
     { 
      this.setWidth(this.getWidth() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     btmRightY.addListener((observable, oldValue, newValue) -> 
     { 
      this.setHeight(this.getHeight() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     this.xProperty().addListener((observable, oldValue, newValue) -> 
     {   
      btmLeftX.set(newValue.doubleValue()); 
      topRightX.set(newValue.doubleValue() + this.getWidth()); 
      btmRightX.set(newValue.doubleValue() + this.getWidth()); 
     }); 

     this.yProperty().addListener((observable, oldValue, newValue) -> 
     {   
      btmLeftY.set(newValue.doubleValue() + this.getHeight()); 
      topRightY.set(newValue.doubleValue()); 
      btmRightY.set(newValue.doubleValue() + this.getHeight()); 
     }); 

     this.widthProperty().addListener((observable, oldValue, newValue) -> 
     { 
      topRightX.set(this.getX() + (newValue.doubleValue() - oldValue.doubleValue())); 
      btmRightX.set(this.getX() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

     this.heightProperty().addListener((observable, oldValue, newValue) -> 
     { 
      btmLeftY.set(this.getY() + (newValue.doubleValue() - oldValue.doubleValue())); 
      btmRightY.set(this.getY() + (newValue.doubleValue() - oldValue.doubleValue())); 
     }); 

    } 
    //JavaFx Accessor and Mutator 
} 

public class FeatureHelper 
{ 
    private static double orgSceneX;  
    private static double orgSceneY; 

    private static double orgTranslateX; 
    private static double orgTranslateY; 

    public static CustomRectangle createDraggableRectangle(double x, double y, double width, double height, 
      boolean resizeImage) 
    { 
     CustomRectangle rect = new CustomRectangle(x, y, width, height); 

     // top left resize handle: 
     Handler topLeftHandle = new Handler(rect.topLeftXProperty(), rect.topLeftYProperty()); 

     // top right resize handle: 
     Handler topRightHandle = new Handler(rect.topRightXProperty(), rect.topRightYProperty()); 

     // bottom left resize handle: 
     Handler btmLeftHandle = new Handler(rect.btmLeftXProperty(), rect.btmLeftYProperty()); 

     // bottom right resize handle: 
     Handler btmRightHandle = new Handler(rect.btmRightXProperty(), rect.btmRightYProperty()); 

     // force circles to live in same parent as rectangle: 
     rect.parentProperty().addListener((obs, oldParent, newParent) -> 
     { 
      for (Circle c : Arrays.asList(topLeftHandle, topRightHandle, btmLeftHandle, btmRightHandle)) 
      { 
       if (newParent != null) 
       { 
        ((Pane) newParent).getChildren().add(c); 
       } 
      } 
     }); 

     rect.setOnMousePressed(event -> 
     { 
      event.consume(); 

      orgSceneX = event.getSceneX(); 
      orgSceneY = event.getSceneY(); 

      Node p = ((Node) (event.getSource())); 

      orgTranslateX = p.getTranslateX(); 
      orgTranslateY = p.getTranslateY();   
     }); 

     rect.setOnMouseDragged(event -> 
     { 
      double offsetX = event.getSceneX() - orgSceneX; 
      double offsetY = event.getSceneY() - orgSceneY; 

      double newTranslateX = orgTranslateX + offsetX; 
      double newTranslateY = orgTranslateY + offsetY; 

      Node p = ((Node) (event.getSource())); 
      p.setTranslateX(newTranslateX); 
      p.setTranslateY(newTranslateY); 

      for(Circle circle : Arrays.asList(topLeftHandle, topRightHandle, btmLeftHandle, btmRightHandle)) 
      { 
       circle.setTranslateX(newTranslateX); 
       circle.setTranslateY(newTranslateY); 
      } 
     }); 

     return rect; 
    } 
} 

답변