JavaFX拖放无法正常工作 [英] JavaFX drag and drop not working correctly
问题描述
我正在使用网格窗格中的两个Imageview进行拖放测试。我的问题是,当我完成拖放并将目标imageview移动到源imageview并释放鼠标时,我错误地结束了它显示来自img2的图片而不是来自img1的图片。当我注释掉setOnDragExited方法时,我最终得到了正确的图像img1。任何建议都将受到赞赏。
Im doing a drag and drop test with two Imageviews in a gridpane. My problem is that when i complete the drag and drop and move target imageview to source imageview and release the mouse i wrongly end up with it showing the picture from "img2" and not the picture from "img1". When i comment out the "setOnDragExited" method i end up with the correct image "img1" Any suggestions would be appreciated.
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Test extends Application
{
Image img1 = new Image("/graphics/hvid/hvidBonde.png");
Image hvidTom = new Image("/graphics/hvid/hvidTom.png");
Image sortTom = new Image("/graphics/sort/sortTom.png");
ImageView source = new ImageView(img1);
Image img2 = new Image("/graphics/sort/sortBonde.png");
ImageView target = new ImageView(img2);
GridPane root = new GridPane();
@Override
public void start(Stage primaryStage) throws Exception
{
root.add(source, 1, 1);
root.add(target, 2, 2);
Scene scene = new Scene(root, 800, 800, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
source.setOnDragDetected(new EventHandler<MouseEvent>() {
public void handle(MouseEvent event)
{
Dragboard db = source.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putString(source.toString());
db.setContent(content);
event.consume();
}
});
target.setOnDragOver(new EventHandler<DragEvent>() {
public void handle(DragEvent event) {
if (event.getGestureSource() != target &&
event.getDragboard().hasString())
{
event.acceptTransferModes(TransferMode.MOVE);
}
event.consume();
}
});
target.setOnDragEntered(new EventHandler<DragEvent>() {
public void handle(DragEvent event)
{
if (event.getGestureSource() != target &&
event.getDragboard().hasString())
{
target.setImage(source.getImage());
}
event.consume();
}
});
target.setOnDragExited(new EventHandler<DragEvent>()
{
public void handle(DragEvent event)
{
target.setImage(img2);
event.consume();
}
});
target.setOnDragDropped(new EventHandler<DragEvent>() {
public void handle(DragEvent event)
{
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasString())
{
target.setImage(source.getImage());
success = true;
}
event.setDropCompleted(success);
event.consume();
}
});
source.setOnDragDone(new EventHandler<DragEvent>() {
public void handle(DragEvent event)
{
if (event.getTransferMode() == TransferMode.MOVE)
{
source.setImage(hvidTom);
}
event.consume();
}
});
}
}
推荐答案
以下是您可以测试的示例应用。在我看来,你不应该把你的事件处理程序放在 ImageViews
上。将它们放在 ImageViews
所在的节点上。
Here is a sample app you can test with. In my opinion, you should not put your event handlers on the ImageViews
. Put them on the nodes the ImageViews
are in.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.DragEvent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Test extends Application
{
Image img1 = new Image("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
@Override
public void start(Stage primaryStage) throws Exception
{
ImageView source = new ImageView();
ImageView target = new ImageView();
source.setImage(img1);
StackPane stackPaneLeft = new StackPane(source);
stackPaneLeft.setStyle("-fx-background-color: yellow");
stackPaneLeft.setPrefSize(400, 800);
stackPaneLeft.setOnDragDetected((MouseEvent event)
-> {
Dragboard db = source.startDragAndDrop(TransferMode.MOVE);
ClipboardContent content = new ClipboardContent();
content.putImage(source.getImage());
db.setContent(content);
event.consume();
});
stackPaneLeft.setOnDragDone((DragEvent event) -> {
if (event.getTransferMode() == TransferMode.MOVE) {
source.setImage(null);
}
event.consume();
});
StackPane stackPaneRight = new StackPane(target);
stackPaneRight.setStyle("-fx-background-color: blue");
stackPaneRight.setPrefSize(400, 800);
stackPaneRight.setOnDragOver((DragEvent event)
-> {
if (event.getGestureSource() != target
&& event.getDragboard().hasImage()) {
event.acceptTransferModes(TransferMode.ANY);
}
event.consume();
});
stackPaneRight.setOnDragEntered((DragEvent event)
-> {
if (event.getGestureSource() != target
&& event.getDragboard().hasImage()) {
target.setImage(source.getImage());
}
event.consume();
});
stackPaneRight.setOnDragExited((DragEvent event)
-> {
if (target.getImage() != null && !event.isDropCompleted()) {
target.setImage(null);
}
event.consume();
});
stackPaneRight.setOnDragDropped((DragEvent event)
-> {
Dragboard db = event.getDragboard();
boolean success = false;
if (db.hasImage()) {
target.setImage(source.getImage());
success = true;
}
event.setDropCompleted(success);
event.consume();
});
HBox root = new HBox(stackPaneLeft, stackPaneRight);
Scene scene = new Scene(root, 800, 800, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.setResizable(false);
primaryStage.show();
}
}
这篇关于JavaFX拖放无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!