如果我有两个节点堆叠在一起并相互重叠,我如何使顶部的节点成为mouseTransparent(以便底部的节点能够对MouseEvents做出反应),但也让顶部的节点对一些MouseEvents做出反应,比如OnMouseEventer?
<StackPane>
<Pane onMouseEntered="#printA" onMouseClicked="#printB" />
<Pane onMouseEntered="#printC" />
</StackPane>
关于Stackoverflow有许多问题看起来类似,但几乎所有问题都可以通过setmouseTransparent(true)
或setpickonbounds(true)
解决。setmouseTransparent
在这里不起作用,从那以后顶部窗格不会打印C。setpickonbounds
使窗格在任何地方都是透明的,但透明部分不会打印C,不透明部分阻止下部窗格打印A或B。因此,即使顶部窗格完全透明或完全不透明,也不能解决我的问题。将顶部窗格的可见性设置为false也不会起作用,因为顶部窗格无法打印C。
我可以考虑的一种方法是,观察鼠标在父节点上的移动,看看鼠标指针是否落在所需节点的检测区域上。这样,您就不需要一个虚拟(透明)节点来进行检测。
所以想法如下:
<StackPane id="parent">
<Pane onMouseEntered="#printA" onMouseClicked="#printB" />
// Other nodes in the parent
</StackPane>
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());
}
}
然后,您可以简单地将鼠标处理程序添加到检测区域和中心节点。
请查看下面的工作演示:
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;
}
}
当 Puppet 运行在一个节点上,它需要知道这个节点应该应用了哪些类。 例如,如果这是一个 web 服务器节点,它可能需要包含一个 apache 类。 将类映射到节点的一种简单方法是在配置清单里声明,例如下面是一个 nodes.pp 文件的例子: node web1 { include apache } 另外,你可以使用 外部节点分类器(external node classifier,E
问题就在这里: 我目前必须打印一个a4的横向页面,其中包含当前javaFx场景的“部分”。 我必须打印的部分是BorderPane的部分,我需要打印左侧、中间和底部节点,所以打印的页面应该如下所示: 我将此作为输出(仅供参考): 感谢您的帮助/阅读,感谢您的帮助。 更新01: 这真是让人摸不着头脑... 更新02: 使用快照和imageViews进行新尝试: 我把它除以600(就像Resoluti
我正在尝试将一个矩形拖动到VBox,然后从VBox内部再次拖动它。 如果矩形被放置在目标VBox之外的任何位置,那么它应该将其位置恢复到它所属的位置:如果它是左VBox的子级,则将其重置回其中;如果它是右VBox的子级,则将其重置回右VBox内部。 第一部分工作正常,我可以将其拖到VBox并将其添加为子级。第二部分是我遇到问题的地方。 重现问题的步骤:<br>1)将左矩形拖动到右矩形的顶部(在VB
我有一个具有必要字段的窗格扩展类。它将是“大门”。 调用控制器从FXML加载节点树,并将其作为子级附加到“gate”对象 然后创建并显示一个以“gate”为根节点的新场景。 新的窗口控制器有一个对FXML根节点(“gate”的直接子节点)的引用,他所需要做的就是在其上使用.getparent()来获取“gate”。 但管他呢!它返回null!我做错了什么?我应该通过FXMLLoader设置一个不同
所以我环顾了一下网络,在stackoverflow中有几个问题是定义: 通常,内部节点是任何不是叶子的节点(没有子节点) 非叶/非末端/内部节点-至少有一个度不等于0的子节点或后代节点 据我所知,它是一个节点,而不是一片叶子。 我即将得出结论,根也是一个内部节点,但它的定义似乎有些模糊,如图所示: 二元搜索树中的“内部节点”是什么? 正如这张精彩的图片所示,内部节点是位于树根和树叶之间的节点 如果
在JavaFX中,我试图通过单击并拖动节点来移动它。如果节点不旋转,它工作得很好,但是当我旋转它时,它开始表现得很奇怪。 在45°左右,当我移动它时,它开始抖动,在60°时,它剧烈地来回抖动。在90°时,只要我开始移动节点,它就会飞离屏幕。 下面是我用来旋转和移动节点的代码。它来自连接到节点的鼠标侦听器。 编辑:这是一些示例输出,以及显示不同节点的图片。 未旋转且缓慢向左移动时的输出: 旋转时缓慢