JavaFX形状集合

时间:2014-12-17 15:13:06

标签: events javafx

我正在尝试创建一个基本上是一堆可交互形状的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/YsetTranslateX/Y之间调用RegionGroup的行为有所不同?

1 个答案:

答案 0 :(得分:1)

在您的论坛上,拨打setPickOnBounds(true),这将允许该小组拦截其范围内的任何鼠标/触摸/输入事件。

  

特定事件处理程序可以注册到每个形状。

只需调用shape.setOnMouseClicked(eventHandler)等(您也可以在封闭组中使用此类设置程序来处理组级别的事件)。如果您不希望它们冒泡到封闭组,您可以使用事件处理程序中的事件,类似地,如果您不希望事件到达子组,则可以向父组添加过滤器。

如果您查看Oracle tutorials on JavaFX event handling,可能会有所帮助。