1
votes

I just made a simple Application which includes FlowPane and some VBoxs which has a Button.

The Main class is like this.

public class Main extends Application {

    @Override
    public void start(Stage stage) {
        Gallery a = new Gallery();
        a.setMaxWidth(200);
        a.setPrefWidth(200);
        Scene scene = new Scene(a); 

        stage.setTitle("Welcome to JavaFX!"); 
        stage.setScene(scene); 
        stage.sizeToScene(); 
        stage.show(); 
    }

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

and this Gallery.class is the main back ground class which extends FlowPane.

public class Gallery extends FlowPane{

    public Gallery() {
        super();

        PlotterPanel p1 = new PlotterPanel(this, "B1" );
        getChildren().add(p1);

        PlotterPanel p2 = new PlotterPanel(this, "B2");
        getChildren().add(p2);

        PlotterPanel p3 = new PlotterPanel(this, "B3" );
        getChildren().add(p3);

        PlotterPanel p4 = new PlotterPanel(this, "B4" );
        getChildren().add(p4);

        PlotterPanel p5 = new PlotterPanel(this, "B5" );
        getChildren().add(p5);

        PlotterPanel p6 = new PlotterPanel(this, "B6" );
        getChildren().add(p6);


    }
}

And PlotterPanel is the VBox which has Button and can be drag-drop in the Gallery.


public class PlotterPanel extends VBox{

    private static final String TAB_DRAG_KEY = "titledpane";
    private ObjectProperty<VBox> draggingTab;
    private Gallery mgallery;
    private PlotterPanel self;

    public PlotterPanel(Gallery gallery, String name) {
        super();
        mgallery = gallery;
        setPrefWidth(100);
        setPrefHeight(100);
        self = this;

        Button btn = new Button(name);
        btn.setEffect(new DropShadow());
        getChildren().add(btn);

        draggingTab = new SimpleObjectProperty<VBox>();

        setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                final Dragboard dragboard = event.getDragboard();
                if (dragboard.hasString()
                        && TAB_DRAG_KEY.equals(dragboard.getString())
                        && draggingTab.get() != null) {
                    event.acceptTransferModes(TransferMode.MOVE);
                    event.consume();
                }
            }
        });
        setOnDragDropped(new EventHandler<DragEvent>() {
            public void handle(final DragEvent event) {
                Dragboard db = event.getDragboard();
                boolean success = false;
                if (db.hasString()) {
                    Pane parent = mgallery;
                    Object source = event.getGestureSource();
                    int sourceIndex = parent.getChildren().indexOf(source);
                    System.out.println(sourceIndex);
                    int targetIndex = parent.getChildren().indexOf(self);
                    System.out.println(targetIndex);
                    List<Node> nodes = new ArrayList<Node>(parent.getChildren());
                    if (sourceIndex < targetIndex) {
                        Collections.rotate(
                                nodes.subList(sourceIndex, targetIndex + 1), -1);
                    } else {
                        Collections.rotate(
                                nodes.subList(targetIndex, sourceIndex + 1), 1);
                    }
                    parent.getChildren().clear();
                    parent.getChildren().addAll(nodes);
                    success = true;
                }
                event.setDropCompleted(success);
                event.consume();
            }
        });
        setOnDragDetected(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                Dragboard dragboard = self.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent clipboardContent = new ClipboardContent();
                clipboardContent.putString(TAB_DRAG_KEY);
                dragboard.setContent(clipboardContent);
                draggingTab.set(self);
                event.consume();
            }
        }); 
    }

}

The problem is that when i drag the PlotterPanel in the Gallery, it can`t be dragged at the first time. And i works after second try. It shows the dragging box when i start dragging, but when i try to drop on the other Node the Mouse point shows the x sign. but when the target is already tried Node to be dragged, i can drop on that Node.

How can i make the Drag-drop works well in JavaFX?

1
Is the Node you are trying to drop in to set up to receive those events?Sedrick
yes, there is setOnDragDropped method. It works as i expect when i try with already tried Nodes. So i think that is not a problem.HyungjinJeon
It could be that you are missing some drag events. Make sure you use them. Especially onDragDone. docs.oracle.com/javafx/2/drag_drop/jfxpub-drag_drop.htmSedrick
Are you trying to drag the button from one Vbox to another ?c0der

1 Answers

1
votes

The problem is in your condition to accept the drag:

            if (dragboard.hasString()
                    && TAB_DRAG_KEY.equals(dragboard.getString())
                    && draggingTab.get() != null) {
                event.acceptTransferModes(TransferMode.MOVE);
                event.consume();
            }

You are checking the draggingTab of the target, not the source. If the target hasn't been dragged itself, its draggingTab property will still be null. If you have dragged the target already, then it won't be null and it will accept the drag.

Did you mean to make draggingTab static?