0

I have a problem with one of my first javafx program/project. I need to make main fxml scene where I can insert some buttons and some another fxml's pages into main scene. I would like to be able to move to the left or right pages by two left/right buttons and could edit 'Label' field on the loaded fxml pages.

I'm trying to display these pages in the BorderPane area on main scene. I load another pages using javafx Controller and it works, but when I try to set 'Label' field (named 'counter') on loaded fxml page1 I have an error that this label field in Controller is null. (I set this one controller for all pages)

My Controller:

public class Controller implements Initializable {

    @FXML
    private Button Start;

    @FXML
    private BorderPane computer;

    @FXML
    private Label counter;

    int status = 0, next=0;

    @FXML
    void onPressed(ActionEvent event) {
        counter.setText(String.valueOf(next));
        next += 1;
    }

    @FXML
    void startComputer() throws IOException {
        loadPage("page1");
        setStatus(1);
    }

    @FXML
    void right_navigation(ActionEvent event) throws IOException {
        if(getStatus() == 1) {
            loadPage("page2");
            setStatus(2);
        } else if(getStatus() == 2){
            loadPage("page3");
            setStatus(3);
        } else if(getStatus() == 3){
            loadPage("page4");
            setStatus(4);
        } else if(getStatus() == 4){
            loadPage("page1");
            setStatus(1);
        }
    }

    @FXML
    void left_navigation(ActionEvent event) throws IOException {
        if(getStatus() == 4){
            loadPage("page3");
            setStatus(3);
        } else if(getStatus() == 3) {
            loadPage("page2");
            setStatus(2);
        } else if(getStatus() == 2){
            loadPage("page1");
            setStatus(1);
        } else if(getStatus() == 1){
            loadPage("page4");
            setStatus(4);
        }
    }

    private void loadPage(String page) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource(page + ".fxml"));
        computer.setCenter(root);
    }

    private void setStatus(int status){
        this.status = status;
    }

    private int getStatus(){
        return status;
    }

}

Main fxml scene:

<?import javafx.scene.image.Image?>
<GridPane alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
    <children>
        <AnchorPane prefHeight="600.0" prefWidth="800.0">
            <children>
                <Button fx:id="start" layoutX="520.0" layoutY="540.0" mnemonicParsing="false" onAction="#startComputer" text="Start" />
                <Button fx:id="count" layoutX="620.0" layoutY="540.0" mnemonicParsing="false" onAction="#onPressed" text="Count" />
                <Button fx:id="left" layoutX="150.0" layoutY="540.0" mnemonicParsing="false" onAction="#left_navigation" text="&lt;" />
                <Button fx:id="right" layoutX="180.0" layoutY="540.0" mnemonicParsing="false" onAction="#right_navigation" text="&gt;" />
                <BorderPane fx:id="computer" layoutX="300.0" layoutY="200.0" prefHeight="200.0" prefWidth="180.0" styleClass="comp_display" stylesheets="@../myCss.css" />
            </children>
        </AnchorPane>
    </children>
</GridPane>

One of fxml pages in BorderPane:

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
   <top>
   </top>
   <center>
      <AnchorPane prefHeight="186.0" prefWidth="144.0" styleClass="page_screen" stylesheets="@../myCss.css" BorderPane.alignment="CENTER">
         <children>
            <Label fx:id="counter" layoutX="51.0" layoutY="59.0" text="0" />
         </children>
      </AnchorPane>
   </center>
</BorderPane>

I would like to set 'counter' Label on fxml page1 from Controller. But is it possible to set this fxml pages by one controller? Maybe there are some other ways instead of load BorderPane in main scene. I would be grateful for help.

anocyney_
  • 1
  • 3
  • 4
    It's "possible" to have multiple FXML files mapped to one controller, yes. But you don't want to do that. Each FXML file should have at most one related controller class. Then you communicate between the controller instances as needed (or better yet, share a model between the controllers and communicate through said model). See [Passing Parameters JavaFX FXML](https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml) and [Applying MVC With JavaFx](https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx). – Slaw Dec 30 '20 at 02:05
  • 1
    java naming conventions please – kleopatra Dec 30 '20 at 03:26
  • @Slaw But if i can mapped more than one FXML files to one controller, I didn't understand why I can't set 'counter' Label by my onPressed method after load this FXML page by loadPage method? I get error: Cannot invoke "javafx.scene.control.Label.setText(String)" because "this.counter" is null. I need to initialize this Label before? – anocyney_ Dec 30 '20 at 17:13
  • Because each FXML gets its own instance and which fields are injected depend on which FXML file was loaded. You really don't want to map multiple FXML files to one controller class. It's messy and confusing and bad practice. – Slaw Dec 30 '20 at 21:28

0 Answers0