7

I have problem when trying to close current scene and open up another scene when menuItem is selected. My main stage is coded as below:

public void start(Stage primaryStage) throws Exception {
   primaryStage.setTitle("Shop Management");
   Pane myPane = (Pane)FXMLLoader.load(getClass().getResource
("createProduct.fxml"));
   Scene myScene = new Scene(myPane);        
   primaryStage.setScene(myScene);
   primaryStage.show();
}

Then within createProduct.fxml, when menuItem is onclick, it will perform this:

public void gotoCreateCategory(ActionEvent event) throws IOException {
    Stage stage = new Stage();
    stage.setTitle("Shop Management");
    Pane myPane = null;
    myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
    Scene scene = new Scene(myPane);
    stage.setScene(scene);
    stage.show();
}

It does opened up createCategory.fxml. However, the previous panel which is createProduct.fxml does not close. I know there's something called stage.close() to do this but I have no idea where to implement it since I not passing the scene from main right from the start. I wonder how should I fix this.

Thanks in advance.

  • Are you sure you have to open the other screen (createCategory.fxml) in new stage? – Shreyas Dave Jun 21 '13 at 03:42
  • I am trying to do like you know Jframe? The getJFrame().dispose(); eForumForgotPwd myWindow = new eForumForgotPwd(); myWindow.getJFrame().setVisible(true); I need to close the current window before opening a new one –  Jun 21 '13 at 03:48

3 Answers3

10

You have to make some changes in start method, like..

public void start(Stage primaryStage) throws Exception {
   primaryStage.setTitle("Shop Management");

   FXMLLoader myLoader = new FXMLLoader(getClass().getResource("createProduct.fxml"));

   Pane myPane = (Pane)myLoader.load();

   CreateProductController controller = (CreateProductController) myLoader.getController();

   controller.setPrevStage(primaryStage);

   Scene myScene = new Scene(myPane);        
   primaryStage.setScene(myScene);
   primaryStage.show();
}

and your CreateProductController.java will be,

public class CreateProductController implements Initializable {

    Stage prevStage;

    public void setPrevStage(Stage stage){
         this.prevStage = stage;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
    }

    public void gotoCreateCategory(ActionEvent event) throws IOException {
       Stage stage = new Stage();
       stage.setTitle("Shop Management");
       Pane myPane = null;
       myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
       Scene scene = new Scene(myPane);
       stage.setScene(scene);

       prevStage.close();

       stage.show();
    }

}
Shreyas Dave
  • 3,815
  • 3
  • 28
  • 57
  • Wow thanks. It worked perfectly. Really really thanks alot. So basically you pass the primaryStage into the setPreviousStage method in controller to get the previousStage. And then you close it? Am I explained in the correct way? –  Jun 21 '13 at 04:12
  • But I still have a problem. For example my window is all textfield. When I go from category window to product window without filling up the text field, I got null pointer exception error –  Jun 21 '13 at 04:26
  • Add validation on your textfield, and check for null. – Shreyas Dave Jun 21 '13 at 04:30
  • What I mean is I can just browse around the window. validation only when create button is on click. –  Jun 21 '13 at 04:33
  • I cant understand what you are trying to make, kindly explain in detail. – Shreyas Dave Jun 21 '13 at 04:36
  • Okay sorry. For example, I have create product and create category page. All their fields are make up of text fields. What I am trying to do is, for example I click on create category. Without filling up anything, I can switch to create product panel. From your codes, I can only switch one page. For example, I set my first page as home. Then i click on home again. after that the panel cant be switch anymore –  Jun 21 '13 at 04:41
  • How should I amend the code if I want to close and open up another window when choosing from menu bar? Because your code only work for once, which is from the default main page to any other page only –  Jun 24 '13 at 11:51
  • The is not the correct way to code by opening different stages for different screens, you should do it in a single stage only. Give some link or screenshots for what you exactly want to do. – Shreyas Dave Jun 24 '13 at 11:58
  • Okay what I wanted to do is like user choose from navigation bar, let's say I got create product and create category in navigation bar. Then from the start method, I set the first page as cartHomePage. From there, I can either go to create product or create category. It should works like a shopping cart, you can go whatever is inside navigation bar. I've been researched these few days but no luck. –  Jun 24 '13 at 12:04
  • Thanks for the answer.. it helped me to switch to my new panel. Now i'm implementing a "Back" button, that should bring me back the to Main Menu, which is the page just before the 2nd Panel that I got in, for example in Carol's question the primaryStage. How can I do that? – ZelelB Apr 16 '14 at 17:55
3

You have multiple ways to solve your problem, few of them I tell you. What I understood from your question is that you want to create an application which contains a navigation (menu bar) on the top and by using it user can switch to any screen.

The easiest method is to make your Navigation Bar available globally, either by you make it static or by passing it to screens, or by any other method. Second, make a single screen (say Border Pane) and load other screens on it (its center).

You can also use spring integration in project so that it provide you better injection of controllers. See Ref : http://www.zenjava.com/2011/10/25/views-within-views-controllers-within-controllers/

You can also create your own single screen controller and manage other screens using that. See Ref: https://blogs.oracle.com/acaicedo/entry/managing_multiple_screens_in_javafx1

But for this (above) you have to change or update your current architecture.

Shreyas Dave
  • 3,815
  • 3
  • 28
  • 57
  • So basically the class which contain the start method is just only set the default page to run? And from the default page, I set the navigation bar to static and ? –  Jun 24 '13 at 13:26
  • 2
    Both links are dead. – zygimantus Jun 07 '18 at 11:36
0

you can get the current open window/stage from the fx:id . just make sure you have an item in your createProduct.fxml that has fx:id like below

<TextField fx:id="username" labelFloat="true" layoutX="80.0" layoutY="300.0" prefHeight="32.0" prefWidth="260.0" promptText="Login Username" />

Hope you see the fx:id attribute.

Then in your start controller, leave as it is

    public void start(Stage primaryStage) throws Exception {
   primaryStage.setTitle("Shop Management");
   Pane myPane = (Pane)FXMLLoader.load(getClass().getResource("createProduct.fxml"));
   Scene myScene = new Scene(myPane);        
   primaryStage.setScene(myScene);
   primaryStage.show();
}

Then in your CreateProductController.java

//make sure you import the javafx item you have used, eg have used TextField
import javafx.scene.control.TextField;

    public class CreateProductController implements Initializable {
// make sure the variable has the same type as the item in the fxml "TextField" and same name "username"
    @FXML
    private TextField username;
//we use the above variable since its referencing the window to which it belongs because of the fx:id attribute, then we close it
    private void closeStage() 
    {
      ((Stage) username.getScene().getWindow()).close();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
    }

    public void gotoCreateCategory(ActionEvent event) throws IOException {
       closeStage();// we close the old stage
       Stage stage = new Stage();
       stage.setTitle("Shop Management");
       Pane myPane = null;
       myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
       Scene scene = new Scene(myPane);
       stage.setScene(scene);    
       stage.show();
    }
}
MAYOBYO HASSAN
  • 467
  • 6
  • 10