【问题标题】:Can't drop a rectangle at the desired location with JavaFX无法使用 JavaFX 在所需位置放置矩形
【发布时间】:2019-05-31 18:46:38
【问题描述】:

我正在尝试使用 JavaFX 实现完整的按下-拖动-释放手势。我想将一个矩形从一个 VBox 拖到另一个。在目标 VBox 上发生的 MOUSE_DRAG_RELEASED 事件中,我试图将拖动的矩形添加为目标 V​​Box 的子项。

问题是当我在目标 VBox 上释放鼠标时,矩形并没有进入 VBox 内的预期位置,而是总是向右偏移一个固定距离。

public class DragFromOneVBoxToAnother extends Application {
    private Disk sourceDisk = new Disk();
    private VBox targetVBox = new VBox();

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage stage) {
        // Build the UI
        GridPane root = getUI();

        // Add the event handlers
        this.addEventHandlers();

        Scene scene = new Scene(root, 800, 600);
        stage.setScene(scene);
        stage.show();
    }

    private GridPane getUI() {
        GridPane pane = new GridPane();
        VBox sourceVBox = new VBox();

        sourceDisk.setWidth(90);
        sourceDisk.setHeight(20);

        sourceVBox.setStyle(" -fx-border-color:red; -fx-border-width: 1; -fx-border-style: solid;");
        targetVBox.setStyle(" -fx-border-color:green; -fx-border-width: 1; -fx-border-style: solid;");

        sourceVBox.getChildren().add(sourceDisk);
        targetVBox.getChildren().add(new Rectangle(200, 20));

        pane.setHgap(200);
        pane.addColumn(0, sourceVBox);
        pane.addColumn(1, targetVBox);
        pane.setPadding(new Insets(200, 100, 200, 100));

        return pane;
    }

    private void addEventHandlers() {
        sourceDisk.setOnMouseEntered(event -> sourceDisk.setCursor(Cursor.HAND));

        sourceDisk.setOnMousePressed(event -> {
            sourceDisk.setOrgSceneX(event.getSceneX());
            sourceDisk.setOrgSceneY(event.getSceneY());
            sourceDisk.setOrgTranslateX(sourceDisk.getTranslateX());
            sourceDisk.setOrgTranslateY(sourceDisk.getTranslateY());

            sourceDisk.setMouseTransparent(true);
            sourceDisk.setCursor(Cursor.CLOSED_HAND);
        });

        sourceDisk.setOnDragDetected(event -> sourceDisk.startFullDrag());

        sourceDisk.setOnMouseDragged(event -> {
            double offsetX = event.getSceneX() - sourceDisk.getOrgSceneX();
            double offsetY = event.getSceneY() - sourceDisk.getOrgSceneY();
            double newTranslateX = sourceDisk.getOrgTranslateX() + offsetX;
            double newTranslateY = sourceDisk.getOrgTranslateY() + offsetY;

            sourceDisk.setTranslateX(newTranslateX);
            sourceDisk.setTranslateY(newTranslateY);
        });

        sourceDisk.setOnMouseReleased(event -> {
            sourceDisk.setMouseTransparent(false);
            sourceDisk.setCursor(Cursor.DEFAULT);
        });

        targetVBox.setOnMouseDragReleased(event -> 
            targetVBox.getChildren().add(sourceDisk));
    }

    private class Disk extends Rectangle {
        private double orgSceneX;
        private double orgSceneY;
        private double orgTranslateX;
        private double orgTranslateY;

        // below, the getters and setters for all the instance variables
        // were removed for brevity
}

我发现,即使拖动矩形的视觉表示在拖放时似乎发生了偏移,但实际上似乎将一个子对象添加到了目标 VBox(这可以看出,因为 VBox 的边框在MOUSE_DRAG_RELEASED 事件)。 可能是什么问题?

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    在鼠标拖动手势期间,您修改节点的translateX/translateY 属性。这会导致拖动的节点偏离新父节点通过此变换放置的位置。您需要重置这些值才能将节点正确添加到 VBox 的底部:

    targetVBox.setOnMouseDragReleased(event -> {
        targetVBox.getChildren().add(sourceDisk);
    
        // reset translate values
        sourceDisk.setTranslateX(0);
        sourceDisk.setTranslateY(0);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-14
      • 1970-01-01
      • 2021-09-25
      • 2014-02-03
      相关资源
      最近更新 更多