Хватит перетаскивать Node из панели - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть StackPane, которую я могу перетаскивать по Панели (панель является родительским макетом панели стека), но в данный момент я могу перетащить ее из Панели. В настоящее время я не могу найти способ остановить перемещение StackPane на панель, когда она перетаскивается из панели.

Мой обработчик событий при нажатии на StackPane:

EventHandler<MouseEvent> circleOnMousePressedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                currentStackPane  = ((StackPane)(t.getSource()));
                orgSceneX = t.getSceneX();
                orgSceneY = t.getSceneY();
                layoutX =  currentStackPane.getLayoutX();
                layoutY =  currentStackPane.getLayoutY();

            }
        };

Мой обработчик событий при перетаскивании StackPane:

EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {


                double offsetX = t.getSceneX() - orgSceneX;
                double offsetY = t.getSceneY() - orgSceneY;
                currentStackPane.setTranslateX(offsetX);
                currentStackPane.setTranslateY(offsetY);
             }
        };

Мой обработчик событий, когда я отпускаю мышь:

            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {

                currentStackPane.setLayoutX(layoutX + ((StackPane)(t.getSource())).getTranslateX());
                currentStackPane.setLayoutY(layoutY + ((StackPane)(t.getSource())).getTranslateY());
                currentStackPane.setTranslateX(0);
                currentStackPane.setTranslateY(0);
            }
        };
        return circleOnMouseReleaseEventHandler;

}

Есть ли способ, которым панель стека может быть перетаскиваемой только внутри панели.

Спасибо.

EDIT:

Что я пробовал:

Я создал этот метод:

private boolean outSideParentBounds( Bounds childBounds, double newX, double newY) {

    Bounds parentBounds = centerPane.getLayoutBounds();

    //check if too left
    if( parentBounds.getMaxX() <= (newX + childBounds.getMaxX()) ) {
        return true ;
    }

    //check if too right
    if( parentBounds.getMinX() >= (newX + childBounds.getMinX()) ) {
        return true ;
    }

    //check if too down
    if( parentBounds.getMaxY() <= (newY + childBounds.getMaxY()) ) {
        return true ;
    }

    //check if too up
    if( parentBounds.getMinY() >= (newY + childBounds.getMinY()) ) {
        return true ;
    }

    return false;
}

И мой обработчик событий перетаскивания теперь выглядит так:

EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {


                double offsetX = t.getSceneX() - orgSceneX;
                double offsetY = t.getSceneY() - orgSceneY;

                if( outSideParentBounds(currentStackPane.getLayoutBounds(), layoutX + ((StackPane)(t.getSource())).getTranslateX(), 
                        layoutY + ((StackPane)(t.getSource())).getTranslateY()) ) {  

                    return; 
                }

                currentStackPane.setTranslateX(offsetX);
                currentStackPane.setTranslateY(offsetY);

            }
        };

Но, похоже, это не сработает, когда я перетаскиваю его из панели, оно просто застревает на краю панели, и вы больше не можете его перетаскивать.

1 Ответ

0 голосов
/ 15 ноября 2018

Одна проблема, которую я могу заметить, это то, что вы не учитываете значения offSet при вычислении outSideParentBounds.А также вы не можете обновлять переводимые значения ТОЛЬКО когда условие выполнено.Вместо этого вы должны ВСЕГДА обновлять переводимые значения до требуемых значений в обработчике перетаскивания.

Ваш обработчик перетаскивания должен быть изменен, как показано ниже: *

EventHandler<MouseEvent> circleOnMouseDraggedEventHandler = e -> {
            // Offset of drag
            double offsetX = e.getSceneX() - sceneX;
            double offsetY = e.getSceneY() - sceneY;

            // Taking parent bounds
            Bounds parentBounds = currentStackPane.getParent().getLayoutBounds();

            // Drag node bounds
            double currPaneLayoutX = currentStackPane.getLayoutX();
            double currPaneWidth = currentStackPane.getWidth();
            double currPaneLayoutY = currentStackPane.getLayoutY();
            double currPaneHeight = currentStackPane.getHeight();

            if ((currPaneLayoutX + offsetX > -1) && (currPaneLayoutX + offsetX < parentBounds.getWidth() - currPaneWidth)) {
                // If the dragNode bounds is within the parent bounds, then you can set the offset value.
                currentStackPane.setTranslateX(offsetX);
            } else if (currPaneLayoutX + offsetX < 0) {
                // If the sum of your offset and current layout position is negative, then you ALWAYS update your translate value to negative layout value
                // which makes the final layout position to 0 in mouse released event.
                currentStackPane.setTranslateX(-currPaneLayoutX);
            } else {
                // If your dragNode bounds are outside parent bounds,ALWAYS setting the translate value that fits your node at end.
                currentStackPane.setTranslateX(parentBounds.getWidth() - currPaneLayoutX - currPaneWidth);
            }

            if ((currPaneLayoutY + offsetY < parentBounds.getHeight() - currPaneHeight) && (currPaneLayoutY + offsetY > -1)) {
                currentStackPane.setTranslateY(offsetY);
            } else if (currPaneLayoutY + offsetY < 0) {
                currentStackPane.setTranslateY(-currPaneLayoutY);
            } else {
                currentStackPane.setTranslateY(parentBounds.getHeight() - currPaneLayoutY - currPaneHeight);
            }
        };

Причина ВСЕГДА обновления заключается в следующем: обработчик события перетаскивания не будет вызываться для каждого перетаскиваемого пикселя.Предположим, вы хотите перетащить узел на 500 пикселей.Если вы напечатаете значения offsetX / Y, вы заметите, что значения offsetX / Y НЕ ВСЕГДА последовательны или не будут печататься для каждого пикселя.Это может прыгать некоторые значения.Они могут варьироваться в зависимости от скорости вашего сопротивления.По этой причине вас могут перепрыгнуть через желаемую конечную точку.

Чтобы убедиться в этом, как только вы ознакомитесь с приведенным выше кодом, попробуйте комментировать части кода else, оставив только первое условие if.Попробуйте быстро перетащить узел, и вы заметите, что ваш узел будет произвольно заканчиваться далеко вперед / позади желаемой конечной точки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...