下面列出了javafx.scene.Node#isMouseTransparent ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Determines the closest node that resides in the x,y scene position, if any.
* <br>
* Obtained from: http://fxexperience.com/2016/01/node-picking-in-javafx/
*
* @param node parent node
* @param sceneX x-coordinate of picking point
* @param sceneY y-coordinate of picking point
*
* @return topmost node containing (sceneX, sceneY) point
*/
public static Node pick(Node node, double sceneX, double sceneY) {
Point2D p = node.sceneToLocal(sceneX, sceneY, true /* rootScene */);
// check if the given node has the point inside it, or else we drop out
if (!node.contains(p)) {
return null;
}
// at this point we know that _at least_ the given node is a valid
// answer to the given point, so we will return that if we don't find
// a better child option
if (node instanceof Parent) {
// we iterate through all children in reverse order, and stop when we find a match.
// We do this as we know the elements at the end of the list have a higher
// z-order, and are therefore the better match, compared to children that
// might also intersect (but that would be underneath the element).
Node bestMatchingChild = null;
List<Node> children = ((Parent) node).getChildrenUnmodifiable();
for (int i = children.size() - 1; i >= 0; i--) {
Node child = children.get(i);
p = child.sceneToLocal(sceneX, sceneY, true /* rootScene */);
if (child.isVisible() && !child.isMouseTransparent() && child.contains(p)) {
bestMatchingChild = child;
break;
}
}
if (bestMatchingChild != null) {
return pick(bestMatchingChild, sceneX, sceneY);
}
}
return node;
}
public static boolean isMouseTransparent(final Node node) {
if (node == null) {
return false;
} else {
return node.isMouseTransparent() || isMouseTransparent(node.getParent());
}
}
public SVRemoteNodeAdapter(final Node node, final boolean collapseControls, final boolean collapseContentControls, final boolean fillChildren, final SVRemoteNodeAdapter parent) {
super(ConnectorUtils.nodeClass(node), node.getClass().getName());
boolean mustBeExpanded = !(node instanceof Control) || !collapseControls;
if (!mustBeExpanded && !collapseContentControls) {
mustBeExpanded = node instanceof TabPane || node instanceof SplitPane || node instanceof ScrollPane || node instanceof Accordion || node instanceof TitledPane;
}
setExpanded(mustBeExpanded);
this.id = node.getId();
this.nodeId = ConnectorUtils.getNodeUniqueID(node);
this.focused = node.isFocused();
if (node.getParent() != null && parent == null) {
this.parent = new SVRemoteNodeAdapter(node.getParent(), collapseControls, collapseContentControls, false, null);
} else if (parent != null) {
this.parent = parent;
}
/**
* Check visibility and mouse transparency after calculating the parent
*/
this.mouseTransparent = node.isMouseTransparent() || (this.parent != null && this.parent.isMouseTransparent());
this.visible = node.isVisible() && (this.parent == null || this.parent.isVisible());
/**
* TODO This should be improved
*/
if (fillChildren) {
nodes = ChildrenGetter.getChildren(node)
.stream()
.map(childNode -> new SVRemoteNodeAdapter(childNode, collapseControls, collapseContentControls, true, this))
.collect(Collectors.toList());
}
}
/**
* Performs picking on the scene graph beginning at the specified root node
* and processing its transitive children.
*
* @param sceneX
* The x-coordinate of the position to pick nodes at, interpreted
* in scene coordinate space.
* @param sceneY
* The y-coordinate of the position to pick nodes at, interpreted
* in scene coordinate space.
* @param root
* The root node at which to start with picking
* @return A list of {@link Node}s which contain the the given coordinate.
*/
public static List<Node> getNodesAt(Node root, double sceneX,
double sceneY) {
List<Node> picked = new ArrayList<>();
// start with given root node
List<Node> nodes = new ArrayList<>();
nodes.add(root);
while (!nodes.isEmpty()) {
Node current = nodes.remove(0);
// transform to local coordinates
Point2D pLocal = current.sceneToLocal(sceneX, sceneY);
// check if bounds contains (necessary to find children in mouse
// transparent regions)
if (!current.isMouseTransparent()
&& current.getBoundsInLocal().contains(pLocal)) {
// check precisely
if (current.contains(pLocal)) {
picked.add(0, current);
}
// test all children, too
if (current instanceof Parent) {
nodes.addAll(0,
((Parent) current).getChildrenUnmodifiable());
}
}
}
return picked;
}
/**
* Traverse the scene graph for all open stages and pick an event target for a dock event based on
* the location. Once the event target is chosen run the event task with the target and the
* previous target of the last dock event if one is cached. If an event target is not found fire
* the explicit dock event on the stage root if one is provided.
*
* @param location The location of the dock event in screen coordinates.
* @param eventTask The event task to be run when the event target is found.
* @param explicit The explicit event to be fired on the stage root when no event target is found.
*/
private void pickEventTarget(Point2D location, EventTask eventTask, Event explicit) {
// RFE for public scene graph traversal API filed but closed:
// https://bugs.openjdk.java.net/browse/JDK-8133331
List<DockPane> dockPanes = DockPane.dockPanes;
// fire the dock over event for the active stages
for (DockPane dockPane : dockPanes) {
Window window = dockPane.getScene().getWindow();
if (!(window instanceof Stage)) continue;
Stage targetStage = (Stage) window;
// obviously this title bar does not need to receive its own events
// though users of this library may want to know when their
// dock node is being dragged by subclassing it or attaching
// an event listener in which case a new event can be defined or
// this continue behavior can be removed
if (targetStage == this.dockNode.getStage())
continue;
eventTask.reset();
Node dragNode = dragNodes.get(targetStage);
Parent root = targetStage.getScene().getRoot();
Stack<Parent> stack = new Stack<Parent>();
if (root.contains(root.screenToLocal(location.getX(), location.getY()))
&& !root.isMouseTransparent()) {
stack.push(root);
}
// depth first traversal to find the deepest node or parent with no children
// that intersects the point of interest
while (!stack.isEmpty()) {
Parent parent = stack.pop();
// if this parent contains the mouse click in screen coordinates in its local bounds
// then traverse its children
boolean notFired = true;
for (Node node : parent.getChildrenUnmodifiable()) {
if (node.contains(node.screenToLocal(location.getX(), location.getY()))
&& !node.isMouseTransparent()) {
if (node instanceof Parent) {
stack.push((Parent) node);
} else {
eventTask.run(node, dragNode);
}
notFired = false;
break;
}
}
// if none of the children fired the event or there were no children
// fire it with the parent as the target to receive the event
if (notFired) {
eventTask.run(parent, dragNode);
}
}
if (explicit != null && dragNode != null && eventTask.getExecutions() < 1) {
Event.fireEvent(dragNode, explicit.copyFor(this, dragNode));
dragNodes.put(targetStage, null);
}
}
}