Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javafx 可调整大小和可移动的矩形_Javafx_Anchor_Rectangles - Fatal编程技术网

Javafx 可调整大小和可移动的矩形

Javafx 可调整大小和可移动的矩形,javafx,anchor,rectangles,Javafx,Anchor,Rectangles,使用下面的代码(多亏了这里的几篇文章),我画了一个矩形,我希望它可以调整大小和移动。 两个锚点(左上角和右下角)执行我想要的操作,最后一个锚点(中下角)移动矩形,但前两个锚点不跟随矩形 package application; import javafx.application.Application; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty;

使用下面的代码(多亏了这里的几篇文章),我画了一个矩形,我希望它可以调整大小和移动。 两个锚点(左上角和右下角)执行我想要的操作,最后一个锚点(中下角)移动矩形,但前两个锚点不跟随矩形

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

}
}
当我移动它们时,它们的侦听器会调整矩形的大小

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

}
}
包应用;
导入javafx.application.application;
导入javafx.beans.property.DoubleProperty;
导入javafx.beans.property.SimpleDoubleProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.EventHandler;
导入javafx.scene.Cursor;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.scene.shape.Rectangle;
导入javafx.scene.shape.shape;
导入javafx.scene.shape.StrokeType;
导入javafx.stage.stage;
导入javafx.stage.StageStyle;
公共类主扩展应用程序{
私有矩形;
私人集团;
私密场景;
私人阶段初级阶段;
私人货币;
公共静态void main(字符串[]args){
应用程序启动(args);
}
@凌驾
公共无效开始(阶段primaryStage){
组=新组();
矩形=新矩形(200400300);
Coins=FXCollections.observearraylist();
//左上方
Coins.add(rectangle.getX());
Coins.add(rectangle.getY());
//右下角
add(rectangle.getX()+rectangle.getWidth());
添加(rectangle.getY()+rectangle.getHeight());
//移动的
add(rectangle.getX()+(rectangle.getWidth()/2));
add(rectangle.getY()+(rectangle.getHeight());
group.getChildren().addAll(createControlAnchorsFor(Coins));
group.getChildren().add(矩形);
场景=新场景(组,800800);
初级阶段。场景(场景);
primaryStage.show();
}
//@返回锚定列表,可以拖动锚定来修改格式为[x1,y1,x2,y2…]的点
私有可观察列表createControlAnchorsFor(最终可观察列表点){
ObservableList anchors=FXCollections.observableArrayList();
//高加索钱币
DoubleProperty xProperty=新的SimpleDoubleProperty(points.get(0));
DoubleProperty yProperty=新的SimpleDoubleProperty(points.get(1));
addListener(新的ChangeListener(){
@Override public void changed(ObservalEvalue由于“句柄”始终位于相对于矩形的相同位置,因此我会将它们的位置绑定到矩形的位置

circle.centerXProperty().bind(...);
circle.centerYProperty().bind(...);
其中参数是某个
可观察值

然后在拖动处理程序中,只需根据需要移动
矩形
(计算稍微复杂,但不是太糟糕)。由于圆的位置是绑定的,因此它们将跟随矩形

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

}
}
下面是一个使用此策略的可能实现:

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


}
导入java.util.array;
导入javafx.application.application;
导入javafx.geometry.Point2D;
导入javafx.scene.Cursor;
导入javafx.scene.scene;
导入javafx.scene.layout.Pane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Circle;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
公共类DraggingRectangle扩展应用程序{
公共静态void main(字符串[]args){
应用程序启动(args);
}
@凌驾
公共无效开始(阶段primaryStage){
窗格根=新窗格();
矩形rect=createDragableRectangle(200200400300);
直接填充(颜色为海军蓝);
root.getChildren().add(rect);
场景=新场景(根,800800);
初级阶段。场景(场景);
primaryStage.show();
}
私有矩形CreateDragableRectangle(双x、双y、双宽、双高){
最终双手耐力=10;
矩形rect=新矩形(x,y,宽度,高度);
//左上角调整手柄:
圆形尺寸Handlenw=新圆形(handleRadius,颜色为金色);
//绑定到矩形的左上角:
resizeHandleNW.centerXProperty().bind(rect.xProperty());
resizeHandleNW.centerYProperty().bind(rect.yProperty());
//右下角调整控制柄:
圆形尺寸Handlese=新圆形(handleRadius,颜色为金色);
//绑定到矩形的右下角:
resizeHandleSE.centerXProperty().bind(rect.xProperty().add(rect.widthProperty());
resizeHandleSE.centerYProperty().bind(rect.yProperty().add(rect.heightProperty());
//移动手柄:
圆形moveHandle=新圆形(handleRadius,颜色为金色);
//绑定到矩形的底部中心:
moveHandle.centerXProperty().bind(rect.xProperty().add(rect.widthProperty().divide(2));
moveHandle.centerYProperty().bind(rect.yProperty().add(rect.heightProperty());
//强制圆与矩形位于同一父对象中:
rect.parentProperty().addListener((obs、oldParent、newParent)->{
for(圆c:Arrays.asList(resizeHandleNW、resizeHandleSE、moveHandle)){
窗格currentParent=(窗格)c.getParent();
如果(currentParent!=null){
currentParent.getChildren().remove(c);
}
((窗格)newParent.getChildren().add(c);
}
});
包装器鼠标位置=新包装器();
设置拖动(大小调整手柄,鼠标定位);
设置拖动(调整手柄大小,鼠标定位);
设置拖动(移动手柄、鼠标定位);
resizeHandleNW.setOnMouseDrawed(事件->{
if(mouseLocation.value!=null){