JavaFX Fire TextField ActionEvent手动|以编程方式

JavaFX Fire TextField ActionEvent手动|以编程方式,java,events,javafx,Java,Events,Javafx,我知道一些避免这种情况的方法,比如在不同的节点中添加相同的ActionHandler: // Custom Event Handler EventHandler<ActionEvent> myHandler = e -> { //code }; inputField.setOnAction(myHandler); // okButton okButt

我知道一些避免这种情况的方法,比如在不同的节点中添加相同的ActionHandler:

        // Custom Event Handler
        EventHandler<ActionEvent> myHandler = e -> {

             //code

        };

        inputField.setOnAction(myHandler);

        // okButton
        okButton.setOnAction(myHandler);
//自定义事件处理程序
EventHandler myHandler=e->{
//代码
};
设置操作(myHandler);
//奥克巴顿
设置操作(myHandler);
但是我可以在Node类中看到一个方法
fireEvent(Event)
。问题是我有多个
TextFields
,当按下名为
okButton
按钮时,我想一次全部激发它们


如何做到这一点?如果这对您来说没有什么意义,那么就说我想要它是出于研究原因:)。

我真的看不出这样做的任何正当理由:您基本上是要求控制器在视图上调用用户事件,而不是做它通常做的事情并更新模型

所以我想我能想到的最接近的东西就是这样的东西。假设您有一个
Person
类(使用规范的JavaFX示例):

public class Person {

    private final StringProperty firstName = new SimpleStringProperty() ;
    private final StringProperty lastName = new SimpleStringProperty() ;
    private final StringProperty email = new SimpleStringProperty() ;

    public StringProperty firstNameProperty() {
        return firstName ;
    }

    public final String getFirstName() {
        return firstNameProperty().get();
    }

    public final void setFirstName(String firstName) {
        firstNameProperty().set(firstName);
    }

    // etc etc
}
然后是某种编辑。您可以在编辑器中创建一个映射,将每个文本字段映射到要执行的操作,然后向调用相应操作的每个文本字段注册单个事件处理程序。您的按钮可以遍历地图并调用所有操作:

public class PersonEditor {

     private TextField firstNameTextField ;
     private TextField lastNameTextField ;
     private TextField emailTextField ;

     private Button okButton ;


     public PersonEditor(Person person) {

         // create controls, do layout, etc etc...

         // map textfields to an action on the person:
         Map<TextField, Consumer<String>> actions = new HashMap<>();
         actions.put(firstNameTextField, person::setFirstName);             
         actions.put(lastNameTextField, person::setLastName);             
         actions.put(emailTextField, person::setEmail);

         // set individual event handlers on each text field:
         actions.entrySet().forEach(entry -> {
             TextField tf = entry.getKey();
             tf.setOnAction(e -> entry.getValue().accept(tf.getText()));
         });

         // event handler for button:
         okButton.setOnAction(e -> {
             // invoke action on each text field:
             actions.entrySet().forEach(entry -> entry.getValue().accept(entry.getKey().getText()));
             // do other stuff if needed...
         }

    }

}
公共类PersonEditor{
私有文本字段firstNameTextField;
私有文本字段lastNameTextField;
私有文本字段emailTextField;
私人按钮;
公共人员编辑(个人){
//创建控件、进行布局等。。。
//将文本字段映射到此人的操作:
Map actions=newhashmap();
actions.put(firstNameTextField,person::setFirstName);
actions.put(lastnamextfield,person::setLastName);
actions.put(emailTextField,person::setEmail);
//在每个文本字段上设置单独的事件处理程序:
actions.entrySet().forEach(条目->{
TextField tf=entry.getKey();
setOnAction(e->entry.getValue().accept(tf.getText());
});
//按钮的事件处理程序:
确定按钮。设置操作(e->{
//对每个文本字段调用操作:
actions.entrySet().forEach(entry->entry.getValue().accept(entry.getKey().getText());
//如果需要,做其他事情。。。
}
}
}

根据OP的要求,我将添加我的评论作为回答

您可以使用
.firevent(new ActionEvent())
来启动
TextField
s操作处理程序

我实现这一点的方法是存储/获取所有
文本字段
s,然后当按下
按钮时,对每个字段进行迭代并
。fireEvent(new ActionEvent());
。下面的小控制器示例.VBox来自FXML文件

public class Controller {

    @FXML private VBox root;
    private List<TextField> all = new ArrayList<>();

    public Controller(){}
    @FXML
    public void initialize(){
        EventHandler<ActionEvent> customEvent = e -> {
            if(e.getSource().getClass() == Button.class){
                all.forEach(t -> t.fireEvent(new ActionEvent()));
            }else {
                System.out.println(((TextField) e.getSource()).getText());
            }
        };

        for(int i=0; i < 10; i++){
            TextField tf = new TextField(Integer.toString(i));
            tf.setOnAction(customEvent);
            all.add(tf);
            root.getChildren().add(tf);
        }
        Button btn = new Button();
        btn.setOnAction(customEvent);
        root.getChildren().add(btn);
    }

}
公共类控制器{
@FXML私有VBox根;
private List all=new ArrayList();
公共控制器(){}
@FXML
公共无效初始化(){
EventHandler customEvent=e->{
如果(例如getSource().getClass()==按钮.class){
all.forEach(t->t.firevent(newactionevent());
}否则{
System.out.println(((TextField)e.getSource()).getText());
}
};
对于(int i=0;i<10;i++){
TextField tf=新的TextField(Integer.toString(i));
tf.设置动作(自定义事件);
全部。添加(tf);
root.getChildren().add(tf);
}
按钮btn=新按钮();
btn.setOnAction(自定义事件);
root.getChildren().add(btn);
}
}

不要手动触发事件,而是通过调用按钮的方法使其成为默认按钮。我使用了
.firevent(new ActionEvent())
来启动我的
TextField
s操作处理程序。我确实需要遍历每个
TextField
并调用每个
firevent
。我以前没有使用
按钮来启动。我想这可能是一个开始。@MichaelPickett您可以添加它作为答案:)@VGR我可以举个例子吗?
okButton.setDefaultButton(true)。这真的很容易。