我正在设置一个战舰游戏,我希望能够通过将ImageView
个战舰拖动到网格中的按钮上来在游戏板上设置飞船。我有以下代码来设置到目前为止的所有拖放操作:
private void configureDragAndDrop(ImageView image) {
image.setOnDragDetected(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
Dragboard db = pictureOne.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
content.putImage(pictureOne.getImage());
db.setContent(content);
event.consume();
}
});
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragOver(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
/* data is dragged over the target */
/* accept it only if it is not dragged from the same node
* and if it has a string data */
if (event.getGestureSource() != target &&
event.getDragboard().hasImage()) {
/* allow for moving */
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
}
});
}
}
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragEntered(new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent event) {
/* the drag-and-drop gesture entered the target */
/* show to the user that it is an actual gesture target */
if (event.getGestureSource() != target &&
event.getDragboard().hasImage()) {
target.setStyle("-fx-background-color: pink");
}
event.consume();
}
});
}
}
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragExited(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* mouse moved away, remove the graphical cues */
target.setStyle("-fx-background-color:blue");
event.consume();
}
});
}
}
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasImage()) {
target.setStyle("-fx-background-color:green");
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
}
}
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* data dropped */
/* if there is a string data on dragboard, read it and use it */
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasImage()) {
target.setStyle("-fx-background-color:yellow");
success = true;
}
/* let the source know whether the string was successfully
* transferred and used */
event.setDropCompleted(success);
event.consume();
}
});
}
}
image.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
/* the drag and drop gesture ended */
/* if the data was successfully moved, clear it */
if (event.getTransferMode() == TransferMode.MOVE) {
pictureOne.setOpacity(0.0);
}
event.consume();
}
});
}
到目前为止,除了setOnDragDone
部分没有将颜色更改为绿色(但我稍后会进行处理)以外,大部分拖动工作正常。
我的问题是,当我开始拖动时,无论如何都可以设置要拖动的图像的大小(而不是显示的原始图像的完整大小)。如果不是,我是否仍可以拖动图像但不显示正在拖动的图像,而只是更改目标的颜色。
答案 0 :(得分:0)
首先是一个非常快速的建议,为什么要使用五个单独的“ for”循环为同一组节点设置不同的拖动处理程序。您只能在一个for循环中完成所有操作。
for(Node target: playerGrid.getChildren()) {
if(target.getId() != null) {
target.setOnDragOver(..);
target.setOnDragEntered(..);
target.setOnDragExited(..);
target.setOnDragDropped(..);
target.setOnDragDone(..);
}
}
谈到实际问题,要调整图像大小并在拖动板上进行设置,您可以使用“快照”功能。检查以下代码,以在剪贴板中设置调整大小的图像。
double displaySize = 150;
double dragSize = 50;
ImageView pictureOne = new ImageView(new Image(ImageDragDemo.class.getResourceAsStream(imgName)));
pictureOne.setFitHeight(displaySize);
pictureOne.setFitWidth(displaySize);
pictureOne.setOnDragDetected(event -> {
Dragboard db = pictureOne.startDragAndDrop(TransferMode.ANY);
ClipboardContent content = new ClipboardContent();
// Resizing the image to required size before taking the snapshot.
pictureOne.setFitHeight(dragSize);
pictureOne.setFitWidth(dragSize);
content.putImage(pictureOne.snapshot(null,null));
// Resetting the image to initial size after taking the snapshot.
pictureOne.setFitHeight(displaySize);
pictureOne.setFitWidth(displaySize);
db.setContent(content);
event.consume();
});
如果您对还原图像大小的实现不感兴趣,则可以创建一个新的ImageView并拍摄快照。
ImageView dragImage = new ImageView(pictureOne.getImage());
dragImage.setFitHeight(dragSize);
dragImage.setFitWidth(dragSize);
content.putImage(dragImage.snapshot(null,null));
对于另一个不显示图像的问题,我认为您可以设置任何STRING内容并进行验证,而不是使用event.getDragboard()。hasImage()。像..
// Instead of content.putImage(..) use
content.putString("DRAG_IMAGE");
..
// And instead of checking using event.getDragboard().hasImage() use
event.getDragboard().hasString() && event.getDragboard().getString().equals("DRAG_IMAGE")