[英]How can I write my code more efficiently for use with different types of JavaFX GUI components?
I am making a basic JavaFX GUI, where I would like a label to change when I am hovering over different types of GUI components. 我正在制作一个基本的JavaFX GUI,当我将鼠标悬停在不同类型的GUI组件上时,我希望在其中更改标签。
For example below, I want my label to change text from 'Bored' to 'Hovered!' 例如,在下面的示例中,我希望我的标签将文本从“无聊”更改为“悬停!” when I hover over either a ComboBox, TextField, Button, Circle etc 当我将鼠标悬停在ComboBox,TextField,Button,Circle等上时
Instead of repeating the same code over again, I am guessing I could create a method with the object as the input argument, but I can't seem to quite get it right. 我猜我不必重复相同的代码,而是可以创建一个以对象作为输入参数的方法,但是我似乎不太正确。
Essentially, is there an elegant way I can adapt this code so that it can be reusable for all types of different JavaFX GUI components? 本质上,我是否可以通过一种优雅的方法来修改此代码,以使其可用于所有类型的不同JavaFX GUI组件?
The following code currently does exactly what I describe, but is something that I would like to be more efficient. 目前,以下代码完全符合我的描述,但是我希望它能更有效。
Thanks. 谢谢。
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");
}
});
You can easily use a helper method to register all those listeners. 您可以轻松地使用辅助方法来注册所有这些侦听器。 Furthermore you can reuse the listeners, since they contain the same code for all of the nodes: 此外,您可以重用侦听器,因为它们对所有节点都包含相同的代码:
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);
Note that you cannot handle the MOUSE_ENTERED
and the MOUSE_EXITED
event on a parent node, since the event is not passed through the hierarchy. 请注意,您不能在父节点上处理MOUSE_ENTERED
和MOUSE_EXITED
事件,因为该事件未通过层次结构传递。 The only way to make this work for arbitrary children would be to handle the MOUSE_MOVED
event on the parent. 使任意子代执行此操作的唯一方法是处理父代上的MOUSE_MOVED
事件。 In this case you cannot be sure the intersected node is one of the nodes you want to allow. 在这种情况下,您不能确定相交的节点是您要允许的节点之一。 It could be a child. 可能是个孩子。 Therefore you need to iterate through the hierarchy yourself: 因此,您需要自己遍历层次结构:
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");
});
I don't really know if this was the best answer. 我真的不知道这是否是最佳答案。 But you can try this: 但是您可以尝试以下操作:
@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;
}
}
Your controller must implement EventHandler 您的控制器必须实现EventHandler
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.