在 javafx 中拖放 vbox 元素并显示快照

Ami*_*avi 3 drag-and-drop javafx-2

我想在 vbox 中拖动一个元素作为父元素,并在拖放元素期间显示节点移动,如何通过最轻微的更改来做到这一点。

Jam*_*s_D 6

只需将鼠标侦听器注册到 VBox 的元素即可。您希望在发生dragDetected 事件时在节点上调用startFullDrag(),并在发生dragReleased 事件时旋转VBox 的子节点。如果您想向用户提供有关拖动的视觉提示,可以使用dragEntered 和dragExited 事件。

有关更多信息,请参阅API 文档。

简单的示例(顺便说一句,JavaFX 8 中的代码更加清晰):

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            final VBox root = new VBox(5);
            final ScrollPane scroller = new ScrollPane();
            scroller.setContent(root);
            final Scene scene = new Scene(scroller,400,200);

            for (int i=1; i<=20; i++) {
                final Label label = new Label("Item "+i);
                addWithDragging(root, label);
            }

            // in case user drops node in blank space in root:
            root.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
                @Override
                public void handle(MouseDragEvent event) {
                    int indexOfDraggingNode = root.getChildren().indexOf(event.getGestureSource());
                    rotateNodes(root, indexOfDraggingNode, root.getChildren().size()-1);
                }
            });

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private void addWithDragging(final VBox root, final Label label) {
        label.setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                label.startFullDrag();
            }
        });

        // next two handlers just an idea how to show the drop target visually:
        label.setOnMouseDragEntered(new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent event) {
                label.setStyle("-fx-background-color: #ffffa0;");
            }
        });
        label.setOnMouseDragExited(new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent event) {
                label.setStyle("");
            }
        });

        label.setOnMouseDragReleased(new EventHandler<MouseDragEvent>() {
            @Override
            public void handle(MouseDragEvent event) {
                label.setStyle("");
                int indexOfDraggingNode = root.getChildren().indexOf(event.getGestureSource());
                int indexOfDropTarget = root.getChildren().indexOf(label);
                rotateNodes(root, indexOfDraggingNode, indexOfDropTarget);
                event.consume();
            }
        });
        root.getChildren().add(label);
    }

    private void rotateNodes(final VBox root, final int indexOfDraggingNode,
            final int indexOfDropTarget) {
        if (indexOfDraggingNode >= 0 && indexOfDropTarget >= 0) {
            final Node node = root.getChildren().remove(indexOfDraggingNode);
            root.getChildren().add(indexOfDropTarget, node);
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)