Невозможно сбросить прямоугольник в нужном месте с помощью JavaFX - PullRequest
0 голосов
/ 31 мая 2019

Я пытаюсь реализовать полный жест пресс-перетаскивания с помощью JavaFX. Я хочу перетащить прямоугольник из одного VBox в другой. В событии MOUSE_DRAG_RELEASED, которое происходит на целевом VBox, я пытаюсь добавить перетаскиваемый прямоугольник как дочерний элемент целевого VBox.

Проблема в том, что когда я отпускаю мышь на целевом 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). В чем может быть проблема?

1 Ответ

0 голосов
/ 31 мая 2019

Во время жеста перетаскивания мышью вы изменяете свойства translateX / translateY узла. Это приводит к смещению перетаскиваемого узла от позиции, в которой новый родитель помещает его с помощью этого преобразования. Вам необходимо сбросить эти значения, чтобы правильно добавить узел в нижнюю часть VBox:

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

    // reset translate values
    sourceDisk.setTranslateX(0);
    sourceDisk.setTranslateY(0);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...