Как узнать владельца обработчика входных событий в Piccolo2D?
Не вижу getSource()
метод в PInputEvent
учебный класс.
Я хочу получить ссылку на объект, к которому был добавлен обработчик.
ОБНОВИТЬ
В следующем примере созданы три концентрических круга. Каждый больший круг владеет меньшим. Обработчик щелчка мыши прикреплен к circle2
, Поскольку этот круг владеет circle3
, обработчик срабатывает при нажатии обоих circle2
а также circle3
, но нет 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 ответ
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));