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

时间:2014-05-02 09:08:26

标签: java javafx

如何从javafx中的事件处理程序返回结果?我有下面的代码,以及如何将数据从事件返回到函数showPrompt?是否有可能恢复事件功能的数据?

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();       

}

3 个答案:

答案 0 :(得分:3)

简短的回答是你无法返回一个值。

为什么?

以下代码名为callback

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

回调没有返回类型,如上例所示,它是void

回调是方法,它作为参数传递给另一个方法。另一种方法会在需要时调用回调方法。这意味着回调是异步的。
在您的示例中,当您按下按钮时,它会调用回调

总之,您无法使用return返回。

怎么办?

您可以通过回调调用方法,并将return值作为参数发送给它。

示例:

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

其中setReturnValue是属于YourClass的方法或其实例,因此它会将您返回的值归零。

另一种方式更好方法是创建一个可能扩展Stage的类。同样在showPrompt方法中,您必须使用showAndWait()或类似方法阻止执行。

总之,您无法从一种方法创建整个Prompt

答案 1 :(得分:1)

不能,因为当你打开并关闭提示阶段时,主线程已经通过了showPrompt方法。

作为Andrei said,您需要做的是使用PromptStage API创建自己的自定义showPrompt,该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";
    }
}

或者如果您愿意,甚至可以创建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();
}

这里有很多方法。说实话,我不打算为你写全班。但是,如果你被困住,请做评论。

答案 2 :(得分:1)

另一个选择是将showPrompt(...)方法传递给StringProperty,并在“确定”按钮的处理程序中更新属性。然后showPrompt的调用者可以创建StringProperty,用它注册一个监听器,并观察它。类似的东西:

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();
        }
    });    

    // ...
}

然后用以下内容调用对话框:

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);