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

如何阻止JavaFX父节点在子节点间拖动后被点击

甄胡非
2023-03-14

我有一种情况,我在JavaFX中有一个容器节点(HBox)和两个子节点。当我从左边的子节点拖到右边时,我会得到很多拖到左边节点的事件,最后当我在右边节点上释放鼠标时,我会在父节点中得到一个单击事件。下面是一些复制这种情况的代码。

我想知道的是:如何阻止家长接收此点击事件?我在使用事件的左、右节点上尝试了各种事件过滤器和事件处理程序,但似乎找不到合适的过滤器和事件处理器来防止单击事件发送到父节点。有什么想法吗?

package test;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class TestDrag extends Application
{

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        String leftHead = "Start dragging from me\n";
        String dragStarted = "Drag begun; staying simple\n";
        Label left = new Label(leftHead);

        left.setOnDragDetected(e -> {
            left.setText(leftHead + dragStarted);
            e.consume();
        });

        left.setOnMouseDragged(e -> {
            left.setText(leftHead + dragStarted + "Mouse dragged to: " + e.getSceneX() + ", " + e.getSceneY());
            e.consume();
        });

        left.setOnMouseReleased(e -> {
            left.setText(leftHead + "Mouse released\n");
            e.consume();
        });

        String rightHead = "Drag on to me\n";
        Label right = new Label(rightHead);
        right.setOnMouseClicked(e -> {
            right.setText(rightHead + "Clicked me!\n");
        });

        left.setPrefSize(400, 300);
        left.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, null, null)));
        right.setPrefSize(400, 300);
        right.setBackground(new Background(new BackgroundFill(Color.LIGHTPINK, null, null)));

        HBox hbox = new HBox(left, right);
        hbox.setOnMouseClicked(e -> {
            right.setText(rightHead + "Clicked the underlying HBox at " + System.currentTimeMillis() + "\n");
        });


        primaryStage.setScene(new Scene(hbox));
        primaryStage.show();
    }

}

共有2个答案

干永丰
2023-03-14

我的第二反应(如评论)是:好奇怪。我对clicked的期望是基于Swing的(可能也是基于Win的,隐约记得很久以前的VB时代):当两次按下/释放都在同一位置的同一个组件上时,就会收到clicked。

FX语义是不同的,因为它实际上是在阅读MouseEvent的文档之后才发现的。鼠标点击次数:

/**
 * This event occurs when mouse button has been clicked (pressed and
 * released on the same node). This event provides a button-like behavior
 * to any node. Note that even long drags can generate click event (it 
 * is delivered to the top-most node on which the mouse was both
 * pressed and released).
 */

因此,对你的问题的简短回答是:你不能阻止点击家长。根据您需要实现的具体目标,您可以选择如何应对以下问题:

  • 不要使用它,使用按下/释放的
  • 实现您自己的“在同一位置”语义:在捕获阶段聆听按下的按钮,存储位置,比较单击的位置,仅在相同/接近时触发反应
郑佐
2023-03-14

您无法阻止事件本身发生,但 isStillSincePressed()(在 MouseEvent 中)可以在父级(在本例中为 HBox)中使用,以区分单击和拖动。

 类似资料:
  • 如果我没弄错的话,树通常是一个列表,其中的元素按特定顺序排列。孩子们不在他们自己的子列表中,他们都在同一个列表中。 所以,我试图创建一个Tree类,其中包含TreeNodes(类)使用Tree类中的List。 我如何跟踪父母/孩子/叶子?如果父母“父母1”,有两个孩子“孩子A”和“孩子B”,我如何将他们联系在一起?

  • 在JavaFX中,我试图通过单击并拖动节点来移动它。如果节点不旋转,它工作得很好,但是当我旋转它时,它开始表现得很奇怪。 在45°左右,当我移动它时,它开始抖动,在60°时,它剧烈地来回抖动。在90°时,只要我开始移动节点,它就会飞离屏幕。 下面是我用来旋转和移动节点的代码。它来自连接到节点的鼠标侦听器。 编辑:这是一些示例输出,以及显示不同节点的图片。 未旋转且缓慢向左移动时的输出: 旋转时缓慢

  • 我有一个具有必要字段的窗格扩展类。它将是“大门”。 调用控制器从FXML加载节点树,并将其作为子级附加到“gate”对象 然后创建并显示一个以“gate”为根节点的新场景。 新的窗口控制器有一个对FXML根节点(“gate”的直接子节点)的引用,他所需要做的就是在其上使用.getparent()来获取“gate”。 但管他呢!它返回null!我做错了什么?我应该通过FXMLLoader设置一个不同

  • 问题内容: 在C#中,我发现了一种非常可爱的方法,该方法使您可以从指定控件中获取所有后代和所有THEIR后代。 我正在寻找JavaFX的类似方法。 我看到了我要使用的类,因为它是派生所有带有孩子的Node类的类。 到目前为止,这是我所拥有的(并且我还没有在Google上通过“ JavaFX从场景中获取所有节点”之类的搜索真正找到任何东西): 那么,如何确定N是否是父母(或从父母继承)呢?我说的对吗

  • 我想从父节点复制到子节点。我真的不确定这是如何实现的。 我的源xml 我想得到输出为 我想要XSLT1.0中的解决方案。 我想将这些节点复制到子节点 谢谢。

  • 我有一个这样的结构` ...等等,在