1

I have a pane with 10 films, and every time the user clicks on a film thumbnail, I have a method that will take the user to a tickets page where they can select how many tickets they'd like to buy. However, I'm trying to figure out how to pass the Film object loadTicketPage in the Controller class for the called tickets page, when I call the film object from the movie page Controller.

public class controller {
    public void initialize() {
        film1.setImage(getFilmFromList(0).getThumbnail());
        film2.setImage(getFilmFromList(1).getThumbnail());
        film3.setImage(getFilmFromList(2).getThumbnail());
        film4.setImage(getFilmFromList(3).getThumbnail());
        film5.setImage(getFilmFromList(4).getThumbnail());
        film6.setImage(getFilmFromList(5).getThumbnail());
        film7.setImage(getFilmFromList(6).getThumbnail());
        film8.setImage(getFilmFromList(7).getThumbnail());
        film9.setImage(getFilmFromList(8).getThumbnail());
        film10.setImage(getFilmFromList(9).getThumbnail());

    }

    public void loadTicketPage(Film film) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("ticketsPage.fxml"));

            Scene scene = new Scene(root);
            Stage stage = new Stage();

            stage.initModality(Modality.APPLICATION_MODAL);

            stage.setScene(scene);
            stage.setTitle("Ticket Page");
            stage.show();

        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void film1() {
        Double price = getFilmFromList(0).getPrice();
        String title = getFilmFromList(0).getFilmName();
        loadTicketPage(getFilmFromList(0));

    }

    public void film2() {
        Double price = getFilmFromList(1).getPrice();
        String title = getFilmFromList(1).getFilmName();
        loadTicketPage(getFilmFromList(1));
    }
}

public class TicketsPageController {
    public Label filmName;
    public Label filmDescription;

    public void initialize() {
        filmName.setText(film.getFilmTitle)
    }
}

Here is fxml file for the ticketsPage:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.String?>
<?import javafx.collections.FXCollections?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.effect.SepiaTone?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>

