One way I can think, is to observe the mouse movements on the parent node, to see if the mouse pointer falls on the detection zone of the desired node. This way you don't need a dummy (transparent)node for detection.
So the idea is as follows:
<StackPane id="parent">
<Pane onMouseEntered="#printA" onMouseClicked="#printB" />
// Other nodes in the parent
</StackPane>
- As usual, you will have handlers on the center node.
- Add a mouseMoved handler on the parent node to detect for mouse entering in detection zone.
Please check the below working demo :

import javafx.application.Application;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class MouseEventsDemo extends Application {
double detectionSize = 30;
@Override
public void start(Stage primaryStage) throws Exception {
Pane center = getBlock("red");
center.setOnMouseEntered(e -> System.out.println("Entered on center pane..."));
center.setOnMouseClicked(e -> System.out.println("Clicked on center pane..."));
// Simulating that the 'center' is surrounded by other nodes
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.addRow(0, getBlock("yellow"), getBlock("pink"), getBlock("orange"));
grid.addRow(1, getBlock("orange"), center, getBlock("yellow"));
grid.addRow(2, getBlock("yellow"), getBlock("pink"), getBlock("orange"));
// Adding rectangle only for zone visual purpose
Rectangle zone = new Rectangle(center.getPrefWidth() + 2 * detectionSize, center.getPrefHeight() + 2 * detectionSize);
zone.setStyle("-fx-stroke:blue;-fx-stroke-width:1px;-fx-fill:transparent;-fx-opacity:.4");
zone.setMouseTransparent(true);
StackPane parent = new StackPane(grid, zone);
VBox root = new VBox(parent);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
root.setSpacing(20);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
addDetectionHandler(parent, center);
}
private Pane getBlock(String color) {
Pane block = new Pane();
block.setStyle("-fx-background-color:" + color);
block.setMaxSize(100, 100);
block.setPrefSize(100, 100);
return block;
}
private void addDetectionHandler(StackPane parent, Pane node) {
final String key = "onDetectionZone";
parent.setOnMouseMoved(e -> {
boolean mouseEntered = (boolean) node.getProperties().computeIfAbsent(key, p -> false);
if (!mouseEntered && isOnDetectionZone(e, node)) {
node.getProperties().put(key, true);
// Perform your mouse enter operations on detection zone,.. like changing to edit mode.. or what ever
System.out.println("Entered on center pane detection zone...");
node.setStyle("-fx-background-color:green");
} else if (mouseEntered && !isOnDetectionZone(e, node)) {
node.getProperties().put(key, false);
// Perform your mouse exit operations from detection zone,.. like change back to default state from edit mode
System.out.println("Exiting from center pane detection zone...");
node.setStyle("-fx-background-color:red");
}
});
}
private boolean isOnDetectionZone(MouseEvent e, Pane node) {
Bounds b = node.localToScene(node.getBoundsInLocal());
double d = detectionSize;
Bounds detectionBounds = new BoundingBox(b.getMinX() - d, b.getMinY() - d, b.getWidth() + 2 * d, b.getHeight() + 2 * d);
return detectionBounds.contains(e.getSceneX(), e.getSceneY());
}
}
Note: You can go with a more better approach for checking if the mouse pointer falls in detection zone of the desired node :)
UPDATE : Approach#2
Looks like what you are seeking is a node which resembles a picture frame that has a hole through it :). If that is the case, the approach i can think of is to build a shape (like a frame) and place it over the desired node.
And then you can simply add mouse handlers to the detection zone and the center nodes.
Please check the below working demo:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;
public class MouseEventsDemo2 extends Application {
double detectionSize = 30;
@Override
public void start(Stage primaryStage) throws Exception {
Pane center = getBlock("red");
center.getChildren().add(new Label("Hello"));
center.setOnMouseEntered(e -> {
System.out.println("Entered on center pane...");
center.setStyle("-fx-background-color:green");
});
center.setOnMouseClicked(e -> System.out.println("Clicked on center pane..."));
// Simulating that the 'center' is surrounded by other nodes
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.addRow(0, getBlock("yellow"), getBlock("pink"), getBlock("orange"));
grid.addRow(1, getBlock("orange"), center, getBlock("yellow"));
grid.addRow(2, getBlock("yellow"), getBlock("pink"), getBlock("orange"));
StackPane parent = new StackPane(grid);
VBox root = new VBox(parent);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(20));
root.setSpacing(20);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
// Building the frame using Polyline node
Polyline zone = new Polyline();
zone.setStyle("-fx-fill:grey;-fx-opacity:.5;-fx-stroke-width:0px;");
zone.setOnMouseEntered(e -> {
System.out.println("Entered on detection zone...");
center.setStyle("-fx-background-color:green");
});
zone.setOnMouseExited(e -> {
System.out.println("Exited on detection zone...");
center.setStyle("-fx-background-color:red");
});
zone.setOnMouseClicked(e -> System.out.println("Clicked on detection zone..."));
parent.getChildren().add(zone);
parent.layoutBoundsProperty().addListener(p -> updatePolylineZone(center, zone));
center.layoutBoundsProperty().addListener(p -> updatePolylineZone(center, zone));
updatePolylineZone(center, zone);
}
/**
* Update the poly line shape to build a frame around the center node if the parent or center bounds changed.
*/
private void updatePolylineZone(Pane center, Polyline zone) {
zone.getPoints().clear();
Bounds b = center.localToParent(center.getBoundsInLocal());
double s = detectionSize;
ObservableList<Double> pts = FXCollections.observableArrayList();
// A-------------------------B
// | |
// | a---------------b |
// | | | |
// | | | |
// | | | |
// | d---------------c |
// | |
// D-------------------------C
// Outer square
pts.addAll(b.getMinX() - s, b.getMinY() - s); // A
pts.addAll(b.getMaxX() + s, b.getMinY() - s); // B
pts.addAll(b.getMaxX() + s, b.getMaxY() + s); // C
pts.addAll(b.getMinX() - s, b.getMaxY() + s); // D
// Inner Square
pts.addAll(b.getMinX() + 1, b.getMaxY() - 1); // d
pts.addAll(b.getMaxX() - 1, b.getMaxY() - 1); // c
pts.addAll(b.getMaxX() - 1, b.getMinY() + 1); // b
pts.addAll(b.getMinX() + 1, b.getMinY() + 1); // a
// Closing the loop
pts.addAll(b.getMinX() - s, b.getMinY() - s); // A
pts.addAll(b.getMinX() - s, b.getMaxY() + s); // D
pts.addAll(b.getMinX() + 1, b.getMaxY() - 1); // d
pts.addAll(b.getMinX() + 1, b.getMinY() + 1); // a
pts.addAll(b.getMinX() - s, b.getMinY() - s); // A
zone.getPoints().addAll(pts);
}
private Pane getBlock(String color) {
Pane block = new Pane();
block.setStyle("-fx-background-color:" + color);
block.setMaxSize(100, 100);
block.setPrefSize(100, 100);
return block;
}
}