我正在尝试在GridPane中拖放图像,但是虽然可以启动拖动操作,但我无法将图像放到另一个单元格上。
我已关注this example。
这是我的Laucher.java:
package app;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Launcher extends Application {
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new DraggableGrid());
primaryStage.setTitle("Hello draggable grid !");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这是我的DraggableGrid.java:
package app;
import java.util.List;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.GridPane;
public class DraggableGrid extends GridPane {
public DraggableGrid(){
final int CELL_SIZE = 60;
for (int rank = 0; rank < 2; rank++){
for (int file = 0; file < 2; file++){
Group group = new Group();
Image bgImage = new Image(String.format("/app/images/%s_bg.jpg",
(file+rank) % 2 == 0 ? "green" : "dark"));
ImageView bgImageView = new ImageView(bgImage);
bgImageView.setFitWidth(CELL_SIZE);
bgImageView.setFitHeight(CELL_SIZE);
Image fgImage = (file+rank) == 0 ?
new Image("/app/images/car.png") : null;
ImageView fgImageView = new ImageView(fgImage);
fgImageView.setFitWidth(CELL_SIZE);
fgImageView.setFitHeight(CELL_SIZE);
group.getChildren().addAll(bgImageView, fgImageView);
add(group, file, rank);
}
}
addDndFeature();
}
private void addDndFeature() {
List<Node> children = getChildrenUnmodifiable();
for (int rank = 0; rank < 2; rank++){
for (int file = 0; file < 2; file++){
Node currentNode = children.get(file + rank*2);
ImageView currentNodeImageView = (ImageView) ((Group) currentNode)
.getChildren().get(1);
Image cellImage = currentNodeImageView.getImage();
currentNodeImageView.setOnDragDetected(event -> {
if (cellImage == null){
event.consume();
}
else {
Dragboard dragboard = currentNodeImageView
.startDragAndDrop(TransferMode.MOVE);
ClipboardContent clipboardContent = new ClipboardContent();
clipboardContent.putImage(cellImage);
dragboard.setContent(clipboardContent);
/////////////////////////
System.err.println("Drag started !");
///////////////////////////
event.consume();
}
});
currentNodeImageView.setOnDragOver(event -> {
if (event.getGestureSource() != currentNodeImageView
&& event.getDragboard().hasImage()){
event.acceptTransferModes(TransferMode.MOVE);
/////////////////////////
System.err.println("Drag accepted !");
///////////////////////////
}
event.consume();
});
currentNodeImageView.setOnDragDropped(event -> {
Dragboard dragboard = event.getDragboard();
boolean success = false;
if (dragboard.hasImage()){
currentNodeImageView.setImage(dragboard.getImage());
success = true;
}
event.setDropCompleted(success);
/////////////////////////
System.err.println("Drag dropped !");
///////////////////////////
event.consume();
});
currentNodeImageView.setOnDragDone(event -> {
if (event.getTransferMode() == TransferMode.MOVE){
((ImageView) event.getSource()).setImage(null);
}
/////////////////////////
System.err.println("Drag done !");
///////////////////////////
event.consume();
});
}
}
}
}
事实上,只有Strings“Drag start!”和“拖累!”被放在屏幕上,绕过被接受和放弃的状态。
答案 0 :(得分:1)
问题是您要将DragOver
和DragDropped
事件处理程序添加到源(即前景)图像视图中。应将它们添加到目标(即背景)图像视图中:
在循环中,获取目标图像视图:
ImageView targetNodeImageView = ( ImageView ) (( Group ) currentNode)
.getChildren().get( 0 );
然后添加linsteners:
targetNodeImageView.setOnDragOver(...);
targetNodeImageView.setOnDragDropped(...);