<AnchorPane prefHeight="670.0" prefWidth="1000.0" style="-fx-background-color: maroon;" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TicketsPageController">
   <children>
      <Label fx:id="lblHello" layoutX="308.0" layoutY="9.0" prefHeight="94.0" prefWidth="460.0" text="Hello! Welcome to Cinema Enterpriso" textAlignment="CENTER" textFill="WHITE" wrapText="true">
         <font>
            <Font name="Broadway" size="30.0" />
         </font>
      </Label>
      <ImageView fitHeight="141.0" fitWidth="297.0" layoutX="10.0" layoutY="10.0" pickOnBounds="true" preserveRatio="true">
         <image>
            <Image url="@images/University_of_Huddersfield_logo.jpg" />
         </image>
      </ImageView>
      <Button fx:id="btnOpenLogin" layoutX="770.0" layoutY="46.0" mnemonicParsing="false" onAction="#btnOpenLoginClick" style="-fx-background-color: tan;" text="Login">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnSignUp" layoutX="840.0" layoutY="46.0" mnemonicParsing="false" onAction="#btnCreateNewUser" style="-fx-background-color: tan;" text="Sign Up">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnBasket" layoutX="925.0" layoutY="46.0" mnemonicParsing="false" onAction="#btnOpenOrderSummary" style="-fx-background-color: tan;" text="Basket">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Label layoutX="35.0" layoutY="328.0" text="Please select your tickets:" textFill="WHITE">
         <font>
            <Font name="Broadway" size="24.0" />
         </font>
      </Label>
      <ComboBox fx:id="ticketType1" layoutX="51.0" layoutY="383.0" prefWidth="150.0" promptText="Ticket type" style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="Adult"> </String>
               <String fx:value="Child"> </String>
               <String fx:value="Teen"> </String>
               <String fx:value="Student"> </String>
               <String fx:value="Senior"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="ticketType2" layoutX="51.0" layoutY="437.0" prefWidth="150.0" promptText="Ticket type" style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="Adult"> </String>
               <String fx:value="Child"> </String>
               <String fx:value="Teen"> </String>
               <String fx:value="Student"> </String>
               <String fx:value="Senior"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="ticketType3" layoutX="51.0" layoutY="489.0" prefWidth="150.0" promptText="Ticket type" style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="Adult"> </String>
               <String fx:value="Child"> </String>
               <String fx:value="Teen"> </String>
               <String fx:value="Student"> </String>
               <String fx:value="Senior"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="ticketType4" layoutX="51.0" layoutY="541.0" prefWidth="150.0" promptText="Ticket type" style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="Adult"> </String>
               <String fx:value="Child"> </String>
               <String fx:value="Teen"> </String>
               <String fx:value="Student"> </String>
               <String fx:value="Senior"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="ticketType5" layoutX="51.0" layoutY="592.0" prefWidth="150.0" promptText="Ticket type" style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
          <items>
              <FXCollections fx:factory="observableArrayList">
                  <String fx:value="Adult"> </String>
                  <String fx:value="Child"> </String>
                  <String fx:value="Teen"> </String>
                  <String fx:value="Student"> </String>
                  <String fx:value="Senior"> </String>
              </FXCollections>
          </items>
      </ComboBox>
      <ComboBox fx:id="no1" layoutX="218.0" layoutY="383.0" prefHeight="31.0" prefWidth="79.0" promptText="no." style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="1"> </String>
               <String fx:value="2"> </String>
               <String fx:value="3"> </String>
               <String fx:value="4"> </String>
               <String fx:value="5"> </String>
               <String fx:value="6"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="no2" layoutX="217.0" layoutY="435.0" prefHeight="31.0" prefWidth="79.0" promptText="no." style="-fx-background-color: tan;">

         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="1"> </String>
               <String fx:value="2"> </String>
               <String fx:value="3"> </String>
               <String fx:value="4"> </String>
               <String fx:value="5"> </String>
               <String fx:value="6"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="no3" layoutX="217.0" layoutY="488.0" prefHeight="31.0" prefWidth="79.0" promptText="no." style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="1"> </String>
               <String fx:value="2"> </String>
               <String fx:value="3"> </String>
               <String fx:value="4"> </String>
               <String fx:value="5"> </String>
               <String fx:value="6"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="no4" layoutX="218.0" layoutY="542.0" prefHeight="31.0" prefWidth="79.0" promptText="no." style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="1"> </String>
               <String fx:value="2"> </String>
               <String fx:value="3"> </String>
               <String fx:value="4"> </String>
               <String fx:value="5"> </String>
               <String fx:value="6"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <ComboBox fx:id="no5" layoutX="217.0" layoutY="594.0" prefHeight="31.0" prefWidth="79.0" promptText="no." style="-fx-background-color: tan;">
         <effect>
            <SepiaTone />
         </effect>
         <items>
            <FXCollections fx:factory="observableArrayList">
               <String fx:value="1"> </String>
               <String fx:value="2"> </String>
               <String fx:value="3"> </String>
               <String fx:value="4"> </String>
               <String fx:value="5"> </String>
               <String fx:value="6"> </String>
            </FXCollections>
         </items>
      </ComboBox>
      <Label fx:id="filmName" layoutX="521.0" layoutY="123.0" text="Film" textFill="WHITE">
         <font>
            <Font name="Broadway" size="30.0" />
         </font>
      </Label>
      <Label fx:id="filmDescription" layoutX="485.0" layoutY="189.0" text="Description" textFill="WHITE">
         <font>
            <Font name="Broadway" size="24.0" />
         </font>
      </Label>
      <Button fx:id="btnAddToOrder1" layoutX="325.0" layoutY="383.0" mnemonicParsing="false" onAction="#btnAddTicketToOrder1" style="-fx-background-color: tan;" text="Add to order" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnAddToOrder2" layoutX="325.0" layoutY="435.0" mnemonicParsing="false" onAction="#btnAddTicketToOrder2" style="-fx-background-color: tan;" text="Add to order" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnAddToOrder3" layoutX="325.0" layoutY="489.0" mnemonicParsing="false" onAction="#btnAddTicketToOrder3" style="-fx-background-color: tan;" text="Add to order" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnAddToOrder4" layoutX="325.0" layoutY="541.0" mnemonicParsing="false" onAction="#btnAddTicketToOrder4" style="-fx-background-color: tan;" text="Add to order" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnAddToOrder5" layoutX="325.0" layoutY="595.0" mnemonicParsing="false" onAction="#btnAddTicketToOrder5" style="-fx-background-color: tan;" text="Add to order" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
      <Button fx:id="btnBackHomepage" layoutX="485.0" layoutY="594.0" mnemonicParsing="false" onAction="#btnBackToHomePageClick" prefHeight="31.0" prefWidth="155.0" style="-fx-background-color: tan;" text="Back to Homepage" textFill="MAROON">
         <effect>
            <SepiaTone />
         </effect>
      </Button>
   </children>
