javafx 有一个 eventfilter 删除自己

javafx have an eventfilter remove itself

我的代码片段如下:

//button clicked method
@FXML
public void newHeatExchanger2ButtonClicked(ActionEvent event) throws Exception {

    //new pane created
    Pane pane = new Pane();

    //method call everytime the button is clicked
    create2DExchanger(pane);

   }

//method declaration
private void create2DExchanger(Pane pane) {

    EventHandler<MouseEvent> panePressed = (e -> {
        if (e.getButton() == MouseButton.SECONDARY){

            do stuff
        }

        if (e.getButton() == MouseButton.PRIMARY){
            do stuff
        }
    });

    EventHandler<MouseEvent> paneDragged = (e -> {
        if (e.getButton() == MouseButton.PRIMARY){
            do stuff
        }
    });
    EventHandler<MouseEvent> paneReleased = (e -> {
        if (e.getButton() == MouseButton.PRIMARY){
            do stuff;
        }

    });
    EventHandler<MouseEvent> paneMoved = (t -> {
        do stuff;
    });
    EventHandler<MouseEvent> paneClicked = (t -> {
        //I need this filter to remove itself right here
        t.consume();
        pane.removeEventFilter(MouseEvent.MOUSE_MOVED, paneMoved);
        pane.addEventHandler(MouseEvent.MOUSE_PRESSED, panePressed);
        pane.addEventHandler(MouseEvent.MOUSE_DRAGGED, paneDragged);
        pane.addEventHandler(MouseEvent.MOUSE_RELEASED, paneReleased);
    });
    pane.removeEventHandler(MouseEvent.MOUSE_PRESSED, panePressed);
    pane.removeEventHandler(MouseEvent.MOUSE_DRAGGED, paneDragged);
    pane.removeEventHandler(MouseEvent.MOUSE_RELEASED, paneReleased);
    pane.addEventFilter(MouseEvent.MOUSE_MOVED, paneMoved);
    pane.addEventFilter(MouseEvent.MOUSE_PRESSED, paneClicked);


}

最初我将窗格设置为只有 mouse_moved 和 mouse_pressed 的事件过滤器。单击鼠标后,我需要 mouse_pressed 和 mouse_moved 的鼠标过滤器消失并添加 eventHandlers,就像我在 paneClicked 过滤器 llamda 中所做的那样。我需要第一组事件作为过滤器,因为有我不想接收事件的子节点(即,作为窗格子节点的弧上的事件过滤器)。第二组需要是处理程序,因为 arc 事件过滤器需要在窗格 eventHandlers 接收事件之前使用该事件。

便利活动如:

    pane.setOnMousePressed() 

可以通过调用

删除自己
    pane.setOnMousePressed(null); 

但我需要这个初始事件过滤器来删除它自己。稍后我将需要在代码中删除自身的事件功能,但是如果我尝试添加

    pane.removeEventFilter(MouseEvent.MOUSE_PRESSED, paneClicked);

    EventHandler<MouseEvent> paneClicked = (t -> {
        //I need this filter to remove itself right here
        t.consume();
        pane.removeEventFilter(MouseEvent.MOUSE_MOVED, paneMoved);
        pane.addEventHandler(MouseEvent.MOUSE_PRESSED, panePressed);
        pane.addEventHandler(MouseEvent.MOUSE_DRAGGED, paneDragged);
        pane.addEventHandler(MouseEvent.MOUSE_RELEASED, paneReleased);
    });

它不会编译。几天来,我一直在研究如何让 eventFilter 或 eventHandler 的功能自行删除,但我做空了。我在 Google 搜索中也没有在网上或 stackexchange 上找到任何东西。我真的很感激能够解决这个问题。谢谢。

我认为问题源于您在完全声明之前尝试访问 paneClicked

您可以使用带有 this 关键字的匿名 class 来解决这个问题:

EventHandler<MouseEvent> paneClicked =  new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        event.consume();
        pane.removeEventFilter(MouseEvent.MOUSE_PRESSED, this);
        pane.removeEventFilter(MouseEvent.MOUSE_MOVED, paneMoved);
        pane.addEventHandler(MouseEvent.MOUSE_PRESSED, panePressed);
        pane.addEventHandler(MouseEvent.MOUSE_DRAGGED, paneDragged);
        pane.addEventHandler(MouseEvent.MOUSE_RELEASED, paneReleased);
    }
};

或者通过引用完全限定的静态函数:

public class ContainingClass {
    ...
    private static EventHandler<MouseEvent> paneClicked = (t -> {
        t.consume();
        pane.removeEventFilter(
            MouseEvent.MOUSE_PRESSED, ContainingClass.paneClicked
        );
    });
}

另请参阅:

  • Why do lambdas in Java 8 disallow forward reference to member variables where anonymous classes don't?
  • Java8 Lambdas vs Anonymous classes