简体   繁体   English

如何才能更有效地编写代码,以与不同类型的JavaFX GUI组件一起使用?

[英]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_ENTEREDMOUSE_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM