我正在尝试创建一个基本上是一堆可交互形状的JavaFX控件。这就是我到目前为止所做的:
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class ScenarioViewer extends Group {
// I want 1mm == 1px so scale everything so that 0.001 == 1px
private static final int DEFAULT_SCALE = 1000;
private static final int DEFAULT_SENSITIVITY = 100;
private double sensitivity;
private Rectangle testRect;
public ScenarioViewer() {
sensitivity = DEFAULT_SENSITIVITY;
testRect = new Rectangle(0.0, 0.0, 0.005, 0.01);
testRect.setStroke(Color.BLACK);
testRect.setFill(null);
testRect.setStrokeWidth(0.001);
getChildren().add(testRect);
setupScale();
setupEventHandlers();
}
private void scale(double change) {
setScaleX(getScaleX() + change);
setScaleY(getScaleY() + change);
}
private void translate(double x, double y) {
setTranslateX(getTranslateX() + x);
setTranslateY(getTranslateY() + y);
}
private void setupScale() {
setScaleX(DEFAULT_SCALE);
setScaleY(DEFAULT_SCALE);
}
private EventHandler<ScrollEvent> onScroll = new EventHandler<ScrollEvent>() {
public void handle(ScrollEvent event) {
scale(event.getDeltaY() * sensitivity);
}
};
private EventHandler<MouseEvent> onDrag = new EventHandler<MouseEvent>() {
public void handle(MouseEvent event) {
if(event.isPrimaryButtonDown()) {
translate(event.getX() * sensitivity,
event.getY() * sensitivity);
}
}
};
private void setupEventHandlers() {
addEventHandler(ScrollEvent.SCROLL, onScroll);
addEventHandler(MouseEvent.MOUSE_DRAGGED, onDrag);
}
}
上述问题是只有当鼠标位于矩形上方时才会触发事件,更具体地说,只有矩形边缘未填充时才会触发事件。我希望相反,只有当鼠标不在形状上时才触发事件,以便可以为每个形状注册特定的事件处理程序。
为什么会这样?
我认为这是因为我的控件扩展了Group
,以及文档中的相关行:
应用于组的任何转换,效果或状态都将应用于 该群体的所有孩子。这样的变换和效果不会 包含在此组的布局边界中,但是如果转换和 效果直接设定在本集团的子女身上 包含在本集团的布局范围内。
是否有更合适的课程要扩展?
更新
我已将基类更改为Region
,这会使事件正确触发,但现在缩放和翻译不会像以前一样工作。我必须迭代所有内容并缩放/翻译每个单独的形状?为什么在getScaleX/Y
和setTranslateX/Y
之间调用Region
和Group
的行为有所不同?
答案 0 :(得分:1)
在您的论坛上,拨打setPickOnBounds(true)
,这将允许该小组拦截其范围内的任何鼠标/触摸/输入事件。
特定事件处理程序可以注册到每个形状。
只需调用shape.setOnMouseClicked(eventHandler)
等(您也可以在封闭组中使用此类设置程序来处理组级别的事件)。如果您不希望它们冒泡到封闭组,您可以使用事件处理程序中的事件,类似地,如果您不希望事件到达子组,则可以向父组添加过滤器。
如果您查看Oracle tutorials on JavaFX event handling,可能会有所帮助。