当前位置: 首页 > 知识库问答 >
问题:

JavaFX拖放无法正常工作

林承悦
2023-03-14

我在网格窗格中用两个ImageView做拖放测试。我的问题是,当我完成拖放并将目标imageview移动到源imageview并释放鼠标时,我错误地以显示“img2”中的图片而不是“img1”中的图片结束。当我注释掉“setOnDragExited”方法时,我最终得到了正确的图像“img1”,任何建议都将不胜感激。

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();
        }
    });
}

}

共有1个答案

蔡默
2023-03-14

这是一个可以测试的示例应用程序。在我看来,不应该将事件处理程序放在ImageViews上。将它们放在图像视图所在的节点上。

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();

    }
}
 类似资料:
  • 我在这里举了一个例子: http://jsfiddle.net/NQQL6/ 当我开始拖动链接时,购物车应该会变成绿色。当商品在购物车上拖动时,购物车应变为红色。 这有效,但前提是购物车是空的:| 如果其中有任何其他元素,似乎是在我将项目拖动到这些元素上时触发的。我如何防止这种情况发生? 我尝试将事件侦听器移动到元素并检查是的子级还是孙子级,但即使项目在购物车区域内,似乎也会在上随机触发,因此我的

  • 问题内容: 我仍然一遍又一遍地收到此错误:。我已经在Internet上搜索了一个解决方案,但没有任何效果,肯定是一个小细节,因为我不熟悉JAvaFX,这是我的第一个HelloWorld应用程序。无论如何,这是我正在使用的代码: sample.fxml: 还有 SampleController.java 任何帮助,将不胜感激。 问题答案: 找到了问题。它是ActionEvent类,在import部分

  • 问题内容: 我仍然一遍又一遍地收到此错误:。我已经在Internet上搜索了一个解决方案,但没有任何效果,肯定是一个小细节,因为我不熟悉JAvaFX,这是我的第一个HelloWorld应用程序。无论如何,这是我正在使用的代码: sample.fxml: 还有 SampleController.java 任何帮助,将不胜感激。 问题答案: 找到了问题。它是ActionEvent类,在import部分

  • testFX。java: testFXController.java: 测验fxml: 当我运行testFX. java时,系统打印: 这是教授的代码,我似乎无法运行它。我意识到主要问题在代码

  • 我正在尝试一个简单的Java FX程序,它可以创建一个窗口,我所需要的只是增加读取已删除文件的能力。我得到了以下代码片段,它不会抛出任何错误,但也不允许我删除任何内容。当我试图删除文件时,它会显示一个红色光标(不允许使用windows光标) 我使用的是Windows 8机器和JDK 8.0_60版。不确定问题出在哪里。代码有问题吗?我错过什么了吗? 我试过的- 已尝试更改传输模式 尝试检查文件权限

  • 我已经在我的游戏中实现了拖放功能,但到目前为止,我只能“拖放”到硬编码的位置。如图所示: 我想要的是: 当船舶被丢弃时,它的x、y值(相对于GridPane)被保存,或者 飞船掉落到的细胞被保存。 我的setOnDragDropped事件在此处处理: 我觉得这应该是一个简单的鼠标悬停事件或类似的事情,但我不知道该怎么做。 编辑:下面类的完整代码: }