correct way to move a node by dragging in javafx 2?

前端 未结 8 804
感动是毒
感动是毒 2020-12-01 05:50

I\'m converting a Swing/Graphics2D app with a lot of custom painting to a JavaFX2 app. Although I absolutely love the new API, I seem to have a performance problem when pain

相关标签:
8条回答
  • 2020-12-01 06:18

    Drag Sphere

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        super.initialize(location, resources);
        labelTableName.setText("Table Categories");
    
        final PhongMaterial blueMaterial = new PhongMaterial();
        blueMaterial.setDiffuseColor(Color.BLUE);
        blueMaterial.setSpecularColor(Color.LIGHTBLUE);
    
        final Sphere sphere = new Sphere(50);
        sphere.setMaterial(blueMaterial);
    
        final Measure dragMeasure = new Measure();
        final Measure position = new Measure();
        sphere.setOnMousePressed(mouseEvent -> {
            dragMeasure.x = mouseEvent.getSceneX() - position.x;
            dragMeasure.y = mouseEvent.getSceneY() - position.y;
            sphere.setCursor(Cursor.MOVE);
        });
        sphere.setOnMouseDragged(mouseEvent -> {
            position.x = mouseEvent.getSceneX() - dragMeasure.x;
            position.y = mouseEvent.getSceneY() - dragMeasure.y;
            sphere.setTranslateX(position.x);
            sphere.setTranslateY(position.y);
        });
        sphere.setOnMouseReleased(mouseEvent -> sphere.setCursor(Cursor.HAND));
        sphere.setOnMouseEntered(mouseEvent -> sphere.setCursor(Cursor.HAND));
    
        bottomHeader.getChildren().addAll( sphere);
    
    }
    
    class Measure {
        double x, y;
    
        public Measure() {
            x = 0; y = 0;
        }
    }
    
    0 讨论(0)
  • 2020-12-01 06:19

    Here is some code I use to allow a Label to be dragged around in a Pane. I don't notice any significant lag behind the mouse trail with it.

    // allow the label to be dragged around.
    final Delta dragDelta = new Delta();
    label.setOnMousePressed(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        // record a delta distance for the drag and drop operation.
        dragDelta.x = label.getLayoutX() - mouseEvent.getSceneX();
        dragDelta.y = label.getLayoutY() - mouseEvent.getSceneY();
        label.setCursor(Cursor.MOVE);
      }
    });
    label.setOnMouseReleased(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        label.setCursor(Cursor.HAND);
      }
    });
    label.setOnMouseDragged(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        label.setLayoutX(mouseEvent.getSceneX() + dragDelta.x);
        label.setLayoutY(mouseEvent.getSceneY() + dragDelta.y);
      }
    });
    label.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        label.setCursor(Cursor.HAND);
      }
    });
    
    . . .
    
    // records relative x and y co-ordinates.
    class Delta { double x, y; }
    

    Here is a small complete example app using the above code.

    Update The above example, will still lag the object being dragged behind the cursor when the objects being dragged are small.

    An alternate approach is to use an ImageCursor comprising of a MousePointer superimposed over the an image representation of the node being dragged, then hide and show the actual node at the start and completion of the drag. This means that the node drag rendering will not lag the cursor (as the image representation of the node is now the cursor). However this approach does have drawbacks => there are restrictions on the size and format of ImageCursors, plus you need to convert your Node to an Image to place it in an ImageCursor, for which you may need advanced Node => Image conversion operations only to available in JavaFX 2.2+.

    0 讨论(0)
提交回复
热议问题