[java] JavaFX 드래그 앤 드랍 기능 구현

JavaFX는 강력한 그래픽 사용자 인터페이스(UI)를 만들 수 있는 프레임워크입니다. 이 프레임워크를 사용하여 대화형 요소를 만들고 다양한 동작을 구현할 수 있습니다. 이번에는 JavaFX를 사용하여 드래그 앤 드랍 기능을 구현하는 방법에 대해 알아보겠습니다.

드래그 앤 드랍 기능 구현 절차

  1. 드래그 앤 드랍을 수행할 컨트롤(이미지, 텍스트 등)을 생성합니다.
  2. 컨트롤의 onMousePressed 이벤트 핸들러를 구현하여 드래그 시작 이벤트를 처리합니다.
  3. onMouseDragged 이벤트 핸들러를 구현하여 드래그 중인 위치를 처리합니다.
  4. 드래그 중인 위치를 타겟으로 설정할 수 있는 컨트롤에서 onDragOver 이벤트 핸들러를 구현하여 드롭 대상 위치를 처리합니다.
  5. 타겟에 드롭할 때의 처리를 위해 onDragDropped 이벤트 핸들러를 구현합니다.

예시 코드

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.Stage;

public class DragAndDropExample extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        Pane root = new Pane();

        Label draggableLabel = new Label("드래그할 레이블");
        draggableLabel.setTranslateX(100);
        draggableLabel.setTranslateY(100);
        draggableLabel.setFont(new Font("Arial", 16));

        Rectangle targetRectangle = new Rectangle(300, 200, Color.LIGHTGRAY);

        draggableLabel.setOnDragDetected(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent event) {
                Dragboard dragboard = draggableLabel.startDragAndDrop(javafx.scene.input.TransferMode.ANY);
                ClipboardContent content = new ClipboardContent();
                content.putString(draggableLabel.getText());
                dragboard.setContent(content);
                event.consume();
            }
        });

        targetRectangle.setOnDragOver(new EventHandler<javafx.scene.input.DragEvent>() {
            public void handle(javafx.scene.input.DragEvent event) {
                if (event.getDragboard().hasString()) {
                    event.acceptTransferModes(javafx.scene.input.TransferMode.ANY);
                }
                event.consume();
            }
        });

        targetRectangle.setOnDragDropped(new EventHandler<javafx.scene.input.DragEvent>() {
            public void handle(javafx.scene.input.DragEvent event) {
                Dragboard db = event.getDragboard();
                boolean success = false;
                if (db.hasString()) {
                    Label droppedLabel = new Label(db.getString());
                    droppedLabel.setTranslateX(event.getX());
                    droppedLabel.setTranslateY(event.getY());
                    root.getChildren().add(droppedLabel);
                    success = true;
                }
                event.setDropCompleted(success);
                event.consume();
            }
        });

        root.getChildren().addAll(draggableLabel, targetRectangle);

        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.setTitle("드래그 앤 드랍 예제");
        primaryStage.show();
    }
}

위의 예시 코드에서는 LabelRectangle을 사용하여 드래그 앤 드랍 기능을 구현하였습니다. Label에 마우스를 누르고 드래그하여 Rectangle 위로 옮길 때, 해당 위치에 새로운 Label을 생성합니다.

참고 자료