javafx有一个eventfilter删除自己

时间:2016-02-23 03:03:18

标签: javafx event-handling mouseevent

我的代码片段如下:

//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的鼠标过滤器消失,并像在paneClicked过滤器llamda中一样添加eventHandlers。我需要第一组事件作为过滤器,因为有子节点我不想接收事件(即弧上的事件过滤器是窗格的子节点)。第二组需要是处理程序,因为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的功能来删除它自己,但我很简短。我在谷歌搜索中也没有在网上或在stackexchange上找到任何东西。我真的很感激能够解决这个问题。感谢。

1 个答案:

答案 0 :(得分:4)

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

您可以使用包含this关键字的匿名类来解决此问题:

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
        );
    });
}

另见: