像在Scene Builder中一样实现拖放

时间:2012-11-29 11:13:13

标签: javafx-2 scenebuilder

我正在JavaFx 2.2中构建一个应用程序,它包含一个splitpane,左侧是一个组件面板,右侧是一个工作表。基本上我想做的是一个简单的所见即所得编辑器,你可以从左到右拖动组件,然后将它们排列在右侧。

我花了最近几天试图实现具有SceneBuilder的相同拖放功能,但没有运气..

http://docs.oracle.com/javafx/2/drag_drop/HelloDragAndDrop.java.html的示例之后,我设法进行了拖放工作,但我无法找到任何方法来更改拖动时出现的默认文件图标(并将其替换为我正在拖动的组件的快照)以及当你无法放弃的东西时如何显示禁用的图标。

任何帮助(可能是建议,代码片段,样本或其他)将不胜感激:)

谢谢!

2 个答案:

答案 0 :(得分:17)

<强> [UPDATE]

最后自己管理:

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

}

答案 1 :(得分:2)

也许迟到了,但是使用setDragView选项,现在更简单了:)

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