Как запустить событие мыши программно в JavaFX?
Следующий код показывает две панели, желтую и синюю, где синий является дочерним по отношению к желтому.
Если я щелкну в центре синей панели, событие мыши обрабатывается обеими панелями.
Как симулировать такое же поведение программно?
вFire event
Кнопка Я пытался сделать это, но не смог: сгенерированное событие оказалось обработанным только желтой панелью.
Можно ли опубликовать событие так, чтобы оно обрабатывалось всеми дочерними элементами, как если бы оно происходило с «нативными» событиями?
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class FireMouseEventProgrammatically extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
BorderPane root = new BorderPane();
AnchorPane yellowPane = new AnchorPane();
yellowPane.setBackground(new Background(new BackgroundFill(Color.YELLOW, CornerRadii.EMPTY, Insets.EMPTY)));
yellowPane.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.print("yellowPane clicked ");
printMouseEvent(event);
System.out.println("");
}
});
root.setCenter(yellowPane);
Pane bluePane = new Pane();
bluePane.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
bluePane.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
System.out.print("bluePane clicked ");
printMouseEvent(event);
System.out.println("");
}
});
AnchorPane.setLeftAnchor(bluePane, 200.);
AnchorPane.setRightAnchor(bluePane, 200.);
AnchorPane.setTopAnchor(bluePane, 200.);
AnchorPane.setBottomAnchor(bluePane, 200.);
yellowPane.getChildren().add(bluePane);
FlowPane buttonPane = new FlowPane();
buttonPane.setHgap(5);
buttonPane.setPadding(new Insets(5, 5, 5, 5));
root.setBottom(buttonPane);
Button fireEventButton = new Button();
fireEventButton.setText("Fire event");
fireEventButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
double blueX = bluePane.getWidth()/2;
double blueY = bluePane.getHeight()/2;
Point2D screenCoords = bluePane.localToScreen(blueX, blueY);
Point2D sceneCoords = bluePane.localToScene(blueX, blueY);
Event.fireEvent(yellowPane, new MouseEvent(MouseEvent.MOUSE_CLICKED,
sceneCoords.getX(), sceneCoords.getY(), screenCoords.getX(), screenCoords.getY(), MouseButton.PRIMARY, 1,
true, true, true, true, true, true, true, true, true, true, null));
}
});
buttonPane.getChildren().add(fireEventButton);
Scene scene = new Scene(root, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private void printMouseEvent(MouseEvent event) {
System.out.print(String.format("x = %f, y = %f, xScreen = %f, yScreen = %f", event.getX(), event.getY(), event.getScreenX(), event.getScreenY()));
}
public static void main(String[] args) {
FireMouseEventProgrammatically.launch(args);
}
}
ОБНОВИТЬ
Я не могу упомянуть дочерний узел явно, потому что в общем случае это может быть множество детей.
Как я узнаю, на какую цель?
Я хотел бы передать координаты и позволить системе автоматически определять цели.