0

I am building an simple javafx application using afterburner. I have main window which have a border pane and it's upper part contains menus and in center it have a vertical split pane which have two anchor panes with fx:id=inputPane and fx:id=tablePane. Now in inputPane i am loading different scenes and submitting data from it into tablePane.

Now i have a scene opened in inputPane which have a button and i want to submit the data from this scene into table as well as i want to open an another scene into inputPane and again want to submit it's data into table.

adara.fxml

<BorderPane fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity"  minHeight="180.0" minWidth="-Infinity" prefHeight="507.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.qaf.presentation.adara.AdaraPresenter">
<top>
  <Pane prefHeight="26.0" prefWidth="800.0" BorderPane.alignment="CENTER">
     <children>
        <MenuBar fx:id="menuBar" prefHeight="25.0" prefWidth="800.0">
           <menus>
              <Menu mnemonicParsing="false" text="Stock">
                 <items>
                    <MenuItem fx:id="createStock" mnemonicParsing="false" onAction="#showCreateStockForm" text="Create" />
                    <MenuItem fx:id="incoming" mnemonicParsing="false" onAction="#showIncomingForm" text="Incoming" />
                 </items>
              </Menu>
           </menus>
        </MenuBar>
     </children>
  </Pane>
</top>
 <center>
  <SplitPane dividerPositions="0.5" orientation="VERTICAL" prefHeight="469.0" prefWidth="800.0" BorderPane.alignment="CENTER">
    <items>
        <BorderPane fx:id="contentBorderPane" prefHeight="200.0" prefWidth="200.0">
           <center>
              <AnchorPane fx:id="contentBox" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
           </center>
        </BorderPane>
      <AnchorPane fx:id="tableBox" minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0" />
    </items>
  </SplitPane>
</center>
</BorderPane>

adaraView.java

public class AdaraView extends FXMLView {

}

adaraPresenter.java

public class AdaraPresenter implements Initializable {
    @FXML
    AnchorPane contentBox;
    @FXML
    AnchorPane tableBox;


    StockCreationPresenter stockCreationPresenter;
    InwardsPresenter inwardsPresenter;
    ViewStockPresenter viewStockPresenter;



    @Override
    public void initialize(URL location, ResourceBundle resources) {       
        StockCreationView scView = new StockCreationView();  

        // other codes     
        .
        .


        ViewStockView vsView = new ViewStockView();

        // other codes     
        .
        .

        contentBox.getChildren().add(scView.getView());
        tableBox.getChildren().add(vsView.getView());
    }

    public void showCreateStockForm(){
        StockCreationView scView = new StockCreationView();

        // other codes     
        .
        .
        ViewStockView vsView = new ViewStockView();

        // other codes     
        .
        .

        contentBox.getChildren().add(scView.getView());
        tableBox.getChildren().add(vsView.getView());
    }
    public void showIncomingForm(){
        InwardsView inView = new InwardsView();

        // other codes     
        .
        .

        ViewStockView vsView = new ViewStockView();

        // other codes     
        .
        .

        contentBox.getChildren().add(inView.getView());
        tableBox.getChildren().add(vsView.getView());
    }
}

Here is the main class which is starting the stage and application.

Main.java

public class App extends Application
{
    @Override
    public void start(Stage stage) throws Exception {        
        AdaraView appView = new AdaraView();       
        Scene scene = new Scene(appView.getView());    
        stage.setTitle("Adara");
        final String uri = getClass().getResource("app.css").toExternalForm();        
        scene.getStylesheets().add(uri);
        stage.setScene(scene);
        stage.show();
    }

    @Override
    public void stop() throws Exception {        
        Injector.forgetAll();
    }

    public static void main(String[] args) {        
        launch(args);
    }
}

Now here is the InwardsPresenter.java which have to save the stockCreationPresenter.java data into table as well as it have to open the inwardsView into the contentPane.

InwardsPresenter.java

public class InwardsPresenter implements Initializable {
    @FXML
    Button saveButton;
    @FXML 
    TextField orderNo;
    @FXML 
    TextField other;
    @FXML
    CheckBox save;

    @Inject
    AdaraPresenter adaraPresenter;

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

    }


    public void save() {

        Inwards inward = newInward();

        inward.setOrderNo(Integer.parseInt(orderNo.getText()));
        inward.setOther(other.getText());
        inward.setSave(save.isSelected());

        this.newInward.set(inward);

        adaraPresenter.incomingForm();
    }
} 

// while executing adaraPresenter.incomingForm(); it's showing NPE to contentBox and tableBox.

                 Thank you very much for any help.
Nazim
  • 209
  • 5
  • 17
  • possible duplicate of [JavaFx: how to reference main Controller class instance from CustomComponentController class?](http://stackoverflow.com/questions/17550578/javafx-how-to-reference-main-controller-class-instance-from-customcomponentcont) – aw-think Jul 12 '15 at 16:23
  • I got through that link @NwDx it's not the same, i got access to the controller but not to the UI component. I want to access UI component of one presenter from another presenter.. – Nazim Jul 12 '15 at 16:51
  • I think you have a reference to a different presenter instance than the one that was generated by loading the FXML file. But there is a fundamental problem with what you're trying to do here. Afterburner is an implementation of the Model-View-Presenter pattern. Accessing components belonging to one view from the presenter for another view basically violates that pattern. You need these to interact via some shared model. – James_D Jul 12 '15 at 17:21
  • Thank you very much @James_D for pointing out that fundamental problem but how can i achieve my requirement ? By interacting via shared model do you mean creating a viewModel and use it wherever i need it, or using some property binding and listeners ? I tried both these methods but it's not helping me. Thanks again. – Nazim Jul 13 '15 at 06:52
  • The "proper" way would be to create a view model, inject it into the presenters that need access to it, and bind/observe properties in it. But note on your `FXMLView` subclasses, you can also call `getPresenter()` to get a reference to the presenter; e.g. in your `showIncomingForm` method, you can do `InwardsView inView = new InwardsView();` `InwardsPresenter inPresenter = (InwardsPresenter)inView.getPresenter();` which means you can then communicate between the two presenters. – James_D Jul 13 '15 at 14:15
  • I already tested injecting `viewModel` @James_D and i know how to communicate using `getPresenter()`. My concern is very simple, if i have to replace a scene on a button click event to the same area (pane) where event is taking place then how would i do that without accessing that area (pane) while the scene i am replacing have a different presenter than one i am replacing with. – Nazim Jul 14 '15 at 07:14
  • Somebody please help me with this.. – Nazim Jul 26 '15 at 05:15

0 Answers0