如何知道Piccolo2D中的输入事件处理程序所有者?

时间:2013-11-05 20:35:39

标签: java graphics piccolo

我在PInputEvent课程中看不到getSource()方法。

我想引用一个对象,该处理程序已添加到。

更新

在以下示例中,创建了三个同心圆。每个较大的圆圈拥有较小的圆圈。鼠标单击处理程序已附加到circle2。由于此圈子拥有circle3,因此处理器会在点击circle2circle3时触发,但不会circle1

如果点击circle2,如何从处理程序中获取对circle3的引用?

两种测试方法都没有帮助。

package test.piccolo;

import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import edu.umd.cs.piccolo.nodes.PPath;
import edu.umd.cs.piccolox.PFrame;

public class App {

    @SuppressWarnings("serial")
    public static void main(String[] args) {

        new PFrame() {

            public void initialize() {

                PPath circle1 = PPath.createEllipse(-50, -50, 100, 100);
                circle1.setPaint(null);
                System.out.println("circle1 = " + circle1.toString());

                getCanvas().getLayer().addChild(circle1);

                PPath circle2 = PPath.createEllipse(-40, -40, 80, 80);
                circle2.setPaint(null);
                System.out.println("circle2 = " + circle2.toString());

                circle1.addChild(circle2);

                PPath circle3 = PPath.createEllipse(-30, -30, 60, 60);
                circle3.setPaint(null);
                System.out.println("circle3 = " + circle3.toString());

                circle2.addChild(circle3);

                circle2.addInputEventListener(new PBasicInputEventHandler() {
                    @Override
                    public void mouseClicked(PInputEvent event) {

                        Object o;

                        o = event.getSourceSwingEvent().getSource().toString();
                        System.out.println("event.getSourceSwingEvent().getSource() = " + o);

                        o = event.getComponent().toString();
                        System.out.println("event.getComponent() = " + o);

                        o = event.getPickedNode().toString();
                        System.out.println("event.getPickedNode() = " + o);

                    }
                });
            };





        };
    }
}

更新2

我的要求是将一些最顶层的虚拟节点视为其子节点的包装器。我想将处理程序附加到父级并跟踪下面的所有事件。同时,父母可以成为一个整体更复杂的场景的孩子。所以,我需要在某个中级水平捕捉事件。

1 个答案:

答案 0 :(得分:1)

PInputEvent.getSourceSwingEvent()返回基础摆动事件 - InputEventgetSource()应该为您提供来源,即:

event.getSourceSwingEvent().getSource()

编辑:

似乎event.getSourceSwingEvent().getSource()始终是画布。事件实际上源于画布,这是有道理的。

event.getPickedNode()是实际挑选的节点。它可能是具有已注册侦听器的节​​点的子节点,例如已发布的示例代码中的circle3

我不确定找到注册侦听器的节​​点的场景和原因是什么。在大多数情况下,所需的输出是拾取的节点。要找到您要查找的内容,您可以使用PInputEventListener的自定义指定扩展名,该扩展名可以包含对注册它的节点的引用。根据情况,这可能是一种矫枉过正。例如:

public static class MyEventHandler extends PBasicInputEventHandler {
    private PNode node;
    public MyEventHandler(PNode node) {
        this.node = node;
    }

    public PNode getNode() {
        return this.node;
    }
}

另一种令人讨厌的方法是遍历选择路径中的一堆对象或节点的层次结构,以找到具有此侦听器的节​​点。例如,遍历节点的层次结构(类似地,也可以枚举event.getPath().getNodeStackReference()中的节点):

public static PNode getRealEventSource(PInputEvent event, PInputEventListener listener) {
    PNode node = event.getPickedNode();
    while(node != null){
        EventListenerList listeners = node.getListenerList();
        if (listeners != null) {
            if (Arrays.asList(listeners.getListenerList()).contains(listener)) {
                return node;
            }
        }
        node = node.getParent();
    }

    return null;
}

然后,在mouseClicked()方法中调用它:

System.out.println("The real source:" + getRealEventSource(event, this));