java - 在 JavaFX 中添加第二个事件处理程序后,拖动表现很奇怪

标签 java javafx

伙计们!我的 JavaFX 应用程序遇到问题。可以将图像拖动并放置在整个 Pane 上的任何位置。这工作得非常好,直到我添加了第二个事件处理程序。我添加了第二个事件处理程序来处理删除。右键单击图像会弹出一个菜单,其中包含删除选项。一旦我添加了这个,拖动就停止正常工作。虽然它仍然可以工作,但鼠标不再位于图像上。一旦你开始拖动,图像就会像 300 px 一样上下跳动?我仍然可以拖动,但我没有在图像顶部拖动。

我知道这个解释不清楚,如果有人想要的话,我可以轻松上传一张 gif 来说明会发生什么。代码如下:

@FXML
    private void handleImageButton() 
    {
        System.out.println("Image Clicked");
        closeMenus(6);

        //contains the image path or image URL
        String picURL = imageURL.getText();

        if (!picURL.equals(""))
        {
            Image image = new Image(new File(picURL).toURI().toString());
            ImageView iv = new ImageView();
            iv.setImage(image);
            iv.setCursor(Cursor.MOVE);
            iv.setOnMousePressed(imageOnMousePressedEventHandler);
            iv.setOnMouseDragged(imageOnMouseDraggedEventHandler);
            workspace.getChildren().add(iv);

            final ContextMenu contextMenu = new ContextMenu();
            MenuItem delete = new MenuItem("Delete");
            contextMenu.getItems().addAll(delete);


            iv.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent e){
                    if (e.isSecondaryButtonDown()){
                        contextMenu.show(workspace, e.getScreenX(), e.getScreenY());
                        delete.setOnAction(new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event){
                                workspace.getChildren().remove(iv);
                            }
                        });
                    } //end if
                }
            });

        }
    }

    EventHandler<MouseEvent> imageOnMousePressedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {
                if (ImageTools.isVisible())
                {
                    originalX = t.getSceneX();
                    originalY = t.getSceneY();
                    newX = ((ImageView)(t.getSource())).getTranslateX();
                    newY = ((ImageView)(t.getSource())).getTranslateY();

                    System.out.println("(" + newX + ", " + newY + ")");
                }
            }
        };

        EventHandler<MouseEvent> imageOnMouseDraggedEventHandler = 
            new EventHandler<MouseEvent>() {

            @Override
            public void handle(MouseEvent t) {
                if (ImageTools.isVisible())
                {
                    double offsetX = t.getSceneX() - originalX;
                    double offsetY = t.getSceneY() - originalY;
                    double newTranslateX = newX + offsetX;
                    double newTranslateY = newY + offsetY;

                    ((ImageView)(t.getSource())).setTranslateX(newTranslateX);
                    ((ImageView)(t.getSource())).setTranslateY(newTranslateY);

                    System.out.println("(" + newTranslateX + ", " + newTranslateY + ")");
                }
            }
        };

最佳答案

问题是您正在覆盖鼠标监听器:

  1. iv.setOnMousePressed(imageOnMousePressedEventHandler);
  2. iv.setOnMouseDragged(imageOnMouseDraggedEventHandler);
  3. iv.setOnMousePressed(new EventHandler() {});

setOnXYZ 是属性的 setter,仅包含一个监听器,因此您可以在步骤 1 和 3 中有效地覆盖监听器。

使用Node.addEventHandler()为同一EventType添加多个处理程序,或者在这种情况下我建议使用setOnContextMenuRequested显示上下文菜单,因为它更方便且独立于系统。

关于java - 在 JavaFX 中添加第二个事件处理程序后,拖动表现很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26990386/

相关文章:

Java:Netbeans 中的 JLayeredPane

java - 使用 rmi 进行远程 jmx 调用时的 NameNotFound

java - 应用程序启动方法 java.lang.reflect.InvocationTargetException 中的异常

java - 如何在 Eclipse 和 M2E 的 Maven pom.xml 文件中定义类路径条目的访问规则?

java - 带有 spring bean 的 MDB 不会从另一个包 Autowiring bean

java - 在网络应用程序(war)中,我有一个配置文本文件。如何阻止网络访问呢?

java - 如何解决雅虎财经API的临时移动错误

java - 如何从网络服务器动态加载 FXML?

java - 在运行的 Java 应用程序中更改 CSS 样式的方法

java - javafx webview/webengine 上的自定义上下文菜单