Implement drag-and-drop like in Scene Builder

2019-04-07 00:07发布

I'm building an application in JavaFx 2.2 which consist in a splitpane with a panel of component on the left side and a working sheet on the right side. Basically what i would like to do is a simple wysiwyg editor where you drag component from the left to the right, then arrange them on the right side.

I've spent the last couple of days trying to implement the same drag-and-drop feature that has SceneBuilder, without luck..

Following the sample at http://docs.oracle.com/javafx/2/drag_drop/HelloDragAndDrop.java.html i've managed to get a drag-and-drop working but i can't find any way to change the default file icon appearing when you are dragging (and replace it with a snapshot of the component i'm dragging) and how to show the forbidden icon when you are over something you can't dropped on.

Any help (could be advice, code snippet, sample or else) would be greatly appreciated :)

Thanks !

2条回答
冷血范
2楼-- · 2019-04-07 00:32

[UPDATE]

Finally managed it myself:

/* The 'sceneRoot' object is the root Node of the scene graph
 *    stage.setScene(new Scene(sceneRoot, 1280, 1024));
 */

private ImageView dragImageView = new ImageView();
private Node dragItem;

_

rightPane.setOnMouseDragEntered(new EventHandler<MouseDragEvent>() {
    public void handle(MouseDragEvent e) {
        rightPane.setStyle("-fx-border-color:red;-fx-border-width:2;-fx-border-style:solid;");
        e.consume();
    }
});
rightPane.setOnMouseDragExited(new EventHandler<MouseDragEvent>() {
    public void handle(MouseDragEvent e) {
        rightPane.setStyle("-fx-border-style:none;");
        e.consume();
    }
});
rightPane.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
    public void handle(MouseDragEvent e) {
        //TODO: add new instance of dragItem to rightPane
        e.consume();
    }
});

_

private void addGesture(final Node node) {
    node.setOnDragDetected(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {

            SnapshotParameters snapParams = new SnapshotParameters();
            snapParams.setFill(Color.TRANSPARENT);
            dragImageView.setImage(node.snapshot(snapParams, null));

            sceneRoot.getChildren().add(dragImageView);

            dragImageView.startFullDrag();
            e.consume();
        }
    });
    node.setOnMouseDragged(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {
            Point2D localPoint = sceneRoot.sceneToLocal(new Point2D(e.getSceneX(), e.getSceneY()));
            dragImageView.relocate(
                    (int)(localPoint.getX() - dragImageView.getBoundsInLocal().getWidth() / 2),
                    (int)(localPoint.getY() - dragImageView.getBoundsInLocal().getHeight() / 2)
            );
            e.consume();
        }
    });
    node.setOnMouseEntered(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {
            node.setCursor(Cursor.HAND);
        }
    });
    node.setOnMousePressed(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {
            dragItem = node;
            dragImageView.setMouseTransparent(true);
            node.setMouseTransparent(true);
            node.setCursor(Cursor.CLOSED_HAND);
        }
    });
    node.setOnMouseReleased(new EventHandler<MouseEvent>() {
        public void handle(MouseEvent e) {
            dragItem = null;
            dragImageView.setMouseTransparent(false);
            node.setMouseTransparent(false);
            node.setCursor(Cursor.DEFAULT);
            sceneRoot.getChildren().remove(dragImageView);
        }
    });

}
查看更多
相关推荐>>
3楼-- · 2019-04-07 00:43

Maybe late, but with the setDragView option, is more simpple by now :)

// Cursor Display for Drag&Drop
source.setOnMouseEntered(e -> source.setCursor(Cursor.OPEN_HAND));
source.setOnMousePressed(e -> source.setCursor(Cursor.CLOSED_HAND));
source.setOnMouseReleased(e -> source.setCursor(Cursor.DEFAULT));

// Manage drag
source.setOnDragDetected(event -> {
    /* drag was detected, start a drag-and-drop gesture*/
    Dragboard db = source.startDragAndDrop(TransferMode.MOVE);

    // Visual during drag
    SnapshotParameters snapshotParameters = new SnapshotParameters();
    snapshotParameters.setFill(Color.TRANSPARENT);
    db.setDragView(source.snapshot(snapshotParameters, null));

    /* Put a string on a dragboard */
    ClipboardContent content = new ClipboardContent();
    content.putString(source.getText());
    db.setContent(content);

    event.consume();
});
查看更多
登录 后发表回答