2016-06-14 62 views
1

我在學習JavaFX事件處理。我發現我們可以通過兩種方式註冊事件。setOnXXX()方法和addEventHandler()之間的區別JavaFx

一種是像setOnAction(EventHandler)方便的方法,setOnMouseClicked(EventHandler)

二是通過使用addEventHandler(MouseEvent.MOUSE_CLICKED, EventHandler)

但我很困惑它們之間有什麼區別呢?如何決定哪一個適合?

我已經測試和註冊兩個事件處理程序使用這兩種方法,都工作正常。

Button btn = new Button("Click Me One!"); 
    btn.setOnMouseEntered(new EventHandler<MouseEvent>(){ 
     @Override 
     public void handle(MouseEvent e){ 
      System.out.println("Mouse Entered on Click Me One"); 
     } 
    }); 

    btn.setOnMouseExited(new EventHandler<MouseEvent>(){ 
     @Override 
     public void handle(MouseEvent e){ 
      System.out.println("Mouse Exited from Click Me One"); 
     } 
    }); 


    Button btn2 = new Button("Click Me Two!"); 
    btn2.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>(){ 
     @Override 
     public void handle(MouseEvent e){ 
      System.out.println("Mouse Entered on Click Me Two"); 
     } 
    }); 
    btn2.addEventHandler(MouseEvent.MOUSE_EXITED, new EventHandler<MouseEvent>(){ 
     @Override 
     public void handle(MouseEvent e){ 
      System.out.println("Mouse Exited from Click Me Two"); 
     } 
    }); 

這是檢查後的輸出。

Mouse Entered on Click Me One 
Mouse Exited from Click Me One 
Mouse Entered on Click Me Two 
Mouse Exited from Click Me Two 

我也通過定義事件處理程序進行檢查。

Button btn2 = new Button("Click Me Two!"); 
     // Define an event handler 
     EventHandler<InputEvent> handler = new EventHandler<InputEvent>() { 
      public void handle(InputEvent event) { 
       System.out.println("Handling event " + event.getEventType()); 

      } 
     }; 
     btn2.addEventHandler(MouseEvent.MOUSE_ENTERED, handler); 
     btn2.addEventHandler(MouseEvent.MOUSE_EXITED, handler); 

     btn2.setOnMouseEntered(handler); 
     btn2.setOnMouseExited(handler); 

輸出:

Handling event MOUSE_ENTERED 
Handling event MOUSE_ENTERED 
Handling event MOUSE_EXITED 
Handling event MOUSE_EXITED 
+0

你的代碼中加入他們無關,與你的問題一樣EventType。你的代碼中沒有任何地方使用'addEventHandler'。 (對於記錄,您應該始終使用setOnAction作爲按鈕,而不是setOnMouseClicked。並非每個用戶都使用鼠標激活按鈕。) – VGR

+0

@VGR我已更新代碼,請現在檢查。 – UnKnown

+0

如果沒有別的,顯式事件屬性可用於確切地列舉哪些事件對於特定類是有效的。 – VGR

回答

1

將它們加入到測試自己,我得到了確切的點是什麼含義只能有一個用方便的方法相同類型的處理程序之後。所以我要回答我自己的問題。

有我setOnXXX()方法和addEventHandler

1之間發現了兩個主要區別是:你有addEventHandler()註冊將首先執行該事件。這是例子。

Button btn = new Button("Hover Me!"); 

btn.setOnMouseEntered(new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event with Convience Method"); 
    } 
}); 
btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event with addEventHandler"); 
    } 
}); 

輸出:

Handling event with addEventHandler 
Handling event with Convience Method 

閱讀James_D的評論我從original doc添加段落的第一個差異後。

節點可以註冊多個處理程序。每個調用處理程序的順序都是基於事件類型的層次結構。針對特定事件類型的處理程序 在針對通用 事件類型的處理程序之前執行。例如,在InputEvent.ANY事件的處理程序之前調用KeyEvent.KEY_TYPED事件 的處理程序。 其中沒有指定執行相同級別的兩個處理程序, ,但使用便捷方法使用的 便利方法註冊的處理程序最後執行的是 。

2:第二個區別是,你可以添加具有相同EventType多處理器(爲我所用MOUSE_ENTERED事件)使用addEventHandler();setOnXXX();最後註冊的事件處理程序的情況下將執行。這是例子。

Button btn = new Button("Hover Me!"); 

btn.setOnMouseEntered(new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event 1 with Convenience Method"); 
    } 
}); 
btn.setOnMouseEntered(new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event 2 with Convenience Method"); 
    } 
}); 
btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event 1 with addEventHandler"); 
    } 
}); 

btn.addEventHandler(MouseEvent.MOUSE_ENTERED, new EventHandler<MouseEvent>() { 
    public void handle(MouseEvent event) { 
     System.out.println("Handling event 2 with addEventHandler"); 
    } 
}); 

輸出:

Handling event 1 with addEventHandler 
Handling event 2 with addEventHandler 
Handling event 2 with Convenience Method 

正如你看到我註冊使用兩種方式了兩個事件處理程序。但在便捷方法的方式執行最後一個事件處理程序。要完成答案,請讓我複製jns的答案。

因此,如果您只需要一個EventHandler,那麼您使用的方法就沒有區別。但是,如果你需要應用幾個事件處理器 你有使用addEventhandler

+0

實際記錄它們的執行順序(即,您是否可以依賴該功能),還是僅僅是您在當前實現中測試過的內容? –

+0

在這裏你可以找到http://docs.oracle。com/javase/8/javafx/events-tutorial/processing.htm「未指定執行同一級別的兩個處理程序的順序,但使用便捷方法使用方便方法註冊的處理程序除外最後執行。' – UnKnown

+1

您應該將其添加到答案中以使其完成 –

4

看一看的Javadoc NodesetEventHandler(這會從setOnXXX叫):

設置用於此事件類型的處理程序。 一次只能指定一個這樣的處理程序。該處理程序保證被 稱爲最後一個處理程序,使用 addEventHandler(javafx.event.EventType,javafx.event.EventHandler)}添加後。

所以,如果你只需要一個EventHandler你使用哪種方法沒有區別。但是,如果您需要爲同一EventType應用幾個EventHandlers您在使用addEventhandler

+0

javadoc鏈接將會有所幫助。你能給我這個段落的鏈接嗎?我已經在上面解釋過了,我可以用兩種技術添加多個事件處理程序。 – UnKnown

+1

http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#setEventHandler-javafx.event.EventType-javafx.event.EventHandler- – jns

+0

其中寫setEventHandler從setOnXXX調用?我很困惑你能給我示例代碼來描述它們之間的區別嗎?和'一次只能指定一個這樣的處理程序'我已經用set方法添加了兩個事件,那麼它爲什麼會起作用? – UnKnown