The following code show two panels, yellow and blue, where blue is a child of yellow.
If I click into the center of blue panel, mouse event is handled with both panels.
How to simulate the same behavior programmatically?
In the Fire event
button I tried to do this, but failed: generated event appeared to handled only by yellow pane.
Is it possible to post event so that it processed by all children as if it happen with "native" events?
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);
}
}
UPDATE
I can't mention child node explicitly, because in general case it can be numerous number of children.
How would I know which one to target?
I would like to pass coordinates and let system determine targets automatically.