Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

JavaFX drag events destroyed by window resize

2843711Jan 24 2015 — edited Jan 25 2015

Hello,

I've been having great success developing a drag-drop component for a JavaFX app, but I've run into an issue that has me completely stumped.

Specifically, I create a component that can be dragged around inside an anchor pane.  That anchorpane is nested in a split pane, which is nested in another anchor pane (the control's root element).

The issue can be described this way:

Case #1:  If I start the application as a small window, I can reposition the control by dragging it around the screen as I please.

Case #2: If I start the application and maximize the window, again, I can drag the control around the screen as I please.

Case #3: If I start the application, drag the control around a bit, then resize the window, the drag event handling breaks as follows:

1.  The control drag events will fire normally only within the bounds of the anchor pane's previous size.

2.  The mouse cursor's drag icon changes as I pass in or out of those bounds

I'm absolutely certain the anchorpane is resizing to match the parent window, otherwise Case #2 would not succeed.  I'm at a complete loss as to determine why the drag events don't fire within the bounds of the resized window after they've been fired within the bounds of it's previous size.

Understand the mechanism I'm using to establish the drag handling:  Once the controller is instantiated and added to the scene, an event listener on the class's parentProperty fires to attach the drag event handling to the parent node.

Previously, I was setting / clearing the drag handling on the parent node in the drag detection / drag dropped event handlers.  I had suspected that adding / removing drag events was causing the trouble and opted for this solution to ensure that the same event instance

was being used each time.  Both methods have had the same result.

If you want to see the UI in action, here's a youtube link (it does not demonstrate the problem I'm having):

http://youtu.be/FJWRFN8xHFY

Here's the code that I'm using, redacted for clarity:

public class FileSystemNode extends AnchorPane {

    @FXML private AnchorPane fs_node_title;

    private FileSystemType mFsType;

    private Point2D mDragPoint;

    private EventHandler <MouseEvent> mNodeDragDetected;

    public FileSystemNode() {

        loadFxml();

        setId(mFsType.toString() + Double.toString(Math.random()));

    }

   

    private void loadFxml() {

        FXMLLoader fxmlLoader = new FXMLLoader(

                getClass().getResource("/FileSystemNode.fxml"));

       

        fxmlLoader.setRoot(this);

        fxmlLoader.setController(this);

       

        try {

            fxmlLoader.load();

       

             parentProperty().addListener(new ChangeListener() {

                    @Override

                    public void changed(ObservableValue observable,

                            Object oldValue, Object newValue) {   

                        buildNodeDragHandlers();   

                        fs_node_title.setOnDragDetected(mNodeDragDetected);       

                    }

                });

            

        } catch (IOException exception) {

            throw new RuntimeException(exception);

        }       

    }

   

    public void relocateToPoint (Point2D p) {

        Point2D p2 = getParent().sceneToLocal(p);

        relocate (

                (int) (p2.getX() - mDragPoint.getX()),

                (int) (p2.getY() - mDragPoint.getY())

            );

    }

   

    public void buildNodeDragHandlers() {

       

        getParent().setOnDragOver(new EventHandler <DragEvent>() {

            //dragover to handle node dragging in the right pane view

            @Override

            public void handle(DragEvent event) {       

                event.acceptTransferModes(TransferMode.ANY);

                relocateToPoint(new Point2D( event.getSceneX(), event.getSceneY()));

                event.consume();

            }

        });

        getParent().setOnDragDropped(new EventHandler <DragEvent> () {

           

            @Override

            public void handle(DragEvent event) {

                event.setDropCompleted(true);

                event.consume();

            }});       

        //drag detection for node dragging

        mNodeDragDetected = new EventHandler <MouseEvent> () {

            @Override

            public void handle(MouseEvent event) {

               

                mDragPoint = new Point2D(event.getX(), event.getY());

                        relocateToPoint(new Point2D(event.getSceneX(), event.getSceneY()));

               

                        ClipboardContent content = new ClipboardContent();

                        content.putString("node_drag");

                        startDragAndDrop (TransferMode.ANY).setContent(content);               

               

                        event.consume();                   

            }   

        };       

    }   

}

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 22 2015
Added on Jan 24 2015
1 comment
1,484 views