我在PInputEvent
类中看到没有getSource()
方法。
我想获取对对象的引用,该处理程序已添加到其中。
更新
在下面的示例中,创建了三个同心圆。每个较大的圈子拥有较小的圈子。鼠标单击处理程序附加到circle2
。由于这个圆圈拥有circle3
,处理程序在circle2
和circle3
点击时触发,但不是circle1
。
如果单击circle3
,如何从处理程序中获取对circle2
的引用?
两种经过测试的方法都没有帮助。
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
我的要求是将一些最顶层的虚拟节点视为其子节点的包装器。我想将处理程序附加到父级并跟踪其下的所有事件。同时,父母可以是整个一些更复杂的场景的孩子。所以,我需要在某个中级水平上捕捉事件。
PInputEvent.getSourceSwingEvent() 返回底层的摆动事件 - InputEvent,从该getSource()
应该给你源代码,即:
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));