2016-10-27 51 views
0

我正在製作一個基本的JavaFX GUI,當我將鼠標懸停在不同類型的GUI組件上時,我想在其中更改標籤。如何更有效地使用不同類型的JavaFX GUI組件來編寫我的代碼?

例如下面,我希望我的標籤將文本從'無聊'改爲'Hovered!'。當我懸停在一個組合框,TextField,按鈕,圓等

而不是重複相同的代碼再次,我猜我可以創建一個方法與對象作爲輸入參數,但我似乎無法相當正確。

從本質上講,是否有一種優雅的方式可以適應此代碼,以便它可以重用於所有類型的不同JavaFX GUI組件?

下面的代碼目前完全符合我所描述的內容,但是我希望更有效。

謝謝。

 comboBox.setOnMouseEntered(new EventHandler<MouseEvent>() { 
      @Override public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.HAND); 
      label.setText("Hovered!"); 
      } 
     }); 
     comboBox.setOnMouseExited(new EventHandler<MouseEvent>() { 
      @Override public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
      } 
     }); 

     textField.setOnMouseEntered(new EventHandler<MouseEvent>() { 
       @Override public void handle(MouseEvent mouseEvent) { 
       label.setCursor(Cursor.HAND); 
       label.setText("Hovered!"); 
       } 
      }); 
     textField.setOnMouseExited(new EventHandler<MouseEvent>() { 
      @Override public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
      } 
     }); 

     button.setOnMouseEntered(new EventHandler<MouseEvent>() { 
       @Override public void handle(MouseEvent mouseEvent) { 
       label.setCursor(Cursor.HAND); 
       label.setText("Hovered!"); 
       } 
      }); 
     button.setOnMouseExited(new EventHandler<MouseEvent>() { 
      @Override public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
      } 
     }); 

     circle.setOnMouseEntered(new EventHandler<MouseEvent>() { 
       @Override public void handle(MouseEvent mouseEvent) { 
       label.setCursor(Cursor.HAND); 
       label.setText("Hovered!"); 
       } 
      }); 
     circle.setOnMouseExited(new EventHandler<MouseEvent>() { 
      @Override public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
      } 
     }); 

回答

2

您可以輕鬆地使用一個輔助方法來註冊所有的聽衆。此外,您還可以重用的聽衆,因爲它們含有相同的代碼對所有節點:

private static void registerListeners(final Label label, Node... nodes) { 
    final EventHandler<MouseEvent> enteredHandler = new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.HAND); 
      label.setText("Hovered!"); 
     } 
    }; 

    final EventHandler<MouseEvent> exitedHandler = new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
     } 
    }; 

    // add listeners to all nodes 
    for (Node n : nodes) { 
     n.setOnMouseEntered(enteredHandler); 
     n.setOnMouseExited(exitedHandler); 
    } 
} 
registerListeners(label, comboBox, textField, button); 

請注意,你不能處理父節點上MOUSE_ENTEREDMOUSE_EXITED事件,因爲事件沒有通過層次結構。爲任意兒童做這項工作的唯一方法是處理父母上的MOUSE_MOVED事件。在這種情況下,您無法確定相交節點是您想要允許的節點之一。它可能是一個孩子。因此,您需要自己遍歷整個層次結構:

commonAncestor.setOnMouseEntered(evt -> { 
    Node n = evt.getPickResult().getIntersectedNode(); 
    while (n != commonAncestor) { 
     if (checkNode(n)) { 
      label.setCursor(Cursor.HAND); 
      label.setText("Hovered!"); 
      return; 
     } 
     n = n.getParent(); 
    } 

    label.setCursor(Cursor.MOVE); 
    label.setText("Bored"); 
}); 
+0

嗨,fabian,這正是我所期待的,非常感謝。我並沒有最終需要使用評論的後半部分,但它提到了它的優點,因爲以後可能需要類似的東西! – LiXie

0

我真的不知道這是否是最好的答案。不過你可以試試這個:

@Override 
public void initialize(URL location, ResourceBundle resources) { 
combobox.setOnMouseEntered(this); 
    combobox.setOnMouseExited(this); 
    textfield.setOnMouseEntered(this); 
    textfield.setOnMouseExited(this); 
    button.setOnMouseEntered(this); 
    button.setOnMouseExited(this); 

} 

@Override 
public void handle(MouseEvent event) { 
    switch (event.getEventType().getName()){ 
     case "MOUSE_ENTERED": 
      label.setCursor(Cursor.HAND); 
      label.setText("Hovered!"); 
      break; 
     case "MOUSE_EXITED": 
      label.setCursor(Cursor.MOVE); 
      label.setText("Bored"); 
      break; 
    } 
} 

你的控制器必須實現事件處理

+0

是的!當然。在問題中沒有提到FXML,但爲什麼不假定它被使用。爲什麼不讓控制器實現一個額外的接口,而不是在fxml文件中添加事件處理程序...... – fabian

相關問題