FXML Inject Controller?

Hi,
Just playing around with the FXML stuff and it has some potential - inline with GWT's XML UI definitions, which was not too bad a thing to work with.
One big problem I have however is that the controller is being specified inside the FXML file. This is nasty for me, I want my view to be told which controller to use, not for it to specify. More importantly I want to load my Controller from a Spring resource bundle so that I can inject it with stuff that it will need (i.e. references to the server comms module and other 'controller' specific things). Currently the FXMLLoader.load method seems to be instantiating the Controller so I have no control of how/where it is loaded.
I have tried writing my own BuilderFactory but it seems to only create the 'Nodes'. Is there anyway I can override the contruction of the controller in my code or inject it?
(Note: I know I could make my controller look up stuff when it gets created, but this is not really Inversion of Control like I want).
Thanks for your input,
zonski

Hey Greg,
Thanks for the confirmation. Good to know.
The static option is just a little too clunky to suit my architecture at this stage. I'll play around with it more but I think the hacks I will have to do in my wiring and main code counter the benefits of the FXML at this stage. I'm a Dependency Injection and Inversion of Control addict these days and can't bring myself to go back to the old days of statics and singletons.
I had another look at GWT just for reference, as it effectively is doing the same thing (XML UI definitions that are bound to classes via annotations) and I remember it working reasonably well when I was using it. It uses a more controller driven approach. You create the controllers in your code and then use the UIBinder.createAndBind(this) to inflate the view from the XML and have it bound to the controller. The controller passes itself into this method so it is then bound to the created view based on annotations in the controller: http://code.google.com/webtoolkit/doc/latest/DevGuideUiBinder.html
For me, something more in this direction would work better. I tend to reference my controllers from my startup and main code, and then they then own and control their views, so I'd like to keep ownership of my controllers and have the FXML just do the UI stuff.
The drawback I guess would be that you would lose the current ability to have multiple controllers in the FXML. For me this would never happen and I wouldn't ever use this feature and would rather own my controllers - but perhaps the multi-controller feature is useful for others.
On a side notes, I really love MigLayout in Swing (JFX port here: http://java.net/projects/miglayoutfx2/pages/Home) and being able to use something like this in FXML would be handy - not sure if you have, or are intending to have, provision for custom panels/layouts in FXML.
Anyway, thanks for your time and it is great to get a definitive answer and I will definitely be watching this space for developments.
Cheers,
zonski
Edited by: zonski on 02-Sep-2011 20:30 (fixed hyperlinks)

Similar Messages

  • FXML and Controller base classes?

    Hey Guys,
    Another FXML question: does anyone know if it is possible to get FXMLLoader to pick up the FXML annotations on base classes?
    If we have this:
    public class MyBaseController
        @FXML
        protected Label myLabel1;
    } And this:
    public class MyController extends MyBaseController
        @FXML
        protected Label myLabel2;  
    } And then we load some FXML that references MyController as its controller, it seems only the direct properties on the Controller class are mapped (i.e. 'myLabel2') and not the inherited ones (i.e. 'myLabel1').
    I'm guessing it just hasn't been written this way?
    Greg - I don't suppose sharing the source code for FXMLLoader is an option? It would certainly help us early users work out what we're doing in lieu of more complete docco.
    Cheers,
    zonski

    Just in case anyone is interested, the answer to this question is currently 'no'.
    JIRA issue for it here: http://javafx-jira.kenai.com/browse/RT-16722

  • Integration between initializable & constructor in a FXML controller class

    Hi guys!
    I know how to create a create an object from an fxml file in two ways:
    1 - (fxml + controller) => no constructor, initialize method create the object
    2 - (fxml without controller + a class with a constructor that become his controller once instantiated) => the object must be instantiated by the constructor, no initialize method
    is there any way to create a single controller with both the approaches ?
    i'm trying but it constructor and initialize seems to call each other, ending in a StackOverflowError...
    suggestions?

    Solved it by myself.
    Access the root element of the FXML file by giving it a fx:id and inject it into the controller by using the @FXML annotation:
    @FXML
    private BorderPane borderPane; // this is my root element in FXML (fx:id="borderPane")
    @FXML
    protected void handleMenuItemImportCsvAction(final ActionEvent event) {
        final FileChooser fileChooser = new FileChooser();
        final File importFile = fileChooser.showOpenDialog(borderPane.getScene().getWindow());
    }

  • Override fxml Controller instantiation

    Hi everyone,
    I want to integrate my DI solution with the FXML, I found some solutions on web that add the injected controller instance on the nameSpace of FXMLLoader for each file. But that's not work with fx:include...
    I'de like know if there's another solutions... like override the default controller builder or something like that...
    thanks,
    best regards.

    Yes, this is supported in JavaFX 2.1. See FXMLLoader#setControllerFactory().

  • Fxml  ComboBox created in scene builder how to fetch data from database

    Hi Sir, How r u? Hope to be fine. Sir, I have a problem that i want to fetch data in fxml comboBox created in Scene Builder?
    I have used this code in JavaFx 2.0 for comboBox and textField the code is
    ComboBox studentRegId = new ComboBox();
    try{
    stm = db.con.createStatement();
    rs = stm.executeQuery("select * from students order by s_reg_id asc");
    while(rs.next()){               
    for(int i=1; i<=1; i++)
    studentRegId.getItems().add(rs.getString("s_reg_id"));
    }catch(SQLException sqlException){         
    final TextField sRegId = new TextField();
    final String regId[] = new String[1000];
    try{
    stm = db.con.createStatement();
    rs = stm.executeQuery("select * from students order by s_reg_id asc");
    int a = 0;
    while(rs.next()) {
    regId[a] = rs.getString("s_reg_id");
    a++; }
    }catch(SQLException sqlException){         
    studentRegId.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>(){
    public void changed(ObservableValue ov,Number value, Number new_value){                           
    sRegId.setText(regId[new_value.intValue()]);
    Now, the problem is that I want to use this code in Scene Builder fxml ComboBox .
    Please Help Me!
    I shall be very grate full to you for this kindness.
    Regards

    Hi,
    Ok, so you create your FXML :
    Add a controller property to your root control. (See Code tab in SceneBuilder or direcly in FXML : fx:controller tag)
    Add a fx:id to your controls (your combobox) (First property in SceneBuilder or directly in FXML : fx:id)
    Example :
    <?xml version="1.0" encoding="UTF-8"?>
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.collections.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.paint.*?>
    <HBox prefHeight="-1.0" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml" fx:controller="org.lgringo.comboexample.Controler">
      <children>
        <TextField fx:id="text" prefWidth="100.0" />
        <ComboBox fx:id="combo" prefWidth="200.0">
          <items>
            <FXCollections fx:factory="observableArrayList">
              <String fx:value="Item 1" />
              <String fx:value="Item 2" />
              <String fx:value="Item 3" />
            </FXCollections>
          </items>
        </ComboBox>
      </children>
    </HBox>Then, you create your Controler class using @FXML annotation (name of control should be the name of fx:id properties)
    You can do some initialisation in the inherit method "initialize"
    Example :
    package org.lgringo.comboexample;
    import javafx.fxml.FXML;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.TextField;
    public class Controler {
         @FXML
         // fx:id="combo"
         private ComboBox<String> combo; // Value injected by FXMLLoader
         @FXML
         // fx:id="text"
         private TextField text; // Value injected by FXMLLoader
         @FXML // This method is called by the FXMLLoader when initialization is complete
        void initialize() {
            assert combo != null : "fx:id=\"combo\" was not injected: check your FXML file 'ComboboxExample.fxml'.";
            assert text != null : "fx:id=\"text\" was not injected: check your FXML file 'ComboboxExample.fxml'.";
            // Initialize your logic here: all @FXML variables will have been injected
            combo.getItems().clear();
            combo.getItems().addAll("John Lennon","Mick Jagger","David Bowie");
            combo.getItems().add("Others...");
            text.setText("List : ");
    }Then you use the FXMLLoader class to load your FXML and Controler.
    Example :
    package org.lgringo.comboexample;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    public class App extends Application {
          * @param args
         public static void main(String[] args) {
              App.launch(args);
         @Override
         public void start(Stage primaryStage) throws Exception {
              Parent root = FXMLLoader.load(getClass().getResource("ComboboxExample.fxml"));
              primaryStage.setTitle("Combo Example");
              primaryStage.setScene(new Scene(root, 300, 275));
              primaryStage.show();
    }More info : http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm

  • How do I create a NetBeans project with multiple JavaFX (FXML) dialogs?

    I'm very new to Java and JavaFX, so forgive what is probably a question asked a thousand times, but I can't seem to find the answer.
    I come from a Visual Studio (C# with WPF) background. I'm used to creating a Solution then adding a Project for each dialog/window that gets included in the Solution. Each dialog/window is a class derived from Window, and I simply create an instance of that class when I need to use the dialog.
    What I need to do is have a main window (stage) that contains two lists of participants (a red team and a blue team).
    Then I need a separate dialog for entering the information for the participant. So when a button on the main stage is pressed ("Add Red Participant"), I want to open the ParticipantDialog. When the "OK" or "Close" button on the Participant dialog is clicked, I want the dialog to be able to return a participant object to the main stage.
    Then the main stage adds that participant to the appropriate list.
    What I've gathered so far is that I will be creating an FXML file for the Participant dialog (and I assume an associated controller). Then when the "Add" button is pressed, I will call an FXMLLoader to load that FXML dialog. Something like this:
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("ParticipantDialog.fxml"));
    Scene scene = (Scene)fxmlLoader.load();
    final Stage participantDialog = new Stage();
    participantDialog.setScene(scene);
    First question is: is that correct so far? Am I at least on the right track?
    Next question is: how or where do I create the FXML and controller files for the participant dialog using NetBeans? Should I create a separate project to make the participant dialog and then copy those files over, or is there a way to make the files within the parent project? And if I make the participant dialog in a separate project, what's the easiest way to access it from my main stage?
    I feel like I'm missing something simple here because this seems a lot harder than it should be.
    Thanks in advance for any advice.

    >  is that correct so far?
    Yes the sample code you have is fine to launch a new dialog when your Add button is pressed .
    > I create the FXML and controller files for the participant dialog using NetBeans?
    You can edit FXML text in NetBeans, but I think that is kind of tedious.
    You might want to create the FXML using SceneBuilder.
    You can use SceneBuilder in NetBeans.
    You may want to get it working without FXML first.
    For example, use the JavaFX scene graph API, then convert your program to use FXML once you are more comfortable with the JavaFX system.
    The piecemeal approach cuts down on the amount of learning you need to do at one time.
    > Should I create a separate project to make the participant dialog and then copy those files over.
    No.
    Just use a single NetBeans project.
    You will have separate FXML files for your main stage and your participant dialog, but they will both be placed in the same NetBeans project.
    > is there a way to make the files within the parent project?
    In NetBeans 7.3.1, do the following:
      File | New Project | JavaFX | JavaFX FXML Application
    This will create a sample project with a sample fxml file.
    Modify the sample project files to get what you want, changing the sample fxml to your main stage fxml and adding a new participant fxml to the same directory.

  • CSS Image loading problem by dynamically loading from fxml file?

    h1. Introduction
    The application I am developing loads an FXML file from a Controller. The FXML uses CSS and images for buttons are set in the CSS.
    CSS directory structure
    <package>.fxml
    Images
    <package>.fxml.resources.<subdir>
    Example CSS Code
    .buttonImage {
        -fx-background-image: url("resources/subdir/image.png");
    }Example loading fxml from controller code
             URL location = getClass().getResource("/package/fxml/UI.fxml");
             FXMLLoader fxmlLoader = new FXMLLoader(location);
             fxmlLoader.setLocation(location);
             fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
             Parent root = (Parent)fxmlLoader.load(location.openStream());
             Controller = (Controller) fxmlLoader.getController();
             newPane.getChildren().add(root);h1. Problem
    The fxml file does not load and causes the following error:
    javafx.fxml.LoadException: Page language not specified.Note, the fxml file loaded correctly before images were added.
    Any ideas of what might be going wrong?
    h1. Attempted
    I have attempted the following: tried changing the url of the image as an absolute path.

    No Problem: Note, this is the actual FXML, my previous examples were simplifications of package names and class names in order to directly illustrate the problem. Note, I am using SceneBuilder to develop the FXML file.
    <?xml version="1.0" encoding="UTF-8"?>
    <?import java.lang.*?>
    <?import java.net.*?>
    <?import java.util.*?>
    <?import javafx.collections.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.text.*?>
    <AnchorPane id="AnchorPane" prefHeight="396.0000999999975" prefWidth="350.0" styleClass="mainFxmlClass" xmlns:fx="http://javafx.com/fxml" fx:controller="com.monkygames.kbmaster.controller.ProfileUIController">
      <children>
        <Label layoutX="14.0" layoutY="14.0" text="Profiles">
          <font>
            <Font size="18.0" />
          </font>
        </Label>
        <GridPane layoutX="15.0" layoutY="44.0" prefHeight="99.0" prefWidth="335.0">
          <children>
            <Label text="Type: " GridPane.columnIndex="0" GridPane.rowIndex="0" />
            <ComboBox fx:id="typeCB" prefWidth="249.0" GridPane.columnIndex="1" GridPane.rowIndex="0">
              <items>
                <FXCollections fx:factory="observableArrayList">
                  <String fx:value="Item 1" />
                  <String fx:value="Item 2" />
                  <String fx:value="Item 3" />
                </FXCollections>
              </items>
            </ComboBox>
            <Label text="Program: " GridPane.columnIndex="0" GridPane.rowIndex="1" />
            <ComboBox fx:id="programCB" prefWidth="249.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
              <items>
                <FXCollections fx:factory="observableArrayList">
                  <String fx:value="Item 1" />
                  <String fx:value="Item 2" />
                  <String fx:value="Item 3" />
                </FXCollections>
              </items>
            </ComboBox>
            <Label text="Profile: " GridPane.columnIndex="0" GridPane.rowIndex="2" />
            <ComboBox prefWidth="249.0" GridPane.columnIndex="1" GridPane.rowIndex="2">
              <items>
                <FXCollections fx:factory="observableArrayList">
                  <String fx:value="Item 1" />
                  <String fx:value="Item 2" />
                  <String fx:value="Item 3" />
                </FXCollections>
              </items>
            </ComboBox>
          </children>
          <columnConstraints>
            <ColumnConstraints fillWidth="false" halignment="RIGHT" hgrow="NEVER" maxWidth="-Infinity" minWidth="10.0" prefWidth="80.0" />
            <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
          </columnConstraints>
          <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          </rowConstraints>
        </GridPane>
        <HBox layoutX="14.0" layoutY="150.0" prefHeight="159.0" prefWidth="335.0">
          <children>
            <Label text="Description: " />
            <TextArea prefHeight="172.0" prefWidth="247.0" wrapText="true" />
          </children>
        </HBox>
        <HBox alignment="CENTER" layoutX="11.0" layoutY="334.0" prefHeight="48.0" prefWidth="329.0">
          <children>
            <Button fx:id="newProfileB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="newProfile" text="New Profile" />
            <Button id="newProfileB" fx:id="cloneProfileB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="cloneProfile" text="Clone Profile" />
            <Button id="newProfileB" fx:id="importProfileB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="importProfile" text="Import Profile" />
            <Button id="newProfileB" fx:id="exportProfileB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="exportProfile" text="Export Profile" />
            <Button id="newProfileB" fx:id="printPDFB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="pdfProfile" text="Print to PDF" />
            <Button id="newProfileB" fx:id="deleteProfileB" contentDisplay="GRAPHIC_ONLY" minHeight="48.0" minWidth="48.0" mnemonicParsing="false" onAction="profileEventFired" prefHeight="48.0" prefWidth="48.0" styleClass="deleteProfile" text="Delete Profile" />
          </children>
        </HBox>
      </children>
      <stylesheets>
        <URL value="@master.css" />
        <URL value="@profile.css" />
      </stylesheets>
    </AnchorPane>Edited by: 960799 on Jan 4, 2013 8:58 PM
    Edited by: 960799 on Jan 4, 2013 8:59 PM

  • Best way to realize controller communication

    Hi,
    my UI has a search text field and a table. To filter the table content the user can enter something in the text field. If the entered text hits a row, it is displayed, otherwise not. The text field filters the table.
    I have a search.fxml (search text field ) with controller and the table (content.fxml) with controller. When the user typed in the text in the search field and hits the button there, the text will be passed to the search controller. Now my problem begins...I need an instance of the controller of the table to invoke a method which gets the search text and does the filtering. Is there a concept in JavaFX to do this easily. The FXMLLoader.getController() delivers a new instance which does not fit in my case.
    Regards,
    Oliver

    The FXMLLoader.getController() delivers a new instance which does not fit in my case.If you are using JavaFX 2.1, you can use a controller factory to manage how controllers are instantiated. See FXMLLoader#setControllerFactory().
    Probably wrote a lot, in short: how should I share controllers?See this thread for more info:
    How to Navigate 'include' resource in .fxml files

  • Resizable webview pane in fxml

    greetings,
    I'm new to java FX and I've been having problems with fxml. I created a custom WebViewPane class that extends from Pane class and the code is pretty much the same with the WebViewPane from the samples of WebViewBrowser. Then I tried to put that class into fxml files that will be used in a conroller class. and basically the fxml files is like this:
    <AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" styleClass="background" xmlns:fx="http://javafx.com/fxml" fx:controller="lenterastudio.WebViewController" >
    <children>
    <WebViewPane fx:id="webPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" />
    </children>
    <stylesheets>
    <URL value="@Form.css"/>
    </stylesheets>
    </AnchorPane>
    the WebViewPane is showed up and successfully load a webpage but the problems are the pane itself is only filled some parts of the AnchorPane and when I tried to resize the form, the WebViewPane didn't align to it and still in the same size with the preferred Height and Width.
    can anyone give me advice how can I make the WebViewPane using the same Height and Width as the parent does? and how can I make it resizable using fxml?

    See this example https://github.com/tomsontom/e-fx-clipse/blob/master/at.bestsolution.efxclipse.testcases.fxgraph/src/at/bestsolution/efxclipse/testcases/fxgraph/AddressBook.fxml its a test case for my Eclipse Tooling named e(fx)clipse. The next version will provide you with some FXML-Tooling beside the one for my custom DSL.

  • Pass controller name runtime

    Hi,
    I want to develope reusable FXML components. I want to pass controller name runtime to FXML, so that everyone can write down own controller and pass the attributes to FXML.
    e.g.
    I will have AnchorPane.FXML. Button should contain <fx:define> component for controller name
    So that
    <AnchorPane id="AnchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="*+_XXXXXXXXXX_+*" >
    This can be included in some XXX.FXML, but XXXXXXXXXX should be passed throgh <var name="controller" value="${controller}"/>, so that button properties like name,size can be passed using own controller.
    Is there any way I can do so?
    Thanks in advance.

    I want to develope reusable FXML components. I want to pass controller name runtime to FXML, so that everyone can write down own controller and pass the attributes to FXML.This isn't currently possible. However, in JavaFX 2.1, you can provide a custom controller factory implementation to FXMLLoader that will allow your application to manage the controller instantiation process. Maybe this will help you address your use case.
    XXXXXXXXXX should be passed throgh <var name="controller" value="${controller}"/>, so that button properties like name,size can be passed using own controller.From a pure design standpoint, the controller probably should not be sourcing values like name and size. Name should probably come from a resource bundle, and size should be defined by the view. The controller is primarily meant to manage the interaction between the model and the view, and respond to user input events fired by the view.

  • Css problem in fxml

    Hi;
    i made a css loaded in fxml:
    <AnchorPane id="AnchorPane" fx:id="ac" prefHeight="200.0" prefWidth="320.0" style="-fx-border-width: 10px;&#10;-fx-border-color: black;" xmlns:fx="http://javafx.com/fxml" fx:controller="style1.Style1Controller">
      <stylesheets>
        <URL value="@Style1.css" />
      </stylesheets>
    </AnchorPane>just an anchorpane ac :
    #ac {
           -fx-background-color: palegreen;
       }but my ac don't get the color
    if i write it in the Style window in scenebuilder it's ok
    why? !!!!

    Hi kapac,
    Before starting CSS let you know about this clearly.
    FXML attribute
    id           = this is the CSS ID of the Node
    fx:id           = this is the javafx variable name of that Node
    styleclass     = this is the CSS styleclass of that Node
    CSS stuffs
    #mynode      = You can style your node with id
    .myclass     = You can style your node with classIn your case you are trying to set color of anchorpane with id where your id="AnchorPane" .
    Instead of *#ac* you can change your css to *#AnchorPane*.
    Thanks
    Narayan

  • Dynamic fxml "source" in fx:include

    Is it possible to have a dynamic source in the <fx:include> ? Setting a controller for this source can be achieved by using controller factories.
    <VBox prefHeight="412.0" prefWidth="352.0" xmlns:fx="http://javafx.com/fxml" fx:controller="fxminclude.ParentController">
      <children>
        <HBox alignment="CENTER" prefHeight="47.0" prefWidth="352.0">
          <children>
            <Label text="Value" />
            <TextField fx:id="valueField" prefWidth="200.0" />
          </children>
        </HBox>
        <Pane prefHeight="312.0" prefWidth="352.0">
          <children>
            <fx:include fx:id="title" source="<SOME_PLACEHOLDER_FILE>" layoutX="42.0" />
          </children>
        </Pane>
      </children>
    </VBox>

    You may be able to provide the value in the resource bundle for your fxml file. See [url http://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html#resource_resolution]Resource Resolution in the FXML reference.

  • MenuBar in FXML

    Hello All: I am completely new to JavaFX without any prior knowledge of Java Swing. I always worked on web based applications and so running into all kinds of troubles. Any hints on solving this would be highly appreciated.
    I have an application with a login page and a welcome page. The welcome page has a menu bar that I am not able to get to display on the screen.
    The FXML for menu page is as follows:
        <children>
            <AnchorPane>
                <children>
                    <fx:include source="header.fxml"/>
                    <Label layoutX="20.0" layoutY="15.0" style="-fx-font-size: 2.0em;" textFill="white" text="Welcome " />
                    <Label layoutX="130.0" layoutY="15.0" style="-fx-font-size: 2.0em;" textFill="white" fx:id="userName" />
                    <Label layoutX="2.0" layoutY="100.0" style="-fx-font-size: 1.0em;" textFill="white" fx:id="printTime" />
                </children>
            </AnchorPane>
            <MenuBar fx:id="menuBar"/>
        </children>-----
    This is my welcome controller: I have to load the contents of the menu bar in the controller as I need to provide access restrictions to certain users based upon their role. However with the below code I am not able to display the menu on the screen.
    public class WelcomeController implements Initializable {
        @FXML
        private Label userName;
        @FXML
        private MenuBar menuBar;
       @FXML
        private void logoutFromApp(ActionEvent event) {
            App.getInstance().userLogout();
        @Override
        public void initialize(URL url, ResourceBundle rb) {
            Logger.getLogger(WelcomeController.class.getName()).log(Level.INFO, "Enter initialize");
            User loggedUser = App.getInstance().getLoggedUser();
            userName.setText(loggedUser.getId());
            // Created as per one of the examples online
            menuBar = new MenuBar();
            // Prepare left-most 'File' drop-down menu 
            Menu fileMenu = new Menu("File");
            fileMenu.getItems().add(new MenuItem("New"));
            fileMenu.getItems().add(new MenuItem("Open"));
            fileMenu.getItems().add(new MenuItem("Save"));
            fileMenu.getItems().add(new MenuItem("Save As"));
            fileMenu.getItems().add(new SeparatorMenuItem());
            fileMenu.getItems().add(new MenuItem("Exit"));
            menuBar.getMenus().add(fileMenu);
            // Prepare 'Help' drop-down menu 
            Menu helpMenu = new Menu("Help");
            final MenuItem searchMenuItem = new MenuItem("Search");
            searchMenuItem.setDisable(true);
            helpMenu.getItems().add(searchMenuItem);
            final MenuItem onlineManualMenuItem = new MenuItem("Online Manual");
            onlineManualMenuItem.setVisible(false);
            helpMenu.getItems().add(onlineManualMenuItem);
            helpMenu.getItems().add(new SeparatorMenuItem());
            final MenuItem aboutMenuItem =
                    MenuItemBuilder.create().text("About").onAction(
                    new EventHandler<ActionEvent>() {
                        @Override
                        public void handle(ActionEvent e) {
                            System.out.println("You clicked on About!");
                    }).accelerator(
                    new KeyCodeCombination(
                    KeyCode.A, KeyCombination.CONTROL_DOWN)).build();
            helpMenu.getItems().add(aboutMenuItem);
            menuBar.getMenus().add(helpMenu);
            Logger.getLogger(WelcomeController.class.getName()).log(Level.INFO, "Exit initialize");
    Also can someone suggest me with a good book on JavaFX 2.0 that extensively covers FXML?
    Thanks.

    Thisi is how my fxml looks...
    <?xml version="1.0" encoding="UTF-8"?>
    <?language javascript?>
    <?import java.lang.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
    <?import javafx.scene.image.*?>
    <StackPane id="StackPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="gov.ca.lc.controllers.WelcomeController">
        <children>
            <fx:script source="../resources/scripts/timeScript.js" />
            <AnchorPane>
                <maxWidth>
                    <Double fx:value="-Infinity"/>
                </maxWidth>
                <children>
                    <fx:include source="header.fxml"/>
                    <Label layoutX="20.0" layoutY="15.0" style="-fx-font-size: 2.0em;" textFill="white" text="Welcome " />
                    <Label layoutX="130.0" layoutY="15.0" style="-fx-font-size: 2.0em;" textFill="white" fx:id="userName" />
                    <Label layoutX="2.0" layoutY="100.0" style="-fx-font-size: 1.0em;" textFill="white" fx:id="printTime" />
                    <fx:script>
                        formatTime();
                    </fx:script>
                </children>
            </AnchorPane>
            <AnchorPane>
                <children>
                    <Hyperlink layoutY="20.0" text="logout" AnchorPane.rightAnchor="52.0" fx:id="logout" onAction="#logoutFromApp"/>
                </children>
            </AnchorPane>
            <MenuBar fx:id="menuBar"/>
        </children>
        <styleClass>
            <String fx:value="welcome" />
        </styleClass>       
    </StackPane>I have also tried displaying just the <MenuBar fx:id="menuBar"/> inside the stack pane by removing other anchor panes. However, still it doesn't display me the menubar.
    Thanks.
    Edited by: SirGeneral on Mar 14, 2012 1:12 PM

  • Class controller Stage/Window reference

    Is there any way of getting the Stage/Window object of an FXML loaded file from the associated class controller?
    Particularly, I have a controller for a modal window and I need the Stage to close it.

    Hi!
    I have a parent FXML-file (no controller added) acting as main frame, which includes several other FXML-files. In one of those included FXML-files, I have added a controller.
    So, my setup looks a bit like this...
    -> Parent FXML
    --> include FXML-file1 + controller attached
    --> ...
    --> include FXML-file5
    Inside that controller, I am trying to access now the stage object in a similar approach like described here. This is when i get the null pointer exception....
    public class FXMLfile1Controller {
    @FXML
    private Button ButtonXYZ;
    @FXML
    protected void ButtonXYZ_Action(ActionEvent event) {
    Stage stage = (Stage)ButtonXYZ.getScene().getWindow();
    stage.setIconified(true);
    // this doesnt work either....
    // stage.close();
    Can it be, that the stage-object in the controller is not the same as the stage of the parent/main FXML?

  • How to have constructor with arguments for controller?

    I would like to have the controller have arguments so that they can be a precondition for the object being constructed and not in setters to be added later on. This will reduce errors.
    Unfortunately, fxml only seems to take the no-arg constructor. Is there another way?
    Edited by: likejiujitsu on Apr 20, 2013 10:30 AM

    Here's perhaps a more realistic example. I have a Main.fxml file with a MainController. The event handler for a button in the Main.fxml file is going to load another fxml file (Dialog.fxml) and display the content in a dialog. The controller associated with Dialog.fxml (DialogController) is going to be initialized by passing a String into the constructor; that String value is retrieved from a text field in Main.fxml.
    Main.java:
    package example;
    import java.io.IOException;
    import javafx.application.Application;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.stage.Stage;
    public class Main extends Application {
      @Override
      public void start(Stage primaryStage) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource("Main.fxml"));
        primaryStage.setScene(new Scene(root, 400, 200));
        primaryStage.show();
      public static void main(String[] args) {
        launch(args);
    }Main.fxml:
    <?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.TextField?>
    <?import javafx.scene.control.Button?>
    <VBox xmlns:fx="http://javafx.com/fxml" spacing="10"
         fx:controller="example.MainController" fx:id="mainRoot">
         <HBox>
              <Label text="Enter text:" />
              <TextField fx:id="textField" />
         </HBox>
         <Button text="Show Dialog" onAction="#showDialog" />
         <!-- TODO Add Nodes -->
    </VBox>MainController.java:
    package example;
    import java.io.IOException;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.TextField;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    public class MainController {
      @FXML
      private TextField textField;
      @FXML
      private Parent mainRoot;
      private final FXMLLoader dialogLoader;
      public MainController() {
        dialogLoader = new FXMLLoader(
            MainController.class.getResource("Dialog.fxml"));
        dialogLoader.setControllerFactory(new Callback<Class<?>, Object>() {
          @Override
          public Object call(Class<?> cls) {
            if (cls == DialogController.class) {
              return new DialogController(textField.getText());
            } else {
              try {
                return cls.newInstance();
              } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
      @FXML
      private void showDialog() throws IOException {
        dialogLoader.setController(null);
        dialogLoader.setRoot(null);
        Parent dialogRoot = (Parent) dialogLoader.load();
        Scene scene = new Scene(dialogRoot, 300, 150);
        Stage dialog = new Stage();
        dialog.initModality(Modality.APPLICATION_MODAL);
        dialog.initOwner(mainRoot.getScene().getWindow());
        dialog.setScene(scene);
        dialog.show();
    }Dialog.fxml
    <?xml version="1.0" encoding="UTF-8"?>
    <?import javafx.scene.layout.VBox?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.control.Button?>
    <?import javafx.scene.layout.HBox?>
    <VBox xmlns:fx="http://javafx.com/fxml" fx:controller="example.DialogController"
         fx:id="dialogRoot">
         <Label fx:id="label" />
         <HBox>
              <Button text="Click Me" onAction="#click" />
              <Button text="Close" onAction="#close" />
         </HBox>
    </VBox>DialogController.java
    package example;
    import javafx.fxml.FXML;
    import javafx.scene.Parent;
    import javafx.scene.control.Label;
    public class DialogController {
      private final String text;
      @FXML
      private Label label;
      @FXML
      private Parent dialogRoot;
      public DialogController(String text) {
        this.text = text;
      public void initialize() {
        label.setText(text);
      @FXML
      private void click() {
        System.out.println("Text is " + text);
      @FXML
      private void close() {
        dialogRoot.getScene().getWindow().hide();
    }Edited by: James_D on Apr 22, 2013 8:00 PM

Maybe you are looking for