问题
First of all, sorry for the bad english.
Here is the case:
I have a \"main stage\" where i press a button to open a \"second stage\" where i have a table, the user selects one item of the the table and click on \"asignar\" button (wich is just a confirm button), once clicked, it must return the code of the item selected in the table to the main stage and close the second stage.
Here is the code that matters.
I have an INT variable wich must take the value of a function:
codigo = controller.setVista(this, usuario, password);
The \"setVista\" function goes like this:
public int setVista(ListHorarios vista, String usuario, String password) {
this.vista = vista;
this.usuario = usuario;
this.password = password;
this.inicializarTabla();
this.actualizarTabla(0, \"%\");
btnSeleccionar.setOnAction(e -> {
asignarSeleccion();
Stage stage = (Stage) btnSeleccionar.getScene().getWindow();
stage.close();
});
return codigo_horario;
}
And the \"asignarSeleccion\" like this:
private void asignarSeleccion() {
final HorarioTableModelo aux_horario = getTablaSeleccionada();
posicion = datos.indexOf(aux_horario);
if (aux_horario != null) {
codigo_horario = aux_horario.getCodigo();
}
}
My problem is that i can\'t get the \"codigo_horario\" value into the first variable \"codigo\" before the stage closes, what do i am missing?
回答1:
Here is a possible example. The structure is the same as in the answer in my comment.
The second Stage
is opened through a "controller" that is stores the data that should be returned even when the Stage
is closed and exposes a getter to be used to retrieve the value from the outer world.
import javafx.application.Application;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
Button bSecondStage = new Button("Show second Stage");
bSecondStage.setOnAction(e -> {
WindowController wc = new WindowController();
wc.showStage();
System.out.println(wc.getData());
});
root.setCenter(bSecondStage);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
class WindowController {
private String data;
void showStage() {
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
VBox root = new VBox();
Scene scene = new Scene(root);
TextField tf = new TextField();
Button submit = new Button("Submit");
submit.setOnAction(e -> {
data = tf.getText();
stage.close();
});
root.getChildren().addAll(tf, submit);
stage.setScene(scene);
stage.showAndWait();
}
String getData() {
return data;
}
}
}
回答2:
You can write your own Stage class with a return statement.
public class MyStage extends Stage {
public String showAndReturn(myFXControll controll) {
super.showAndWait();
return controll.getReturn();
}
}
After that you have to define a return function to your controller.
public class TableFilterControll implements Initializable {
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
public String getReturn() {
return "I'm a nice return value"; //return what you want controlled by your controller class
}
}
Now you can controll your return from the parent controller.
String retValue=myStage.showAndReturn(childControll);
System.out.println(retValue);
I think this is a good solution for clean code. And you can style your FXML with Screne Builder.
回答3:
In my main controller I create Stage. Load controller which I can use like any class. And by creating an event I can get data just before closing the window.
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/package/mySceneBuilderWindow.fxml"));
final Pane rootPane = (Pane)loader.load();
Scene scene = new Scene(rootPane);
Stage stage = new Stage();
stage.setTitle("Optional title");
stage.setScene(scene);
mySceneBuilderWindowController controller = loader.<mySceneBuilderWindowController>getController();
controller.iCanSendDataToCtrl("String for now"); // sending data or init textFields...
stage.show();
/* set event which is fired on close
// How to close in the other window... (pressing X is OK too)
@FXML private Button fxidSave = new Button(); // global var
@FXML private void handleSaveButton() {
Stage stage = (Stage) fxidSave.getScene().getWindow();
stage.close(); // closes window
}
*/
stage.setOnCloseRequest((EventHandler<WindowEvent>) new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
String iCanGetDataBeforeClose = controller.getData();
System.out.println(iCanGetDataBeforeClose);
// static class can be used aswell -> System.out.println(Context.getMyString());
}
});
} catch (IOException e) {
System.out.println("something wrong with .fxml - name wrong? path wrong? building error?");
}
My other mySceneBuilderWindowController methods:
public void iCanSendDataToCtrl(String giveMe) {
// do something ex. myTextBox.setText(giveMe);
}
public String iCanGetDataBeforeClose() {
// do something ex. return myTextBox.getText();
}
来源:https://stackoverflow.com/questions/40676656/how-to-return-value-from-a-stage-before-closing-it