2014年2月24日 星期一

JavaFX Event (3) Mouse Event

滑鼠最早是在1962年由Stanford Research Institute的Douglas Engelbart教授所發明,如下圖所示 (資料來源Wikipedia):
在此並向Douglas Engelbart教授致敬。
1971年Stanford Research Institute將滑鼠授權給Xerox (全錄) 的Palo Alto Research Center研究中心,1984年Apple Macintosh正式問世,主機附有單鍵滑鼠,如下圖所示 (資料來源Wikipedia)
發展至今,滑鼠的樣式日新月異,如軌跡球、Touchpad、無線滑鼠、光學滑鼠等,此外滑鼠按鍵分別有一、二、三個按鍵或滾輪等樣式:
滑鼠事件是指當使用滑鼠時所產生的事件,包括移動滑鼠 (Mouse Moved)、按下滑鼠按鍵 (Mouse Pressed)、放開滑鼠按鍵 (Mouse Released)、拖曳滑鼠 (Mouse Drag Entered) 等,並分為滑鼠事件與滑鼠拖曳事件,類別分別為MouseEventMouseDragEvent,以下為相關的設定方法:
  • setOnMouseClicked():按下並放開滑鼠按鍵。
  • setOnMouseDragged():在物件上方按住滑鼠按鍵並拖曳。
  • setOnMouseEntered():滑鼠移至物件上方。
  • setOnMouseExited():滑鼠離開物件。
  • setOnMouseMoved():滑鼠在物件上方移動。
  • setOnMousePressed():按下滑鼠按鍵。
  • setOnMouseReleased():放開滑鼠按鍵。
  • setOnMouseDragEntered():滑鼠拖曳至物件。
  • setOnMouseDragExited():滑鼠拖曳離開物件。
  • setOnMouseDragOver():滑鼠拖曳至物件上方。
  • setOnMouseDragReleased():拖曳中放開滑鼠按鍵。
滑鼠與滑鼠拖曳事件為Node抽象類別與Scene類別所定義之事件,因此凡繼承Node抽象類別的物件,均會產生滑鼠與滑鼠拖曳事件。

滑鼠事件的類別為MouseEvent,繼承自InputEvent類別,MouseEvent類別定義以下的事件類型,以做為註冊Event Handler與Event Filter之用:
  • MouseEvent.DRAG_DETECTED:偵測滑鼠拖曳。
  • MouseEvent.MOUSE_CLICKED:按下並放開滑鼠按鍵。
  • MouseEvent.MOUSE_DRAGGED:在物件上方按住滑鼠按鍵並拖曳。
  • MouseEvent.MOUSE_ENTERED:滑鼠移至物件上方。
  • MouseEvent.MOUSE_ENTERED_TARGET:滑鼠移至物件上方。
  • MouseEvent.MOUSE_EXITED:滑鼠離開物件。
  • MouseEvent.MOUSE_EXITED_TARGET:滑鼠離開物件。
  • MouseEvent.MOUSE_MOVED:滑鼠在物件上方移動。
  • MouseEvent.MOUSE_PRESSED:按下滑鼠按鍵。
  • MouseEvent.MOUSE_RELEASED:放開滑鼠按鍵。
  • MouseEvent.ANY:代表上述任一種事件類型。
請參考以下範例,介紹如何處理滑鼠事件,分別以相關方法設定滑鼠事件的Event Handler函式。

此外,並分別以getButton()getX()getY()方法取得產生滑鼠事件時所按下的滑鼠按鍵、滑鼠相對於物件的水平與垂直座標位置:


// Mouse Clicked
scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Clicked: " + e.getButton());
  }
});

// Mouse Entered
scene.setOnMouseEntered(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Entered: X: " + e.getX() + ", Y: " + e.getY());
  }
});

// Mouse Exited
scene.setOnMouseExited(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Exited: X: " + e.getX() + ", Y: " + e.getY());
  }
});

// Mouse Moved
scene.setOnMouseMoved(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Moved: X: " + e.getX() + ", Y: " + e.getY());
  }
});

// Mouse Pressed
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Pressed: " + e.getButton());
  }
});

// Mouse Released
scene.setOnMouseReleased(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    label.setText("Mouse Released: " + e.getButton());
  }
});


除了上述語法之外,亦可以建立類別的方式處理,請參考以下範例,當滑鼠移動時,則移動圖像:


// Mouse Moved
scene.setOnMouseMoved(onMouseMovedEventHandler);
...

EventHandler onMouseMovedEventHandler = new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    imageview.setX(e.getX());
    imageview.setY(e.getY());
  }
};


以下範例示範以addEventHandler()方法註冊事件的Event Handler,並分別處理按下滑鼠按鍵 (MouseEvent.MOUSE_PRESSED) 與在物件上方按住滑鼠按鍵並拖曳 (MouseEvent.MOUSE_DRAGGED) 之事件。當在圖像上方按住滑鼠按鍵並拖曳時,則移動圖像:


// Mouse Pressed
imageview.addEventHandler(MouseEvent.MOUSE_PRESSED, 
  new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    orgSceneX = e.getSceneX();
    orgSceneY = e.getSceneY();
    orgTranslateX = ((ImageView)(e.getSource())).getTranslateX();
    orgTranslateY = ((ImageView)(e.getSource())).getTranslateY();
  }
});

// Mouse Dragged
imageview.addEventHandler(MouseEvent.MOUSE_DRAGGED, 
  new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent e) {
    double offsetX = e.getSceneX() - orgSceneX;
    double offsetY = e.getSceneY() - orgSceneY;
    double newTranslateX = orgTranslateX + offsetX;
    double newTranslateY = orgTranslateY + offsetY;

    ((ImageView)(e.getSource())).setTranslateX(newTranslateX);
    ((ImageView)(e.getSource())).setTranslateY(newTranslateY);
  }
});


接著說明滑鼠拖曳事件。

滑鼠拖曳事件的類別為MouseDragEvent,繼承自MouseEvent類別,MouseDragEvent類別定義以下的事件類型,以做為註冊Event Handler與Event Filter之用:
  • MouseDragEvent.MOUSE_DRAG_ENTERED:滑鼠拖曳至物件。
  • MouseDragEvent.MOUSE_DRAG_ENTERED_TARGET:滑鼠拖曳至物件。
  • MouseDragEvent.MOUSE_DRAG_EXITED:滑鼠拖曳離開物件。
  • MouseDragEvent.MOUSE_DRAG_EXITED_TARGET:滑鼠拖曳離開物件。
  • MouseDragEvent.MOUSE_DRAG_OVER:滑鼠拖曳至物件上方。
  • MouseDragEvent.MOUSE_DRAG_RELEASED:拖曳中放開滑鼠按鍵。
  • MouseDragEvent.ANY:代表上述任一種事件類型。
但由於MouseDragEvent類別並未提供與拖放剪貼簿 (Drag-and-Drop Clipboard) 間之互動,因此在實作上常使用DragEvent類別取代MouseDragEvent類別。

【參考資料】

[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,深入研究Java Swing。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 2.2 API Specification.
[6] Java Platform, Standard Edition 7 API Specification.

© Chia-Hui Huang

沒有留言:

張貼留言