This discussion is archived
3 Replies Latest reply: Dec 27, 2012 8:07 AM by James_D RSS

how to pass values from one stage to other

966041 Newbie
Currently Being Moderated
I have two stage (say primary and secondary).The primary stage creates the secondary stage. When the secondary is opened i can access all the members(say bitNo) of 1st stage and try to set some value. But in the 1st stage i find the value not being set. I think it's because 1st is executed before the 2nd. I used showAndWait() in 1st then show() on 2nd then it is throwing exception.

So i want to use the values set by the 2nd stage in the 1st stage.
How do i synchronize them ?
Thanks .
package test;

import javafx.application.Application;
import javafx.event.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.*;


public class Test extends Application {
   
    private int bitNo;
    Stage primaryStage,secondaryStage;    
    TextField textField;    
    double x,y;
   
    public static void main(String[] args) { launch(args); }

    
    @Override 
    public void start(final Stage primaryStage) {
        
        this.primaryStage=primaryStage;
        Group rt=new Group();
        Scene sc= new Scene(rt,300,300);
        
        Button button =new Button("Click Me");
        button.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                secondaryStage=new Stage(StageStyle.TRANSPARENT);
                secondaryStage.initModality(Modality.WINDOW_MODAL);
                secondaryStage.initOwner(primaryStage);     
                
                showSecondaryWindow();
            }
        });
        
        rt.getChildren().add(button);           
        primaryStage.setScene(sc);
        primaryStage.show();
        
        //primaryStage.showAndWait();
        
        System.out.println("Bit no set= "+bitNo);       

 }//start

 public void showSecondaryWindow(){
     
     Pane root=new Pane();
     root.setStyle("-fx-background-color: rgb(0,50,70);");
     //root.setPrefSize(200,200);
     Scene scene=new Scene(root,200,300);
            
     Label label=new Label("Data");
     textField=new TextField();
     textField.setUserData("one");
            
     Button ok=new Button("Ok");
     ok.setDefaultButton(true);
     ok.setOnMouseClicked(new EventHandler<MouseEvent>() {

        @Override
        public void handle(MouseEvent event) {
            System.out.println("New Stage Mouse Clicked");
            bitNo=Integer.parseInt(textField.getText());
            System.out.println("Bit no set by Secondary= "+bitNo);
            primaryStage.getScene().getRoot().setEffect(null);
            secondaryStage.close();
        }
     });
     Button cancel=ButtonBuilder.create().cancelButton(true).text("Cancel").build();
     cancel.setOnMouseClicked(new EventHandler<MouseEvent>() {  
         @Override
         public void handle(MouseEvent event) {
             System.out.println("New Stage Mouse Clicked");
             primaryStage.getScene().getRoot().setEffect(null);
             secondaryStage.close();
         }
     });
     //VBox vBox =new VBox();
     //vBox.getChildren().addAll(label,textField,ok);
     HBox dataFileds=new HBox(10);
     dataFileds.getChildren().addAll(label,textField);
     HBox buttons=new HBox(10);
     buttons.getChildren().addAll(cancel,ok);
     root.getChildren().add(VBoxBuilder.create().children(dataFileds,buttons).spacing(10).build());
     //scene.getStylesheets().add(Test.class.getResource("Modal.css").toExternalForm());
     secondaryStage.setScene(scene);
     //final Node root = secondaryStage.getScene().getRoot();
     root.setOnMousePressed(new EventHandler<MouseEvent>() {
         @Override public void handle(MouseEvent mouseEvent) {
             // record distance for the drag and drop operation.
             x = secondaryStage.getX() - mouseEvent.getScreenX();
             y = secondaryStage.getY() - mouseEvent.getScreenY();
         }
     });
     root.setOnMouseDragged(new EventHandler<MouseEvent>() {
         @Override public void handle(MouseEvent mouseEvent) {
             secondaryStage.setX(mouseEvent.getScreenX() +x);
             secondaryStage.setY(mouseEvent.getScreenY() +y);
         }
     });
     //primaryStage.getScene().getRoot().setEffect(new BoxBlur());
     secondaryStage.show();
     
 }//showSecondaryWindow
    
}//class
  • 1. Re: how to pass values from one stage to other
    James_D Guru
    Currently Being Moderated
    You can use showAndWait() on your secondary stage. Then execution is blocked and you'll see the change to your variable:
    package test ;
    
    import javafx.application.Application;
    import javafx.event.*;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.*;
    import javafx.stage.*;
    
    public class Test extends Application {
    
      private int bitNo;
      Stage primaryStage, secondaryStage;
      TextField textField;
      double x, y;
    
      public static void main(String[] args) {
        launch(args);
      }
    
      @Override
      public void start(final Stage primaryStage) {
    
        this.primaryStage = primaryStage;
        Group rt = new Group();
        Scene sc = new Scene(rt, 300, 300);
    
        Button button = new Button("Click Me");
        button.setOnAction(new EventHandler<ActionEvent>() {
    
          @Override
          public void handle(ActionEvent event) {
            secondaryStage = new Stage(StageStyle.TRANSPARENT);
            secondaryStage.initModality(Modality.WINDOW_MODAL);
            secondaryStage.initOwner(primaryStage);
    
            // This calls showAndWait(), so execution blocks until the window is closed
            showSecondaryWindow();
            // secondary window is now closed, value should be updated:
            System.out.println("Bit no now: " + bitNo);
          }
        });
    
        rt.getChildren().add(button);
        primaryStage.setScene(sc);
        primaryStage.show();
    
        // primaryStage.showAndWait();
    
        System.out.println("Bit no set= " + bitNo);
    
      }// start
    
      public void showSecondaryWindow() {
    
        Pane root = new Pane();
        root.setStyle("-fx-background-color: rgb(0,50,70);");
        // root.setPrefSize(200,200);
        Scene scene = new Scene(root, 200, 300);
    
        Label label = new Label("Data");
        textField = new TextField();
        textField.setUserData("one");
    
        Button ok = new Button("Ok");
        ok.setDefaultButton(true);
        ok.setOnMouseClicked(new EventHandler<MouseEvent>() {
    
          @Override
          public void handle(MouseEvent event) {
            System.out.println("New Stage Mouse Clicked");
            bitNo = Integer.parseInt(textField.getText());
            System.out.println("Bit no set by Secondary= " + bitNo);
            primaryStage.getScene().getRoot().setEffect(null);
            secondaryStage.close();
          }
        });
        Button cancel = ButtonBuilder.create().cancelButton(true).text("Cancel")
            .build();
        cancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            System.out.println("New Stage Mouse Clicked");
            primaryStage.getScene().getRoot().setEffect(null);
            secondaryStage.close();
          }
        });
        // VBox vBox =new VBox();
        // vBox.getChildren().addAll(label,textField,ok);
        HBox dataFileds = new HBox(10);
        dataFileds.getChildren().addAll(label, textField);
        HBox buttons = new HBox(10);
        buttons.getChildren().addAll(cancel, ok);
        root.getChildren().add(
            VBoxBuilder.create().children(dataFileds, buttons).spacing(10).build());
        // scene.getStylesheets().add(Test.class.getResource("Modal.css").toExternalForm());
        secondaryStage.setScene(scene);
        // final Node root = secondaryStage.getScene().getRoot();
        root.setOnMousePressed(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent mouseEvent) {
            // record distance for the drag and drop operation.
            x = secondaryStage.getX() - mouseEvent.getScreenX();
            y = secondaryStage.getY() - mouseEvent.getScreenY();
          }
        });
        root.setOnMouseDragged(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent mouseEvent) {
            secondaryStage.setX(mouseEvent.getScreenX() + x);
            secondaryStage.setY(mouseEvent.getScreenY() + y);
          }
        });
        // primaryStage.getScene().getRoot().setEffect(new BoxBlur());
        secondaryStage.showAndWait();
    
      }// showSecondaryWindow
    
    }// class
    You can also use an IntegerProperty to hold the variable, and listen for changes on it:
    package test ;
    
    import javafx.application.Application;
    import javafx.beans.property.IntegerProperty;
    import javafx.beans.property.SimpleIntegerProperty;
    import javafx.beans.value.ChangeListener;
    import javafx.beans.value.ObservableValue;
    import javafx.event.*;
    import javafx.scene.*;
    import javafx.scene.control.*;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.*;
    import javafx.stage.*;
    
    public class Test extends Application {
    
      private IntegerProperty bitNo;
      Stage primaryStage, secondaryStage;
      TextField textField;
      double x, y;
    
      public static void main(String[] args) {
        launch(args);
      }
    
      @Override
      public void start(final Stage primaryStage) {
    
        this.bitNo = new SimpleIntegerProperty();
        
        bitNo.addListener(new ChangeListener<Number>() {
    
          @Override
          public void changed(ObservableValue<? extends Number> observable,
              Number oldValue, Number newValue) {
            System.out.printf("bit no changed from %d to %d%n", oldValue, newValue);
          }
          
        });
        this.primaryStage = primaryStage;
        Group rt = new Group();
        Scene sc = new Scene(rt, 300, 300);
    
        Button button = new Button("Click Me");
        button.setOnAction(new EventHandler<ActionEvent>() {
    
          @Override
          public void handle(ActionEvent event) {
            secondaryStage = new Stage(StageStyle.TRANSPARENT);
            secondaryStage.initModality(Modality.WINDOW_MODAL);
            secondaryStage.initOwner(primaryStage);
    
            showSecondaryWindow();
          }
        });
    
        rt.getChildren().add(button);
        primaryStage.setScene(sc);
        primaryStage.show();
    
        // primaryStage.showAndWait();
    
        System.out.println("Bit no set= " + bitNo.get());
    
      }// start
    
      public void showSecondaryWindow() {
    
        Pane root = new Pane();
        root.setStyle("-fx-background-color: rgb(0,50,70);");
        // root.setPrefSize(200,200);
        Scene scene = new Scene(root, 200, 300);
    
        Label label = new Label("Data");
        textField = new TextField();
        textField.setUserData("one");
    
        Button ok = new Button("Ok");
        ok.setDefaultButton(true);
        ok.setOnMouseClicked(new EventHandler<MouseEvent>() {
    
          @Override
          public void handle(MouseEvent event) {
            System.out.println("New Stage Mouse Clicked");
            bitNo.set(Integer.parseInt(textField.getText()));
            System.out.println("Bit no set by Secondary= " + bitNo);
            primaryStage.getScene().getRoot().setEffect(null);
            secondaryStage.close();
          }
        });
        Button cancel = ButtonBuilder.create().cancelButton(true).text("Cancel")
            .build();
        cancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent event) {
            System.out.println("New Stage Mouse Clicked");
            primaryStage.getScene().getRoot().setEffect(null);
            secondaryStage.close();
          }
        });
        // VBox vBox =new VBox();
        // vBox.getChildren().addAll(label,textField,ok);
        HBox dataFileds = new HBox(10);
        dataFileds.getChildren().addAll(label, textField);
        HBox buttons = new HBox(10);
        buttons.getChildren().addAll(cancel, ok);
        root.getChildren().add(
            VBoxBuilder.create().children(dataFileds, buttons).spacing(10).build());
        // scene.getStylesheets().add(Test.class.getResource("Modal.css").toExternalForm());
        secondaryStage.setScene(scene);
        // final Node root = secondaryStage.getScene().getRoot();
        root.setOnMousePressed(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent mouseEvent) {
            // record distance for the drag and drop operation.
            x = secondaryStage.getX() - mouseEvent.getScreenX();
            y = secondaryStage.getY() - mouseEvent.getScreenY();
          }
        });
        root.setOnMouseDragged(new EventHandler<MouseEvent>() {
          @Override
          public void handle(MouseEvent mouseEvent) {
            secondaryStage.setX(mouseEvent.getScreenX() + x);
            secondaryStage.setY(mouseEvent.getScreenY() + y);
          }
        });
        // primaryStage.getScene().getRoot().setEffect(new BoxBlur());
        secondaryStage.show();
    
      }// showSecondaryWindow
    
    }// class
  • 2. Re: how to pass values from one stage to other
    966041 Newbie
    Currently Being Moderated
    Thank you very much.
    Both of the codes are working fine.

    Although it is not required but Out of my curiosity i am asking you, Can you please tell me if i want to block(wait) the primary stage as soon as the secondary stage is opened and when the secondary stage is closed it should notify to 1st stage which would continue its normal execution and it would see some of its field values changed by the 2ndary stage while it was in block state..
  • 3. Re: how to pass values from one stage to other
    James_D Guru
    Currently Being Moderated
    You can block the execution of a method by having the thread on which it's running wait (by some mechanism) until some condition is true. It doesn't really make sense to talk about blocking a stage, as the stage is an object, not a method (or thread).

    My first example does what you ask. The showAndWait() method causes the thread to wait until the window that is shown closes. So the handle(...) method will block at that point, as you require.

    If you are looking to block the start(...) method, I don't think you can do that. The start(...) method is executed on the FX Application Thread. The handle(...) method which responds to the button being pressed (and causes the secondary stage to be shown) is also executed on the FX Application Thread. So if you block in the start(...) method, the handle(...) method will never get a chance to execute, so the secondary stage never gets shown, and so the condition you are waiting for will never arise. This is deadlock.

    But you're kind of trying to avoid using all the functionality that the Java FX event handling model provides. The idea is that you're writing event-driven code. Use the start(...) method to set up the UI and register event handlers. The event handlers are invoked for you by the FX system when events occur; these events can be user events (user pressed a button), or other events (tasks completing or changing state, or FX properties' values changing).

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points