JavaFX: доставлять события мыши на скрытые узлы тоже - PullRequest
2 голосов
/ 05 марта 2019

JavaFX MouseEvent доставляется только на самый верхний узел, который не прозрачен для мыши.Я ищу способ доставки MouseEvent на несколько узлов (мышь может быть полупрозрачной?).

В приведенном ниже примере у меня есть 2 частично перекрывающихся круга.Верхний круг прослушивает MOUSE_CLICKED событий, чтобы изменить его цвет.Нижний круг получает MOUSE_ENTERED и MOUSE_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 Ответ

1 голос
/ 06 марта 2019

Я понял это с помощью небольшой математики. Поймай все события, которые происходят на верхнем круге. Если в качестве события указана мышь, она перемещена или завершена, проверьте, находится ли мышь внутри нижнего круга.

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);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...