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?
Node
you are trying to drop in to set up to receive those events? – SedricksetOnDragDropped
method. It works as i expect when i try with already tried Nodes. So i think that is not a problem. – HyungjinJeonVbox
to another ? – c0der