【问题标题】:Determine if an event was consumed in JavaFX确定是否在 JavaFX 中使用了事件
【发布时间】:2018-03-28 15:22:03
【问题描述】:

我正在尝试用 JavaFX 中的事件处理来做一些非滑雪的事情。我需要能够在手动触发事件后确定它是否已被使用。

在以下示例中,合成鼠标事件被正确接收,但调用 consume() 不会更新事件。

我已经调试过了,发现 JavaFX 实际上创建了一个新的事件实例,所以原来的没有改变

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,但是我不知道如何让它工作。该按钮可以生成一个事件调度链,但需要一个开始......以下失败,因为我不知道如何创建初始尾部。

Event result = button.buildEventDispatchChain(null).dispatchEvent(event);
System.out.println(result.isConsumed());

【问题讨论】:

  • 您在哪个线程上触发以及在哪个线程上分派事件?也许添加 Thread.Sleep()?
  • @alex440 在 JavaFX 线程上... Application.start() 始终在 JavaFX 线程上运行。
  • @alex440 - 如果 fx 内部复制事件没有帮助,或者?
  • 我认为函数在事件有机会被处理之前就终止了。

标签: java javafx


【解决方案1】:

我对此的唯一解决方案是实现EventDispatchChain 接口。一个相当小的接口如下。不幸的是,javafx 使用的内置版本位于不可访问的包中 - 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;
        }
    }
}

这样使用时会产生预期的结果

Event result = button.buildEventDispatchChain(new SimpleChain()).dispatchEvent(event);
System.out.println(result.isConsumed());

【讨论】:

    猜你喜欢
    • 2016-11-12
    • 2012-05-04
    • 1970-01-01
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多