Moving a Node within its parent pane, and dropping it to another

十年热恋 提交于 2019-12-11 17:07:24

问题


Moving a node (Label in this case) within its parent Pane (lets call it moving), works as expected by adding appropriate handlers for MouseEvent:

node.setOnMousePressed(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
        x = node.getLayoutX() - mouseEvent.getSceneX();
        y = node.getLayoutY() - mouseEvent.getSceneY();
    }
});

node.setOnMouseDragged(new EventHandler<MouseEvent>() {
    @Override public void handle(MouseEvent mouseEvent) {
        node.setLayoutX(mouseEvent.getSceneX() + x);
        node.setLayoutY(mouseEvent.getSceneY() + y);
    }
});

Dragging the Label and dropping it at another Pane (lets call it dragging) also works as expected by adding appropriate handlers to source :

    node.setOnDragDetected(new EventHandler <MouseEvent>()  {
        @Override public void handle(MouseEvent event) {

            Dragboard dragboard = node.startDragAndDrop(TransferMode.COPY_OR_MOVE);
            ClipboardContent content = new ClipboardContent();
            content.putString(node.getId());
            dragboard.setContent(content);
            event.consume();
        }
    });

and target:

    target.setOnDragOver(new EventHandler <DragEvent>() {
        @Override public void handle(DragEvent event) {
            event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
            event.consume();
        }
    });

    target.setOnDragDropped(new EventHandler <DragEvent>(){
        @Override public void handle(DragEvent event) {
            Dragboard dragboard = event.getDragboard();
            if (dragboard.hasString())  {
                Node dragged = scene.lookup("#"+dragboard.getString());
                ((Pane) dragged.getParent()).getChildren().remove(dragged);
                target.getChildren().add(dragged);
                event.setDropCompleted(true);
            }
            else{
                event.setDropCompleted(false);
            }
            event.consume();
        }
    });

The problem is getting both work together. After adding drag-drop support it seems that MouseEvents are disabled so "moving" does not work.
Sure, I can work-around it and enable drag-drop only when Label is outside its parent Pane, but I wonder is this the appropriate way to get both functionalities ?

Here is a mcve. Setting isEnableDargAndDrop to false will disable node.setOnDragDetected thus enable moving it:

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;


public class DragTest extends Application {

    private double x, y;
    private boolean isEnableDargAndDrop;
    private Scene scene;

    @Override public void start(Stage primaryStage) throws Exception {

        isEnableDargAndDrop = true;
        GridPane root = new GridPane();
        Label label = getLabel();
        Pane leftPane = getPane(label, "cyan");
        root.add(leftPane,0,0);
        Pane rightPane = getPane(null, "yellow");
        root.add(rightPane,1,0);
        scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
        addDragSupport(label);
        addDropSupport(rightPane);
        addDropSupport(leftPane);
    }

    private Label getLabel() {

        Label label = new Label(" Move me ");
        label.setId("label");
        label.setStyle("-fx-background-color:white;-fx-border-width: 1;-fx-border-color: red;" );
        return label;
    }

    private Pane getPane(Node label, String color) {

        Pane pane = (label == null)? new Pane() : new Pane(label);
        pane.setStyle("-fx-background-color:"+color+";");
        pane.setPrefSize(150,100);
        return pane;
    }

    private void addDragSupport(Node node) {

        node.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent mouseEvent) {
                x = node.getLayoutX() - mouseEvent.getSceneX();
                y = node.getLayoutY() - mouseEvent.getSceneY();
                node.setCursor(Cursor.MOVE);
            }
        });
        node.setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent mouseEvent) {
                node.setCursor(Cursor.HAND);
            }
        });
        node.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent mouseEvent) {
                node.setLayoutX(mouseEvent.getSceneX() + x);
                node.setLayoutY(mouseEvent.getSceneY() + y);
            }
        });
        node.setOnMouseEntered(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent mouseEvent) {
                node.setCursor(Cursor.HAND);
            }
        });

        node.setOnDragDetected(new EventHandler <MouseEvent>()  {
            @Override public void handle(MouseEvent event) {
                if(! isEnableDargAndDrop ) { return;}
                Dragboard dragboard = node.startDragAndDrop(TransferMode.COPY_OR_MOVE);
                ClipboardContent content = new ClipboardContent();
                content.putString(node.getId());
                dragboard.setContent(content);
                event.consume();
            }
        });
    }

    private void addDropSupport(Pane target) {

        target.setOnDragOver(new EventHandler <DragEvent>() {
            @Override public void handle(DragEvent event) {
                event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
                event.consume();
            }
        });

        target.setOnDragDropped(new EventHandler <DragEvent>(){
            @Override public void handle(DragEvent event) {

                Dragboard dragboard = event.getDragboard();

                if (dragboard.hasString())  {

                    Node dragged = scene.lookup("#"+dragboard.getString());
                    if((dragged == null) || (dragged.getParent() == target)) {return;}

                    ((Pane) dragged.getParent()).getChildren().remove(dragged);
                    target.getChildren().add(dragged);
                    event.setDropCompleted(true);
                }
                else{
                    event.setDropCompleted(false);
                }
                event.consume();
            }
        });
    }

    public static void main (String[] args) {launch(null);  }
}

来源:https://stackoverflow.com/questions/44878414/moving-a-node-within-its-parent-pane-and-dropping-it-to-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!