</AnchorPane>

Here is the stacktrace:

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
    ... 45 more
Caused by: java.lang.NullPointerException
    at sample.TicketsPageController.setStuff(TicketsPageController.java:54)
    at sample.TicketsPageController.initialize(TicketsPageController.java:41)
    ... 55 more

Here is my TicketPageController

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.stage.Window;

import java.io.IOException;

public class TicketsPageController {
    public Label lblHello;
    public Button btnOpenLogin;
    public Button btnSignUp;
    public Button btnBasket;
    public Label filmName;
    public Label filmDescription;
    public ComboBox ticketType1;
    public ComboBox ticketType2;
    public ComboBox ticketType3;
    public ComboBox ticketType4;
    public ComboBox ticketType5;
    public ComboBox no1;
    public ComboBox no2;
    public ComboBox no3;
    public ComboBox no4;
    public ComboBox no5;
    public Button btnAddToOrder1;
    public Button btnAddToOrder2;
    public Button btnAddToOrder3;
    public Button btnAddToOrder4;
    public Button btnAddToOrder5;
    public Button btnBackHomepage;
    private String filmTitle;

    private Film film;

    public void initialize() {
          setStuff();
//        System.out.println(filmTitle);
          filmName.setText(filmTitle);
    }

//    public void setFilm(Film film) {
//        System.out.println("in set film");
//        this.film = film;
//
//    }

    public void setFilm(Film film) {
        this.film = film;
        filmName.setText(film.getFilmName());
    }

    public void setStuff() {
        System.out.println("test");
        filmTitle = film.getFilmName();
    }

    public String printFilm(){
        return film.getFilmName();
    }

    public void btnOpenLoginClick(ActionEvent actionEvent) {
        printFilm();
    }

    public void btnCreateNewUser(ActionEvent actionEvent) {
    }

    public void btnOpenOrderSummary(ActionEvent actionEvent) {
    }

    public void btnAddTicketToOrder1(ActionEvent actionEvent) {
    }

    public void btnAddTicketToOrder2(ActionEvent actionEvent) {
    }

    public void btnAddTicketToOrder3(ActionEvent actionEvent) {
    }

    public void btnAddTicketToOrder4(ActionEvent actionEvent) {
    }

    public void btnAddTicketToOrder5(ActionEvent actionEvent) {
    }

    public void btnBackToHomePageClick(ActionEvent actionEvent) throws IOException {
        Window mainWindow = btnBackHomepage.getScene().getWindow();
        Parent newRoot = FXMLLoader.load(getClass().getResource("homepage.fxml"));
        mainWindow.getScene().setRoot(newRoot);
    }
}
  • I have seen that before, however I didn't really understand it, and I don't think it matches my question – Karishma Parmar Mar 17 '19 at 21:27
  • You could add a method in your `ticketsPage` controller that accepts a `Film` object? Then, just call that method after initializing that controller. – Zephyr Mar 17 '19 at 21:31

1 Answers1

1

During the load process of the new Pane you can get the controller from the FXMLLoader and pass the film to it:

public void loadTicketPage(Film film){
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("ticketsPage.fxml"));

        Scene scene = new Scene(loader.load());
        Stage stage = new Stage();

        stage.initModality(Modality.APPLICATION_MODAL);

        stage.setScene(scene);
        stage.setTitle("Ticket Page");

        // get the controller and set the film
        TicketsPageController controller = loader.getController();
        controller.setFilm(film);

        stage.show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Assuming your controller looks like the following:

