简体   繁体   中英

How to return result from event handler in javafx?

How to return result from event handler in javafx? I have bellow code, and how to return data from event to function 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 .

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 .

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 .

What to do ?

You can call a method from your callback and sent your return value to it as an argument .

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.

Another way better approach would be to create a class that extends Stage maybe. Also in your showPrompt method you will have to block execution using showAndWait() or similar.

In conclusion, you can't create your entire Prompt from just one method.

You , 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.

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

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. The caller of showPrompt can then create the StringProperty , register a listener with it, and observe it. 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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