Reputation: 136
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.
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
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?
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");
}
});
Upvotes: 0
Views: 95
Reputation: 82461
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. The only way to make this work for arbitrary children would be to handle the MOUSE_MOVED
event on the parent. 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");
});
Upvotes: 2
Reputation: 11
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
Upvotes: 0