public class TicketsPageController {
    private Film film;

    public Label filmName;
    public Label filmDescription;

    public void setFilm(Film film) {
        this.film = film;
        filmName.setText(film.getFilmTitle());
    }
}
Samuel Philipp
  • 10,631
  • 12
  • 36
  • 56
  • Thank you! Most of it seems all okay, but I'm now having a problem with my initialise method that is giving me a LoadException, I'll paste it below: public void initialize() { filmName.setText(film.getFilmName()); } – Karishma Parmar Mar 17 '19 at 22:23
  • UPDATE: I have tested this with a button, and it printed the film name correctly. However, when I tried it in the initialize method, I received the LoadException. My friend has experienced a similar issue, and he fixed it by making the method static, but I cannot do this as I need to call a field of the film object – Karishma Parmar Mar 18 '19 at 00:09
  • @KarishmaParmar Can you please add your fxml file to your question? – Samuel Philipp Mar 18 '19 at 07:09
  • 1
    @KarishmaParmar A `LoadException` usually wraps another exception, same as `ExecutionException`, `CompletionException`, and `InvocationTargetException`. You should be looking at the `Caused by:`s to see the actual error. And if you're getting an exception you should [edit your question](https://stackoverflow.com/posts/55212037/edit) to include the [stack trace](https://stackoverflow.com/questions/3988788/). – Slaw Mar 18 '19 at 09:11
  • @SamuelPhilipp I have now edited the question with the fxml file – Karishma Parmar Mar 18 '19 at 12:22
  • @Slaw I am not receiving an error with a stack trace, I'll post below what it is saying: javafx.fxml.LoadException: /C:/Users/karis/IdeaProjects/CinemaEnterpriso/out/production/CinemaEnterpriso/sample/ticketsPage.fxml – Karishma Parmar Mar 18 '19 at 12:24
  • @KarishmaParmar That looks like the `Throwable#toString()` output. For instance, in your `loadTicketPage` method you have `System.out.println(e)`. You should instead use `e.printStackTrace()`. – Slaw Mar 18 '19 at 13:07
  • @Slaw thank you! I have tried that and the error now is stating is: Caused by: java.lang.reflect.InvocationTargetException and Caused by: java.lang.NullPointerException – Karishma Parmar Mar 18 '19 at 13:33
  • @KarishmaParmar can you please add the __complete stacktrace__ to your question? – Samuel Philipp Mar 18 '19 at 15:47
  • @KarishmaParmar I also updated my question, maybe you want to try that again. Another thing I recognized is that the name of the controller you are referencing in your fxml (`fx:controller="sample.TicketsPage"`) is different than the name of the controller you are trying to pass the film to (`TicketsPageController`). Maybe you are using the wrong controller on one place and this is causing the `NullPointerException`. – Samuel Philipp Mar 18 '19 at 15:52
  • @SamuelPhilipp I have added the stack trace to my question, is that the right thing? And sorry I refactored the name of my controller but forgot to update the question on here, I've now changed the question, however I'm still receiving the error – Karishma Parmar Mar 18 '19 at 16:06
  • The problem is, that the `initialize` method is called before `setFilm` is called so `film` is null, which causes the error. Try setting the label text in the `setFilm` method, like I did in my updated question. – Samuel Philipp Mar 18 '19 at 16:11
  • Can you please share the full code or your `TicketsPageController` where the exception happens? – Samuel Philipp Mar 18 '19 at 16:27
  • My full program should be available on the link, please would you be able to have a look on there, as I am really struggling? – Karishma Parmar Mar 18 '19 at 16:31
  • No there is not, please edit your question. – Samuel Philipp Mar 18 '19 at 16:32
  • Okay, I have added the TicketPageController to my question – Karishma Parmar Mar 18 '19 at 16:37
  • The problem is the same thing I mentioned before: `initialize()` is called before `setFilm()`. In the `initialize()` method you are calling `setStuff()` which tries to set `filmTitle = film.getFilmName();`. At this moment `film` is null, which causes the exception. Remove the `setStuff()` statement in your `initialize()` method and it should work. – Samuel Philipp Mar 18 '19 at 16:41