如何在子项之间拖动后停止JavaFX父节点的单击

时间:2014-10-27 14:38:31

标签: javafx javafx-8

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

我想知道的是:如何阻止父级接收此点击事件?我在使用事件的左右节点上尝试了各种事件过滤器和事件处理程序,但我似乎无法找到正确的事件来阻止点击事件被发送到父母。有什么想法吗?

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 个答案:

答案 0 :(得分:9)

您不能阻止事件本身发生,但isStillSincePressed()(在MouseEvent中)可以在父(本例中的HBox)中使用来区分点击和拖动。

答案 1 :(得分:0)

我的第二反应(评论时)是:有多奇怪。我对点击的期望是基于Swing的(也可能是基于Win的,似乎记得很久以前的VB时间):当同时按下/释放的同一组件位于同一位置时,会收到一个点击。

FX语义不同,因为在实际阅读MouseEvent.MOUSE_CLICKED的文档之后结果是:

/**
 * 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).
 */

所以对你的问题的简短回答是:你不能阻止点击父母。根据您需要实现的目标,可以选择如何应对所点击的内容:

  • 根本不使用它,使用按下/释放
  • 实现你自己的同位置语义:在捕获阶段听取压力,存储位置,比较点击的位置,如果相同/接近则仅触发反应