JavaFX:还将鼠标事件传递给模糊的节点

时间:2019-03-05 19:23:22

标签: javafx

JavaFX MouseEvent仅传递到不是鼠标透明的最顶层节点。我正在寻找一种将MouseEvent传递到多个节点(鼠标是半透明的,也许是?)的方法。

在下面的示例中,我有2个部分重叠的圆圈。顶部的圆圈侦听MOUSE_CLICKED事件以更改其颜色。底部的圆圈接收MOUSE_ENTEREDMOUSE_EXITED以更新其悬停属性,并在鼠标悬停于其上方时更改其颜色。

当顶部圆圈是鼠标透明的时,底部圆圈的行为符合预期,但是顶部圆圈不再接收MOUSE_CLICKED事件。如果顶部圆圈不是鼠标透明的,则即使鼠标停留在底部圆圈的形状内,当鼠标经过顶部圆圈时,底部圆圈也会显示MOUSE_EXITED

是否可以同时支持两种行为?

public class MainApp extends Application {
  private final Random RND = new Random();

  @Override
  public void start(Stage stage) throws Exception {

      Circle bottomCircle = new Circle(150, 150, 100, Color.BLUE);
      bottomCircle.fillProperty().bind(Bindings.when(bottomCircle.hoverProperty()).then(Color.AQUA).otherwise((Color.BLUE)));

      Circle topCircle = new Circle(200, 100, 40, randColor());
      topCircle.setOnMouseClicked((event) -> topCircle.setFill(randColor()));

      CheckBox mouseTransparencyCheckBox = new CheckBox("Top Circle Mouse Transparency");
      topCircle.mouseTransparentProperty().bind(mouseTransparencyCheckBox.selectedProperty());

      Pane pane = new Pane();
      pane.setPrefSize(300, 300);
      pane.getChildren().addAll(mouseTransparencyCheckBox, bottomCircle, topCircle);

      Scene scene = new Scene(pane);
      stage.setScene(scene);
      stage.show();
  }

  private Color randColor() {
    return Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
  }

  public static void main(String[] args) {
      launch(args);
  }
}

1 个答案:

答案 0 :(得分:1)

我通过一点数学就知道了。捕获发生在最上面的圈子的所有事件。如果事件是进入,移动或退出鼠标,请查看鼠标是否在底部圆圈内。

import java.util.Random;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.EventType;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication349 extends Application
{

    private final Random RND = new Random();
    Circle bottomCircle = new Circle(150, 150, 100, Color.BLUE);
    Circle topCircle = new Circle(200, 100, 40, randColor());

    MouseEvent enteredBottomCircle = new MouseEvent(MouseEvent.MOUSE_ENTERED, bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), MouseButton.NONE, 1, true, true, true, true, true, true, true, true, true, true, null);
    MouseEvent exitedBottomCircle = new MouseEvent(MouseEvent.MOUSE_EXITED, bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), MouseButton.NONE, 1, true, true, true, true, true, true, true, true, true, true, null);

    @Override
    public void start(Stage stage) throws Exception
    {

        bottomCircle.fillProperty().bind(Bindings.when(bottomCircle.hoverProperty()).then(Color.AQUA).otherwise((Color.BLUE)));

        topCircle.addEventHandler(EventType.ROOT, (event) -> {
            System.out.println(event.getEventType());

            if (event.getEventType() == MouseEvent.MOUSE_ENTERED || event.getEventType() == MouseEvent.MOUSE_MOVED || event.getEventType() == MouseEvent.MOUSE_EXITED) {
                MouseEvent event1 = (MouseEvent) event;

                if (Math.sqrt(Math.pow((event1.getSceneX() - bottomCircle.getCenterX()), 2) + Math.pow((event1.getSceneY() - bottomCircle.getCenterY()), 2)) < bottomCircle.getRadius()) {
                    System.out.println("entered bottom circle");
                    bottomCircle.fireEvent(enteredBottomCircle);
                }

                else {
                    System.out.println("exited bottom circle");
                    bottomCircle.fireEvent(exitedBottomCircle);
                }
            }

        });

        topCircle.setOnMouseClicked((event) -> topCircle.setFill(randColor()));

        CheckBox mouseTransparencyCheckBox = new CheckBox("Top Circle Mouse Transparency");
        topCircle.mouseTransparentProperty().bind(mouseTransparencyCheckBox.selectedProperty());

        Pane pane = new Pane();
        pane.setPrefSize(300, 300);
        pane.getChildren().addAll(mouseTransparencyCheckBox, bottomCircle, topCircle);

        Scene scene = new Scene(pane);
        stage.setScene(scene);
        stage.show();
    }

    private Color randColor()
    {
        return Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
    }

    public static void main(String[] args)
    {
        launch(args);
    }

}