Peter Penzov
Peter Penzov

Reputation: 1720

Drag BorderPane body

I use this JavaFX code to drag BorderPane into FlowPane:

private Node dragPanel(Node bp)
    {
        bp.setOnDragDetected(new EventHandler<MouseEvent>()
        {
            @Override
            public void handle(MouseEvent event)
            {
                Dragboard db = bp.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent clipboard = new ClipboardContent();
                final int nodeIndex = bp.getParent().getChildrenUnmodifiable()
                    .indexOf(bp);
                clipboard.putString(Integer.toString(nodeIndex));
                db.setContent(clipboard);

                Image img = bp.snapshot(null, null);
                db.setDragView(img, 7, 7);

                event.consume();
            }
        });
        bp.setOnDragOver(new EventHandler<DragEvent>()
        {
            @Override
            public void handle(DragEvent event)
            {
                boolean accept = true;
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString())
                {
                    try
                    {
                        int incomingIndex = Integer.parseInt(dragboard.getString());
                        int myIndex = bp.getParent().getChildrenUnmodifiable()
                            .indexOf(bp);
                        if (incomingIndex == myIndex)
                        {
                            accept = false;
                        }
                    }
                    catch (java.lang.NumberFormatException e)
                    {
                        // handle null or not number string in clipboard
                        accept = false;
                    }
                }
                else
                {
                    accept = false;
                }
                if (accept)
                {
                    event.acceptTransferModes(TransferMode.MOVE);
                }
            }
        });
        bp.setOnDragDropped(new EventHandler<DragEvent>()
        {
            @Override
            public void handle(DragEvent event)
            {
                boolean success = false;
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString())
                {
                    try
                    {
                        int incomingIndex = Integer.parseInt(dragboard.getString());
                        final Pane parent = (Pane) bp.getParent();
                        final ObservableList<Node> children = parent.getChildren();
                        int myIndex = children.indexOf(bp);
                        final int laterIndex = Math.max(incomingIndex, myIndex);
                        Node removedLater = children.remove(laterIndex);
                        final int earlierIndex = Math.min(incomingIndex, myIndex);
                        Node removedEarlier = children.remove(earlierIndex);
                        children.add(earlierIndex, removedLater);
                        children.add(laterIndex, removedEarlier);
                        success = true;
                    }
                    catch (java.lang.NumberFormatException e)
                    {
                        //TO DO... handle null or not number string in clipboard
                    }
                }
                event.setDropCompleted(success);
            }
        });
//        bp.setMinSize(50, 50);
        return bp;
    }

I enable this drag event using this code:

BorderPane panel = new BorderPane();
dragPanel(panel),

I also have resize code which is also activated. I need some way to apply the drag code only of I click and drag the panel. I want to disable the drag listener when I drag the panel borders. Is there a way to limit this?

Upvotes: 0

Views: 548

Answers (1)

James_D
James_D

Reputation: 209694

I'm guessing by "borders" you just mean the edges of the border panes. You can just check the coordinates of the mouse event and only initiate dragging if you're away from the borders. To do this, you need to know the width and height of the border pane. The methods to get those are defined in Region, so you need to narrow the type of the parameter from Node to Region. This will still work if you call dragPanel(panel) but you won't be able to pass in a Node that is not a Region instance.

final int borderSize = 5 ;

// ...
private Node dragPane(Region bp) {

    bp.setOnDragDetected(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            double x = event.getX();
            double y = event.getY();
            double width = bp.getWidth();
            double height = bp.getHeight();
            if (x > borderSize && x < width - borderSize 
                  && y > borderSize && y < height - borderSize) {

                Dragboard db = bp.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent clipboard = new ClipboardContent();
                final int nodeIndex = bp.getParent().getChildrenUnmodifiable()
                    .indexOf(bp);
                clipboard.putString(Integer.toString(nodeIndex));
                db.setContent(clipboard);

                Image img = bp.snapshot(null, null);
                db.setDragView(img, 7, 7);

                event.consume();
            }
        }
    });

    // ...
}

Upvotes: 1

Related Questions