简体   繁体   English

如何从javafx中的事件处理程序返回结果?

[英]How to return result from event handler in javafx?

How to return result from event handler in javafx? 如何从javafx中的事件处理程序返回结果? I have bellow code, and how to return data from event to function showPrompt? 我有下面的代码,如何从事件返回数据到函数showPrompt? Is it possible to recover the data for the function of the event? 是否可以为事件的功能恢复数据?

public static String showPrompt(String title, String defValue){
          final Stage dlgStage = new Stage();
          TextField txtPromptValue = new TextField(defValue);

          Button btnOk = new Button("Ok");
          Button btnCancel = new Button("Cancel");
          btnOk.setOnAction(new EventHandler<ActionEvent>(){
              @Override
              public void handle(ActionEvent arg0) {
                  //How to return data from event to function?
                  dlgStage.close();
              }
          });
          btnCancel.setOnAction(new EventHandler<ActionEvent>(){
              @Override
              public void handle(ActionEvent arg0) { 
                  //How to return data from event to function?
                  dlgStage.close();
              }
          });
          //
          Label lblTitle = new Label(title);
          lblTitle.setFont(Font.font("Amble CN", FontWeight.NORMAL, 14));
          //
          VBox vbox = new VBox(lblTitle,txtPromptValue,btnOk,btnCancel);
          vbox.setAlignment(Pos.CENTER);
          vbox.setMinSize(300, 200);
          //
          Scene dlgScene = new Scene(vbox);
          //
          dlgStage.setScene(dlgScene);
          dlgStage.initStyle(StageStyle.UNDECORATED);
          dlgStage.initModality(Modality.APPLICATION_MODAL);
          dlgStage.setMinWidth(300);
          dlgStage.setMinHeight(200);
          dlgStage.show();       

} }

The short answer is you can't return a value. 简短的答案是您无法返回值。

Why ? 为什么呢

This code bellow is called a callback . 下面的代码称为callback

new EventHandler<ActionEvent>(){
    @Override
    public void handle(ActionEvent arg0) {
        dlgStage.close();
    }
}

Callbacks have no return type, as you can see in the example above, it is void . 回调没有返回类型,如您在上面的示例中看到的那样,它是void

Callbacks are methods that you pass as an argument to another method. 回调是方法 ,您作为参数传递给另一个方法。 The other method will call you callback method when it wants. 另一个方法会在需要时调用回调方法 This means that callbacks are asynchronous. 这意味着回调是异步的。
In your example, it calls the callback when you press the button. 在您的示例中,当您按下按钮时,它将调用回调

In conclusion, you can't return from it using return . 总之,您不能使用return从中return

What to do ? 该怎么办 ?

You can call a method from your callback and sent your return value to it as an argument . 您可以从回调中调用方法,并将return值作为参数发送给该方法。

Example: 例:

btnCancel.setOnAction(
   new EventHandler<ActionEvent>(){
        @Override
        public void handle(ActionEvent arg0) {
            YourClass.setReturnValue("This is button Cancel");
            dlgStage.close();
        }
    }
});

Where setReturnValue is a method belonging to YourClass or an instance of it so it will retail your returned value. setReturnValue是属于YourClass的方法或其实例,因此它将零售您的返回值。

Another way better approach would be to create a class that extends Stage maybe. 更好的方法的另一种方式是创建可能扩展Stage的类。 Also in your showPrompt method you will have to block execution using showAndWait() or similar. 同样在showPrompt方法中,您将必须使用showAndWait()或类似方法阻止执行。

In conclusion, you can't create your entire Prompt from just one method. 总之,您不能仅通过一种方法来创建整个Prompt

You can't , because by the time you've opened and closed the prompt stage, the main thread will have already passed the showPrompt method. 不能这样做 ,因为在打开和关闭提示阶段之前,主线程已经通过了showPrompt方法。

As Andrei said , what you need to do is create your own custom PromptStage with a showPrompt API that blocks the main thread until the prompt stage is closed. 正如安德烈说 ,你需要做的就是创建自己的自定义PromptStageshowPrompt API,阻止主线程,直到提示阶段被关闭。

public static String showPrompt(final String title, final String defValue)
{
    // This line will block the main thread
    // See the "showAndWait()" API from JavaFX
    final boolean result = PromptStage.showPrompt("My Prompt Stage", " ");

    // And when the stage is closed, it will carry on to this piece of code
    if (result) 
    {
         return "This is button OK";
    }
    else
    {
         return "This is button CANCEL";
    }
}

Or you could even create instances of your PromptDialog if you like 或者,如果您愿意,甚至可以创建PromptDialog实例

public static String showPrompt(final String title, final String defValue)
{
    final PromptStage pStage = new PromptStage();

    // This line will block the main thread
    // See the "showAndWait()" API from JavaFX        
    pStage.showAndWait();

    return pStage.getResultAsString();
}

There are very many approaches here. 这里有很多方法。 To be honest, I won't bother writing the whole class for you. 老实说,我不会为您写整个课程。 However, do comment if you're stuck. 但是,如果遇到问题,请发表评论。

Another option is to pass the showPrompt(...) method a StringProperty , and update the property in your OK button's handler. 另一个选择是将showPrompt(...)方法传递给StringProperty ,并在“确定”按钮的处理程序中更新属性。 The caller of showPrompt can then create the StringProperty , register a listener with it, and observe it. 然后, showPrompt的调用者可以创建StringPropertyshowPrompt其注册一个侦听器并进行观察。 Something like: 就像是:

public String showPrompt(String title, String defValue, final StringProperty result){
    // ...
    final TextField txtPromptValue = new TextField(defValue);
    // ...
    btnOk.setOnAction(new EventHandler<ActionEvent>(){
        @Override
        public void handle(ActionEvent event) {
            result.set(txtPromptValue.getText());
            dlgStage.close();
        }
    });    

    // ...
}

Then you call the dialog with something like: 然后,您使用类似以下内容的对话框:

StringProperty dialogResult = new SimpleStringProperty();
dialogResult.addListener(new ChangeListener<String>() {
    public void changed(ObservableValue<? extends String> obs, String oldValue, String newValue) { 
        // process newValue, the value from the dialog...
    }
});
showPrompt("Dialog Title", "Default value", dialogResult);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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