Javafx 可检索的拖放错误

Posted

技术标签:

【中文标题】Javafx 可检索的拖放错误【英文标题】:Javafx retrievable drag and drop bug 【发布时间】:2017-12-23 18:32:30 【问题描述】:

我正在创建一个具有拖放功能的 javafx 应用程序。我需要能够从一个窗格拖放到下一个窗格。删除后,所有已删除的节点都需要可访问。拖放工作顺利。但是,我遇到了一个问题,即在删除后并非所有节点都可以访问。我会拖动一个节点并单击它,有时它会响应,但有时当我单击它时,随机节点将不再显示功能。关于哪些节点停止工作以及哪些节点一直工作,没有明显的模式(我可以看到)。如果有人对为什么这可能是一个问题或如何解决它有任何想法,我们将不胜感激。几年前我到处寻找,只发现一个类似的问题,但包含他们解决方案的页面已被删除。

我将简要解释我如何设置我的代码结构。 我拖动的节点扩展了 StackPane,并将这些节点从 VBox 中的 ImageView 拖动到中心窗格上。但是,这两个都是扩展 BorderPane 的 Main 布局的子级,我称之为 MainEntrance。 在我的节点类中,我有 onMousePressed 和 onMouseDragged 功能以及 onContextMenuRequested 功能。在 MainEntrance 类中,我还具有拖动功能,当一个对象第一次从另一个子 VBox 拖动到子 Pane 上时处理。

以下是相关的类/方法:

VBox 类:(从中拖动节点)

ImageView iV= new ImageView(image);
    iV.setId("image");
    iV.setOnDragDetected(new EventHandler<MouseEvent>() 
        @Override
        public void handle(MouseEvent event) 
            dragAndDrop(iV, iV.getId(), event);
        
    );

我拖了三个 ImageViews,这些 ImageViews 是 VBox 的子项。

主入口: 在这个类中,我有一个方法可以将我的拖动事件注册到我的窗格中: PView 是我对 Pane 的类扩展

public void registerOnDragDropped(PView pView)


    pView.setOnDragOver(new EventHandler<DragEvent>() 
        @Override
        public void handle(DragEvent event) 
            event.acceptTransferModes(TransferMode.ANY);

            System.out.println("drag over registered");

        
    );


    pView.setOnDragDropped(new EventHandler<DragEvent>() 
        @Override
        public void handle(DragEvent event) 

            Dragboard db = event.getDragboard();
            final String id = db.getString();

            double mousePosY = event.getY();
            double mousePosX = event.getX();
            deviceCounter += 1;

            pView.createBoardView(id, deviceCounter, mousePosX, mousePosY);

            event.setDropCompleted(true);

        
    );

    pView.setOnDragExited(new EventHandler<DragEvent>() 
        @Override
        public void handle(DragEvent event) 
            event.acceptTransferModes(TransferMode.ANY);
            //computerView.setEffect(null);

            event.consume();
        
    );



注意:此方法在我的 MainEntrance 类 (BorderPane) 中。在这个类中,我初始化 MainEntrance 的所有其他子节点。

节点:(可拖动节点扩展 StackPane) 我的节点处理程序位于我称为 makeDraggable() 的方法中

public void makeDraggable(Node node) 
    this.setOnMousePressed(new EventHandler<MouseEvent>() 
        @Override
        public void handle(MouseEvent event) 

            node.getScene().setCursor(Cursor.MOVE);
            System.out.println("makeDraggable mouse pressed");
        
    );

    node.setOnMouseReleased(new EventHandler<MouseEvent>() 
        @Override
        public void handle(MouseEvent event) 
            node.getScene().setCursor(Cursor.DEFAULT);

        
    );

    node.setOnMouseDragged(new EventHandler<MouseEvent>() 
        @Override
        public void handle(MouseEvent event) 

            node.setTranslateX(node.getTranslateX() + event.getX() - 35);
            node.setTranslateY(node.getTranslateY() + event.getY() - 35);

            event.consume();

            node.toFront();

        
    );

如果需要任何其他信息,请告诉我。提前谢谢!

【问题讨论】:

我是对的,您将图像从一个窗格拖到另一个窗格吗?你如何处理父开关?在将拖动的节点添加到新的父节点之前,您是否将其从旧父节点中删除? 我不需要。我在左侧有一个图标菜单,然后拖动我选择的图标。当它被拖到右窗格时,它会创建一个新的不同节点。 哦,这是个好方法。不幸的是,没有其他想法,除非您准备一个 SSCCE,这似乎在这里具有挑战性 【参考方案1】:

我已经找到了解决这个问题的方法。

问题在于我放置在节点上的附件的呈现顺序。因此,当我将节点拖到屏幕上时,我有另一个节点(放置在窗格上的一条线)将屏幕中心绑定到节点。我最初并不认为这是问题所在,所以我什至没有包括那个类或 sn-p。然而,在玩了它之后,我意识到这确实是问题所在。我必须将该行添加到渲染顺序的顶部。这可以通过以下方式在任何允许您创建新节点的方法中完成:

Pane line = new Pane();
//add whatever code binds your line to desired places
getChildren.add(0, line); 
//add the other node as child

【讨论】:

以上是关于Javafx 可检索的拖放错误的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX - 拖放 TableCell

Swift 中的拖放 - 注册拖动类型的问题?

jQuery拖放 - 检查droppable之外的拖放

如何在 mousedown 元素之外捕获 mouseup 事件? (即正确的拖放?)

可拖动 div 内的图像在拖动时停止了我的拖放

如何使用angularJS突出显示可拖动元素下的拖放区?