0

Relevant Files: (apologies on any formatting, made many attempts to make it work)

If the files are not sufficient, the repository is here: https://github.com/TheeNinja/StockLookupTool

stock_lookup_tool_main.fxml

<BorderPane fx:id="borderPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.112" xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.theeninja.stocklookuptool.gui.StockLookupToolApplicationController">
<top>
    ...    
</top>
<left />
<center /> 
</BorderPane>

stock_information_center.fxml

<GridPane xmlns="http://javafx.com/javafx"
        xmlns:fx="http://javafx.com/fxml"
        fx:controller="me.theeninja.stocklookuptool.gui.selection.StockSearchSelectionController"
        prefHeight="400.0" prefWidth="600.0"
        fx:id="stockInformationCenter">

</GridPane>

favorite_stocks_sidebar.fxml

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="me.theeninja.stocklookuptool.gui.selection.StockSearchSelectionController" fx:id="verticalStockList">
    ...
</VBox>

StockLookupTool.java (Class with the start method)

public class StockLookupTool extends Application {


....
@Override
public void start(Stage stage) throws Exception {

    ...
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("/fxml/stock_lookup_tool_main.fxml"));
    Parent root = loader.load();

    Scene scene = new Scene(root, 250, 300);

    stage.setTitle(APPLICATION_TITLE);
    stage.setScene(scene);
    stage.setFullScreen(true);
    stage.show();
}
....
}

StockLookupToolApplicationController (controller for stock_lookup_tool_main.fxml)

public class StockLookupToolApplicationController {

...

@FXML public Label stockSearchLabel;
@FXML public Label newsLabel;
@FXML public Label settings;

@FXML public BorderPane borderPane;
@FXML public HBox topApplicationNavigation;

@FXML
public void handleStockSearchSelection() {
    logger.log(Level.INFO, "Setting GUI View to Stock Search");
    setView(StockSearchSelectionController.getInstance());
}

private void setView(Selection selection) {
    borderPane.setLeft(selection.getLeft());
    borderPane.setCenter(selection.getCenter());
    borderPane.setRight(selection.getRight());
    borderPane.setBottom(selection.getBottom());
}
}

StockSearchSelectionController.java (controller for both stock_information_center.fxml and favorite_stocks_sidebar.fxml)

public class StockSearchSelectionController implements Selection {

@FXML public Label favoriteStocksLabel;
@FXML public TextField addFavoriteStockInput;
@FXML public VBox verticalStockList;
@FXML public HBox addFavoriteStockInputContainer;
@FXML public GridPane stockInformationCenter;

@FXML
public void handleFavoriteStockInput(KeyEvent keyEvent) {
    if (keyEvent.getCode() == KeyCode.ENTER) {
    ...
        // makes visual changes to both stockInformationCenter AND verticalStockList, hence I need access to both fxml files (which is why this controls both).
    }
}

@Override
public Node getLeft() {
    return verticalStockList;
}

@Override
public Node getCenter() {
    return stockInformationCenter;
}
}

More information:

The interface Selection has the methods getLeft() and getCenter() (among other irrelevant ones). Both of these returns Node. In stock_lookup_tool_main.fxml, in the top portion of the BorderPane I have a button (cut out in the provided snippet) that, when pressed, calls handleStockSearchSelection() (this method call indeed happens, I have verified it with a logger).

Now there is a controller, that controls both stock_information_center.fxml and favorite_stocks_sidebar.fxml. This controller implements Selection, and in turn, implements getLeft() and getCenter(). getLeft() returns the VBox variable that correlates to favorite_stocks_sidebar.fxml, while getCenter() returns the GridPane variable that correlates to stock_information_center.fxml. When handleStockSearchSelection() is called, the left part of the borderPane object is set to the VBox, and the center is set to the GridPane. All these method calls/actions have been verified to occur. However, there is no visual change to the scene.

My question is: Why are these changes to borderPane not implemented visually in the scene? I have established a link between the scene <-> stock_lookup_tool_main.fxml through setting the loader's location. I have also established a link between stock_lookup_tool_main.fxml <-> its controller, hence they should share changes. I have modified the border pane in stock_lookup_tool_main.fxml in the controller by calling setLeft() and setCenter() on the variable (same name as the ID, borderPane). Yet, the scene visually does not change.

Mario Ishac
  • 5,060
  • 3
  • 21
  • 52
  • *"Now there is a controller, that controls both `stock_information_center.fxml` and `favorite_stocks_sidebar.fxml`. "* It seems unlikely you are actually using the same controller for both: I think you mean that both controllers are from the same class. I strongly don't recommend doing that; it's almost impossible to keep track of which fields are initialized in which controller. Anyway, you should create and post a [MCVE] in your actual question; otherwise it is just guesswork. – James_D Nov 12 '17 at 15:43
  • @James_D The way I have implemented it (edited the class StockSearchSelectionController inside the OP), the class does control both, and thus has java variables correlating to the fxml nodes of both of the fxml files. The reason I have one controller for two fxml files is because when handleFavoriteStockInput() of class StockSearchSelectionController and of fxml file favorite_stocks_sidebar.fxml is called, I need access to the contents of the other controlled fxml file as well. How else would I implement it? – Mario Ishac Nov 12 '17 at 19:25
  • Can you show the code that ensures you are actually using the *same controller* (not just making both controllers the same class) when you load both FXML files? Also, it would be helpful if you would make your language more precise, e.g.: *"the class does control both"* doesn't make sense (the *class* doesn't control anything: the controller(s), which are instance(s) of the appropriate class(es) control the UI). I can't see that you have one controller for two FXML files; you just seem to have made both controllers instances of the same class. – James_D Nov 12 '17 at 19:27
  • @James_D So I did some clarifying research based on the questions you asked and it appears I have misunderstood controllers entirely. Based on what I've read, a new instance of the controller is created for each fxml file even if it is the same class. So, to answer your question: no, I only specified the class name of the controller is the fx:controller attribute of each fxml file. Apparently, that means they don't use the same instance based on what I have read. How can I share the data between the two fxml files if the controller's values for the instance variables won't be preserved across? – Mario Ishac Nov 12 '17 at 19:34
  • Before this, I thought that JavaFX would correlate the fxml files to the same instance of a controller (just by specifying the class name in fx:controller) so I could share the data. – Mario Ishac Nov 12 '17 at 19:36
  • *"a new instance of the controller is created for each fxml file"*. By default, a new instance of the controller class is created when you load the FXML (whether you load the same FXML file twice, or two different FXML files that specify the same controller class). The recommended approach would be to use a different controller class for each FXML file, and [pass information between the controllers](https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml). – James_D Nov 12 '17 at 19:37
  • *"I thought that JavaFX would correlate the fxml files to the same instance of a controller "* How would that work? What if you wanted to load the same FXML twice and display two copies in your application (e.g., a text editor that edited different files in different tabs in a tab pane)? You would only be able to get a single reference to the controls, even though multiple controls were displayed. – James_D Nov 12 '17 at 19:38
  • Duplicate of https://stackoverflow.com/questions/30464857/one-controller-to-2-fxmls-javafx (and perhaps also https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml). – James_D Nov 12 '17 at 19:44
  • Okay, I understand what I need to fix. Thank you for your help @James_D – Mario Ishac Nov 12 '17 at 19:49

0 Answers0