This discussion is archived
5 Replies Latest reply: Nov 13, 2012 6:02 AM by daniel RSS

Manage multi Scene JavaFX 2.2 FXML

967237 Newbie
Currently Being Moderated
I'd like to know that when i change from one Scene to another by action, as TableView, ComboBox, anyway controls. The data don't show that i have sent, even though that when i do a System.Out.Println of them, the Data is there.

How I can fix this?
  • 1. Re: Manage multi Scene JavaFX 2.2 FXML
    jsmith Guru
    Currently Being Moderated
    Please post a small, executable code sample which demonstrates the issue - thanks.
  • 2. Re: Manage multi Scene JavaFX 2.2 FXML
    967237 Newbie
    Currently Being Moderated
    this is my code..

    JavaFXApplication16.java

    package javafxapplication16;

    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.JavaFXBuilderFactory;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.layout.AnchorPane;
    import javafx.stage.Stage;

    public class JavaFXApplication16 extends Application {

    private Stage stage;

    private static JavaFXApplication16 instancia;

    public JavaFXApplication16(){
    instancia = this;
    }

    public static JavaFXApplication16 getIntancia(){
    return instancia;
    }


    @Override
    public void start(Stage fstage) throws Exception {


    stage = fstage;
    CambiarEscena("Sample_1.fxml");
    stage.show();
    }

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

    public Parent CambiarEscena(String fxml) throws Exception {

    AnchorPane page = (AnchorPane) FXMLLoader.load(JavaFXApplication16.class.getResource(fxml), null, new JavaFXBuilderFactory());
    Scene scene = stage.getScene();

    if (scene == null) {
    scene = new Scene(page,800,600);
    //scene.getStylesheets().add(AdministradorINFINIX.class.getResource("demo.css").toExternalForm());
    stage.setScene(scene);
    } else {

    stage.getScene().setRoot(page);

    }

    //stage.resizableProperty().setValue(Boolean.FALSE);
    stage.show();
    return page;
    }

    }

    SampleController.java

    public class SampleController implements Initializable {

    @FXML
    private Label label;
    @FXML
    TableView<Person> table = new TableView<>();
    @FXML
    TableColumn<Person,String> numColumn = new TableColumn<>();
    @FXML
    TableColumn<Person,String> firstNameColumn = new TableColumn<>();
    @FXML
    TableColumn<Person,String> lastNameColumn = new TableColumn<>();

    ObservableList<Person> data;

    @FXML
    private void handleButtonAction(ActionEvent event) throws Exception {
    System.out.println("You clicked me!");
    label.setText("Hello World!");

    JavaFXApplication16.getIntancia().CambiarEscena("Sample.fxml");
    data.addAll(
    new Person("1", "Joe", "Pesci"),new Person("2", "Audrey", "Hepburn"),
    new Person("3", "Gregory", "Peck"),new Person("4", "Cary", "Grant"),
    new Person("5", "De", "Niro"),new Person("6", "Katharine", "Hepburn"),
    new Person("7", "Jack", "Nicholson"),new Person("8", "Morgan", "Freeman"),
    new Person("9", "Elizabeth", "Taylor"),new Person("10", "Marcello", "Mastroianni"));

    System.out.println(""+table.getItems());

    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
    // TODO
    data = FXCollections.observableArrayList();

    numColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("num"));

    firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));

    lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("lastName"));

    table.setItems(data);
    }
    }

    Sample_1.fxml

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

    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.scene.control.cell.ComboBoxTableCell?>
    <?import javafx.scene.control.Pagination?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.image.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.util.Callback?>

    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication16.SampleController">
    <children>
    <Button layoutX="330" layoutY="20" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
    <Label layoutX="315" layoutY="40" minHeight="16" minWidth="69" fx:id="label" />
    </children>
    </AnchorPane>

    Sample.fxml

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

    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.scene.control.cell.ComboBoxTableCell?>
    <?import javafx.scene.control.Pagination?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.image.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.util.Callback?>

    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication16.SampleController">
    <children>
    <TableView fx:id="table" GridPane.columnIndex="0" GridPane.rowIndex="1">
    <columns>
    <TableColumn fx:id="numColumn" text="Num" prefWidth="100">
    <cellValueFactory>
    <PropertyValueFactory property="num" />
    </cellValueFactory>
    </TableColumn>
    <TableColumn fx:id="firstNameColumn" text="First Name" prefWidth="100">
    <cellValueFactory>
    <PropertyValueFactory property="firstName" />
    </cellValueFactory>
    </TableColumn>
    <TableColumn fx:id="lastNameColumn" text="Last Name" prefWidth="100">
    <cellValueFactory>
    <PropertyValueFactory property="lastName" />
    </cellValueFactory>
    </TableColumn>
    </columns>
    </TableView>
    </children>
    </AnchorPane>

    Person.java

    package javafxapplication16;

    import javafx.beans.property.SimpleStringProperty;

    public class Person {
    private SimpleStringProperty num;
    private SimpleStringProperty firstName;
    private String lastName;

    public Person(String id, String fName, String lName) {
    this.firstName = new SimpleStringProperty(fName);
    this.lastName = new String(lName);
    this.num = new SimpleStringProperty(id);
    }

    public String getFirstName() {
    return firstName.get();
    }

    public void setFirstName(String fName) {
    firstName.set(fName);
    }

    public String getLastName() {
    return lastName;
    }

    public void setLastName(String fName) {
    this.lastName = fName;
    }

    public String getNum() {
    return num.get();
    }

    public void setNum(String id) {
    num.set(id);
    }
    }
  • 3. Re: Manage multi Scene JavaFX 2.2 FXML
    jsmith Guru
    Currently Being Moderated
    Here are instructions on how to post code, thx.
    https://forums.oracle.com/forums/ann.jspa?annID=1622
  • 4. Re: Manage multi Scene JavaFX 2.2 FXML
    967237 Newbie
    Currently Being Moderated
    JavaFXApplication16.java
    package javafxapplication16;
    
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.JavaFXBuilderFactory;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.layout.AnchorPane;
    import javafx.stage.Stage;
    
    public class JavaFXApplication16 extends Application {
         private Stage stage;
         private static JavaFXApplication16 instancia;
         public JavaFXApplication16(){
              instancia = this;
         }
         public static JavaFXApplication16 getIntancia(){
              return instancia;
         }
         @Override 
         public void start(Stage fstage) throws Exception {
             stage = fstage;
             CambiarEscena("Sample_1.fxml"); 
             stage.show();
         }
    
         public static void main(String[] args) {launch(args);}
    
         public Parent CambiarEscena(String fxml) throws Exception {
              AnchorPane page = (AnchorPane) FXMLLoader.load(JavaFXApplication16.class.getResource(fxml), null, new    JavaFXBuilderFactory()); 
              Scene scene = stage.getScene();
              if (scene == null) {
                   scene = new Scene(page,800,600);
                   stage.setScene(scene);
              } else {
                   stage.getScene().setRoot(page); 
              }
    
              stage.show(); 
              return page;
         }
    }
    SampleController.java
    package javafxapplication16;
    
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.ListView;
    import javafx.scene.control.Pagination;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.image.ImageView;
    import javafx.scene.layout.VBox;
    
    
    /**
     *
     * @author bc11736
     */
    public class SampleController implements Initializable {
        
        @FXML
        private Label label;
        @FXML 
        TableView<Person> table = new TableView<>();
        @FXML
        TableColumn<Person,String> numColumn = new TableColumn<>();
        @FXML
        TableColumn<Person,String> firstNameColumn = new TableColumn<>();
        @FXML
        TableColumn<Person,String> lastNameColumn = new TableColumn<>();    
        
        ObservableList<Person> data;
        
        @FXML
        private void handleButtonAction(ActionEvent event) throws Exception {
            System.out.println("You clicked me!");
            label.setText("Hello World!");
            
            JavaFXApplication16.getIntancia().CambiarEscena("Sample.fxml");
            data.addAll(
                new Person("1", "Joe", "Pesci"),new Person("2", "Audrey", "Hepburn"),
                new Person("3", "Gregory", "Peck"),new Person("4", "Cary", "Grant"),
                new Person("5", "De", "Niro"),new Person("6", "Katharine", "Hepburn"),
                new Person("7", "Jack", "Nicholson"),new Person("8", "Morgan", "Freeman"),
                new Person("9", "Elizabeth", "Taylor"),new Person("10", "Marcello", "Mastroianni"));       
            
            System.out.println(""+table.getItems());
            
        }           
        
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            // TODO                                
            data = FXCollections.observableArrayList();      
            
            numColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("num"));
    
            firstNameColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));
    
            lastNameColumn.setCellValueFactory(new PropertyValueFactory<Person,String>("lastName"));                
            
            table.setItems(data);
        }    
    }
    Sample_1.fxml
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    
    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication16.SampleController">
        <children>        
            <Button layoutX="330" layoutY="20" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
            <Label layoutX="315" layoutY="40" minHeight="16" minWidth="69" fx:id="label" />                
        </children>
    </AnchorPane>
    Sample.fxml
    <?xml version="1.0" encoding="UTF-8"?>
    
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.cell.PropertyValueFactory?>
    <?import javafx.scene.control.cell.ComboBoxTableCell?>
    <?import javafx.scene.control.Pagination?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.image.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.util.Callback?>
    
    <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication16.SampleController">
        <children>                       
            <TableView fx:id="table" GridPane.columnIndex="0" GridPane.rowIndex="1">
                <columns>
                    <TableColumn fx:id="numColumn" text="Num" prefWidth="100">
                        <cellValueFactory>
                            <PropertyValueFactory property="num" />
                        </cellValueFactory>                   
                    </TableColumn>
                    <TableColumn fx:id="firstNameColumn" text="First Name" prefWidth="100">
                        <cellValueFactory>
                            <PropertyValueFactory property="firstName" />
                        </cellValueFactory>                   
                    </TableColumn>
                    <TableColumn fx:id="lastNameColumn" text="Last Name" prefWidth="100">
                        <cellValueFactory> 
                            <PropertyValueFactory property="lastName" />
                        </cellValueFactory>                                                                                              
                    </TableColumn>                                                        
                </columns>                
            </TableView>          
        </children>
    </AnchorPane>
    Person.java
    package javafxapplication16;
    
    import javafx.beans.property.SimpleStringProperty;
    
    public class Person {
        private SimpleStringProperty num;
            private SimpleStringProperty firstName;
            private String lastName;
     
            public Person(String id, String fName, String lName) {
                this.firstName = new SimpleStringProperty(fName);
                this.lastName = new String(lName);
                this.num = new SimpleStringProperty(id);
            }
     
            public String getFirstName() {
                return firstName.get();
            }
     
            public void setFirstName(String fName) {
                firstName.set(fName);
            }
     
            public String getLastName() {
                return lastName;
            }
     
            public void setLastName(String fName) {
                this.lastName = fName;
            }
     
            public String getNum() {
                return num.get();
            }
     
            public void setNum(String id) {
                num.set(id);
            }
    }
  • 5. Re: Manage multi Scene JavaFX 2.2 FXML
    daniel Journeyer
    Currently Being Moderated
    Hi Doug,

    You have two instance of SampleController: one is attached to the scenegraph you loaded with Sample_1.fxml, the other is attached to the scenegraph you loaded with Sample.fxml.

    1. you're loading Sample_1.fxml: an instance of SampleController is create (let's call it controller1)

    2. you click on the button. controller1.handleButtonAction is called. It loads Sample.fxml, which creates a new instance of SampleController (let's call it controller2) attached to the new scenegraph.

    3. you fill up controller1.data with a list of persons.

    The problem is that your scenegraph (Sample.fxml) is not linked to controller1, it's linked to controller2. So it's not controller1.data that you need to fill but controller2.data.

    To fix that you should change your method CambiarEscena so that it returns the controller attached to the loaded scenegraph instead of returning the root node of the loaded scenegraph, and then fill the data list of that controller - instead of filling the data list of the controller of the old discarded scenegraph.

    You can have a look at the SceneBuilder Login sample to see how to retrieve the controller of the scenegraph you're loading (you have to create an FXMLLoader instance instead of using the static FXMLLoader.load method).

    Hope this helps,
    -- daniel

    Edited by: daniel on Nov 13, 2012 6:02 AM

    BTW: given that you have two different scenegraphs, maybe you should have two different controller classes as well?

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points