簡體   English   中英

停止將Node拖出窗格

[英]Stop dragging Node out of a Pane

我有一個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;

}

有沒有一種方法可以使堆棧窗格只能在窗格中拖動。

謝謝。

編輯:

我試過的

我創建了這種方法:

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

            }
        };

但是,一旦我將其拖出窗格,它似乎就卡住了窗格的邊緣,並且您再也無法將其拖拽了,這似乎不起作用。

我注意到的一個問題是您在計算outSideParentBounds時沒有考慮offSet值。 而且,只有在滿足條件時,您才能更新轉換值。 相反,您必須始終在拖動處理程序中將轉換值更新為所需值。

您的拖動處理程序應如下更改:

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

始終更新的原因是::拖動事件處理程序不會為您拖動的每個像素調用。 假設您要將一個節點拖動500px。 如果您打印offsetX / Y值,您會注意到offsetX / Y值並非始終是順序的,或者不會為每個像素打印。 它可能會跳一些值。 它們可能會根據您拖動的速度而變化。 因此,您可能會跳過所需的終點。

為了驗證這一點,一旦您熟悉上面的代碼,請嘗試注釋代碼的“其他”部分,並僅保留第一個if條件。 嘗試快速拖動節點,您會注意到您的節點將隨機終止在所需端點的前面/后面。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM