问题描述
我正在尝试使用JavaFX中的事件处理来做一些滑雪以外的事情.我需要能够确定手动触发事件后是否消耗了事件.
I'm trying to do some off-piste stuff with event handling in JavaFX. I need to be able to determine if an event was consumed after I manually fire it.
在下面的示例中,正确接收到合成鼠标事件,但是调用consump()不会更新该事件.
In the following example a synthetic mouse event is correctly received, however calling consume() does not update the event.
我已对此进行调试,发现JavaFX实际上创建了一个新的事件实例,因此原始实例未更改
I've debugged this and found JavaFX actually creates a new event instance so the original is unchanged
public class EventManipulation extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button();
button.setOnMouseDragged(event -> {
System.out.println("dragged");
event.consume();
});
primaryStage.setScene(new Scene(new HBox(button), 400, 300));
primaryStage.show();
MouseEvent event = new MouseEvent(MouseEvent.MOUSE_DRAGGED, 0, 0, 0, 0, MouseButton.PRIMARY, 1, false, false,
false, false, false, false, false, false, false, false, null);
Event.fireEvent(button, event);
System.out.println(event.isConsumed()); // <== prints false
}
}
我发现了EventDispatchChain,但是我不知道如何使它起作用.该按钮可以生成事件分发链,但需要一个开始....以下失败,因为我不知道如何创建初始尾巴.
I've discovered EventDispatchChain, however I cannot figure out how to get this to work. The button can generate a event dispatch chain but requires one to start off with... The following fails because I don't know how to create an initial tail.
Event result = button.buildEventDispatchChain(null).dispatchEvent(event);
System.out.println(result.isConsumed());
推荐答案
为此,我唯一的解决方案是实施 EventDispatchChain 接口.相当小的接口如下.不幸的是,javafx使用的内置版本位于不可访问的程序包中-com.sun.javafx.event.EventDispatchChainImpl
The only solution I have for this is to implement the EventDispatchChain interface. A fairly minimal interface is as follows. Unfortunately the built in version used by javafx is in a non-accessible package - com.sun.javafx.event.EventDispatchChainImpl
private class SimpleChain implements EventDispatchChain {
private Deque<EventDispatcher> dispatchers = new LinkedList<>();
@Override
public EventDispatchChain append(EventDispatcher eventDispatcher) {
dispatchers.addLast(eventDispatcher);
return this;
}
@Override
public EventDispatchChain prepend(EventDispatcher eventDispatcher) {
dispatchers.addFirst(eventDispatcher);
return this;
}
@Override
public Event dispatchEvent(Event event) {
if (dispatchers.peekFirst() != null) {
Event result = dispatchers.removeFirst().dispatchEvent(event, this);
if (result != null) {
return result;
} else {
event.consume();
return event;
}
} else {
return event;
}
}
}
然后像这样使用时会产生预期的结果
This then produces expected result when used like this
Event result = button.buildEventDispatchChain(new SimpleChain()).dispatchEvent(event);
System.out.println(result.isConsumed());
这篇关于确定是否在JavaFX中使用了事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!